From 12e3001b3aad7381c51ef348dc86cdf5cc193e05 Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Wed, 8 May 2024 17:26:57 +0300 Subject: [PATCH 1/3] Generic enhancements (#1435) * Disable Ledger for MacOS * increase update duration for Solana [skip ci] * change tron default Node Update build number * Add disabling tron grid to privacy settings * update monero.com versions [skip ci] --- assets/text/Release_Notes.txt | 5 ++- assets/tron_node_list.yml | 4 +-- cw_solana/lib/solana_wallet.dart | 2 +- cw_tron/lib/default_tron_tokens.dart | 4 +-- cw_tron/lib/tron_http_provider.dart | 4 +-- cw_tron/lib/tron_wallet.dart | 20 +++++++---- ios/Flutter/AppFrameworkInfo.plist | 2 +- ios/Podfile.lock | 20 +++++------ lib/entities/default_settings_migration.dart | 2 +- lib/entities/preferences_key.dart | 1 + .../provider/thorchain_exchange.provider.dart | 14 ++++---- .../screens/restore/restore_options_page.dart | 22 ++++++------ lib/src/screens/settings/privacy_page.dart | 8 +++++ lib/store/settings_store.dart | 12 +++++++ lib/tron/cw_tron.dart | 5 +++ .../hardware_wallet/ledger_view_model.dart | 35 +++++++++++-------- lib/view_model/link_view_model.dart | 11 ++---- .../settings/privacy_settings_view_model.dart | 12 +++++++ macos/Podfile.lock | 4 +-- macos/Runner.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/xcschemes/Runner.xcscheme | 10 +++--- res/values/strings_ar.arb | 5 +-- res/values/strings_bg.arb | 5 +-- res/values/strings_cs.arb | 5 +-- res/values/strings_de.arb | 5 +-- res/values/strings_en.arb | 5 +-- res/values/strings_es.arb | 5 +-- res/values/strings_fr.arb | 5 +-- res/values/strings_ha.arb | 5 +-- res/values/strings_hi.arb | 5 +-- res/values/strings_hr.arb | 5 +-- res/values/strings_id.arb | 5 +-- res/values/strings_it.arb | 5 +-- res/values/strings_ja.arb | 5 +-- res/values/strings_ko.arb | 5 +-- res/values/strings_my.arb | 5 +-- res/values/strings_nl.arb | 5 +-- res/values/strings_pl.arb | 5 +-- res/values/strings_pt.arb | 5 +-- res/values/strings_ru.arb | 5 +-- res/values/strings_th.arb | 5 +-- res/values/strings_tl.arb | 5 +-- res/values/strings_tr.arb | 5 +-- res/values/strings_uk.arb | 5 +-- res/values/strings_ur.arb | 5 +-- res/values/strings_yo.arb | 5 +-- res/values/strings_zh.arb | 5 +-- scripts/android/app_env.sh | 8 ++--- scripts/ios/app_env.sh | 8 ++--- scripts/macos/app_env.sh | 8 ++--- tool/configure.dart | 2 ++ 51 files changed, 217 insertions(+), 138 deletions(-) diff --git a/assets/text/Release_Notes.txt b/assets/text/Release_Notes.txt index ae6306209..3ff7aa3b4 100644 --- a/assets/text/Release_Notes.txt +++ b/assets/text/Release_Notes.txt @@ -1 +1,4 @@ -Bitcoin Bug fixes and enhancements \ No newline at end of file +Hardware wallets support for Bitcoin, Ethereum and Polygon +Add Tron wallet +Security enhancements +Bug fixes and generic enhancements \ No newline at end of file diff --git a/assets/tron_node_list.yml b/assets/tron_node_list.yml index 4c67b920e..d28e38f2e 100644 --- a/assets/tron_node_list.yml +++ b/assets/tron_node_list.yml @@ -1,8 +1,8 @@ - - uri: api.trongrid.io + uri: tron-rpc.publicnode.com:443 is_default: true useSSL: true - - uri: tron-rpc.publicnode.com:443 + uri: api.trongrid.io is_default: false useSSL: true \ No newline at end of file diff --git a/cw_solana/lib/solana_wallet.dart b/cw_solana/lib/solana_wallet.dart index 6692b65a6..401968698 100644 --- a/cw_solana/lib/solana_wallet.dart +++ b/cw_solana/lib/solana_wallet.dart @@ -524,7 +524,7 @@ abstract class SolanaWalletBase _transactionsUpdateTimer!.cancel(); } - _transactionsUpdateTimer = Timer.periodic(const Duration(seconds: 20), (_) { + _transactionsUpdateTimer = Timer.periodic(const Duration(seconds: 30), (_) { _updateBalance(); _updateNativeSOLTransactions(); _updateSPLTokenTransactions(); diff --git a/cw_tron/lib/default_tron_tokens.dart b/cw_tron/lib/default_tron_tokens.dart index ad70f28cd..6aa6357e6 100644 --- a/cw_tron/lib/default_tron_tokens.dart +++ b/cw_tron/lib/default_tron_tokens.dart @@ -22,14 +22,14 @@ class DefaultTronTokens { symbol: "BTC", contractAddress: "TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9", decimal: 8, - enabled: true, + enabled: false, ), TronToken( name: "Ethereum", symbol: "ETH", contractAddress: "TRFe3hT5oYhjSZ6f3ji5FJ7YCfrkWnHRvh", decimal: 18, - enabled: true, + enabled: false, ), TronToken( name: "Wrapped BTC", diff --git a/cw_tron/lib/tron_http_provider.dart b/cw_tron/lib/tron_http_provider.dart index 193a3dbdd..58d313378 100644 --- a/cw_tron/lib/tron_http_provider.dart +++ b/cw_tron/lib/tron_http_provider.dart @@ -19,7 +19,7 @@ class TronHTTPProvider implements TronServiceProvider { Future> get(TronRequestDetails params, [Duration? timeout]) async { final response = await client.get(Uri.parse(params.url(url)), headers: { 'Content-Type': 'application/json', - 'TRON-PRO-API-KEY': secrets.tronGridApiKey, + if (url.contains("trongrid")) 'TRON-PRO-API-KEY': secrets.tronGridApiKey, }).timeout(timeout ?? defaultRequestTimeout); final data = json.decode(response.body) as Map; return data; @@ -31,7 +31,7 @@ class TronHTTPProvider implements TronServiceProvider { .post(Uri.parse(params.url(url)), headers: { 'Content-Type': 'application/json', - 'TRON-PRO-API-KEY': secrets.tronGridApiKey, + if (url.contains("trongrid")) 'TRON-PRO-API-KEY': secrets.tronGridApiKey, }, body: params.toRequestBody()) .timeout(timeout ?? defaultRequestTimeout); diff --git a/cw_tron/lib/tron_wallet.dart b/cw_tron/lib/tron_wallet.dart index 6cef05348..96f92e450 100644 --- a/cw_tron/lib/tron_wallet.dart +++ b/cw_tron/lib/tron_wallet.dart @@ -31,7 +31,6 @@ import 'package:cw_tron/tron_wallet_addresses.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:on_chain/on_chain.dart'; -import 'package:shared_preferences/shared_preferences.dart'; part 'tron_wallet.g.dart'; @@ -61,8 +60,6 @@ abstract class TronWalletBase if (!CakeHive.isAdapterRegistered(TronToken.typeId)) { CakeHive.registerAdapter(TronTokenAdapter()); } - - sharedPrefs.complete(SharedPreferences.getInstance()); } final String? _mnemonic; @@ -81,7 +78,7 @@ abstract class TronWalletBase late String _tronAddress; - late TronClient _client; + late final TronClient _client; Timer? _transactionsUpdateTimer; @@ -102,8 +99,6 @@ abstract class TronWalletBase @observable late ObservableMap balance; - Completer sharedPrefs = Completer(); - Future init() async { await initTronTokensBox(); @@ -464,6 +459,7 @@ abstract class TronWalletBase } } + @override Future? updateBalance() async => await _updateBalance(); List get tronTokenCurrencies => tronTokensBox.values.toList(); @@ -543,7 +539,7 @@ abstract class TronWalletBase _transactionsUpdateTimer!.cancel(); } - _transactionsUpdateTimer = Timer.periodic(const Duration(seconds: 20), (_) async { + _transactionsUpdateTimer = Timer.periodic(const Duration(seconds: 30), (_) async { _updateBalance(); await fetchTransactions(); fetchTrc20ExcludedTransactions(); @@ -557,4 +553,14 @@ abstract class TronWalletBase String getTronBase58AddressFromHex(String hexAddress) { return TronAddress(hexAddress).toAddress(); } + + void updateScanProviderUsageState(bool isEnabled) { + if (isEnabled) { + fetchTransactions(); + fetchTrc20ExcludedTransactions(); + _setTransactionUpdateTimer(); + } else { + _transactionsUpdateTimer?.cancel(); + } + } } diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index cb6be3098..cae654377 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 12.0 diff --git a/ios/Podfile.lock b/ios/Podfile.lock index cd03e10a9..0cc57e075 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -109,6 +109,8 @@ PODS: - flutter_inappwebview_ios/Core (0.0.1): - Flutter - OrderedSet (~> 5.0) + - flutter_local_authentication (1.2.0): + - Flutter - flutter_mailer (0.0.1): - Flutter - flutter_secure_storage (6.0.0): @@ -118,8 +120,6 @@ PODS: - Toast - in_app_review (0.2.0): - Flutter - - local_auth_ios (0.0.1): - - Flutter - MTBBarcodeScanner (5.0.11) - OrderedSet (5.0.0) - package_info (0.0.1): @@ -175,11 +175,11 @@ DEPENDENCIES: - file_picker (from `.symlinks/plugins/file_picker/ios`) - Flutter (from `Flutter`) - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`) + - flutter_local_authentication (from `.symlinks/plugins/flutter_local_authentication/ios`) - flutter_mailer (from `.symlinks/plugins/flutter_mailer/ios`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) - in_app_review (from `.symlinks/plugins/in_app_review/ios`) - - local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`) - package_info (from `.symlinks/plugins/package_info/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) @@ -233,6 +233,8 @@ EXTERNAL SOURCES: :path: Flutter flutter_inappwebview_ios: :path: ".symlinks/plugins/flutter_inappwebview_ios/ios" + flutter_local_authentication: + :path: ".symlinks/plugins/flutter_local_authentication/ios" flutter_mailer: :path: ".symlinks/plugins/flutter_mailer/ios" flutter_secure_storage: @@ -241,8 +243,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/fluttertoast/ios" in_app_review: :path: ".symlinks/plugins/in_app_review/ios" - local_auth_ios: - :path: ".symlinks/plugins/local_auth_ios/ios" package_info: :path: ".symlinks/plugins/package_info/ios" package_info_plus: @@ -282,18 +282,18 @@ SPEC CHECKSUMS: DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 file_picker: 15fd9539e4eb735dc54bae8c0534a7a9511a03de - Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 flutter_inappwebview_ios: 97215cf7d4677db55df76782dbd2930c5e1c1ea0 + flutter_local_authentication: 1172a4dd88f6306dadce067454e2c4caf07977bb flutter_mailer: 2ef5a67087bc8c6c4cefd04a178bf1ae2c94cd83 flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be fluttertoast: 48c57db1b71b0ce9e6bba9f31c940ff4b001293c in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d - local_auth_ios: 1ba1475238daa33a6ffa2a29242558437be435ac MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85 - path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c + path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 Protobuf: 8e9074797a13c484a79959fdb819ef4ae6da7dbe ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 @@ -301,13 +301,13 @@ SPEC CHECKSUMS: SDWebImage: a3ba0b8faac7228c3c8eadd1a55c9c9fe5e16457 sensitive_clipboard: d4866e5d176581536c27bb1618642ee83adca986 share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 - shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 + shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1 SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f Toast: ec33c32b8688982cecc6348adeae667c1b9938da uni_links: d97da20c7701486ba192624d99bffaaffcfc298a UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841 - url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812 + url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586 wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47 workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6 diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index 94b23d3c9..77db474a9 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -36,7 +36,7 @@ const cakeWalletBitcoinCashDefaultNodeUri = 'bitcoincash.stackwallet.com:50002'; const nanoDefaultNodeUri = 'rpc.nano.to'; const nanoDefaultPowNodeUri = 'rpc.nano.to'; const solanaDefaultNodeUri = 'rpc.ankr.com'; -const tronDefaultNodeUri = 'api.trongrid.io'; +const tronDefaultNodeUri = 'tron-rpc.publicnode.com:443'; const newCakeWalletBitcoinUri = 'btc-electrum.cakewallet.com:50002'; Future defaultSettingsMigration( diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart index 55b5d55a1..cf9ae3019 100644 --- a/lib/entities/preferences_key.dart +++ b/lib/entities/preferences_key.dart @@ -56,6 +56,7 @@ class PreferencesKey { static const pinNativeTokenAtTop = 'pin_native_token_at_top'; static const useEtherscan = 'use_etherscan'; static const usePolygonScan = 'use_polygonscan'; + static const useTronGrid = 'use_trongrid'; static const defaultNanoRep = 'default_nano_representative'; static const defaultBananoRep = 'default_banano_representative'; static const lookupsTwitter = 'looks_up_twitter'; diff --git a/lib/exchange/provider/thorchain_exchange.provider.dart b/lib/exchange/provider/thorchain_exchange.provider.dart index 826e203f3..22937e603 100644 --- a/lib/exchange/provider/thorchain_exchange.provider.dart +++ b/lib/exchange/provider/thorchain_exchange.provider.dart @@ -19,15 +19,15 @@ class ThorChainExchangeProvider extends ExchangeProvider { ...(CryptoCurrency.all .where((element) => ![ CryptoCurrency.btc, - CryptoCurrency.eth, + // CryptoCurrency.eth, CryptoCurrency.ltc, CryptoCurrency.bch, - CryptoCurrency.aave, - CryptoCurrency.dai, - CryptoCurrency.gusd, - CryptoCurrency.usdc, - CryptoCurrency.usdterc20, - CryptoCurrency.wbtc, + // CryptoCurrency.aave, + // CryptoCurrency.dai, + // CryptoCurrency.gusd, + // CryptoCurrency.usdc, + // CryptoCurrency.usdterc20, + // CryptoCurrency.wbtc, // TODO: temporarily commented until https://github.com/cake-tech/cake_wallet/pull/1436 is merged ].contains(element)) .toList()) ]; diff --git a/lib/src/screens/restore/restore_options_page.dart b/lib/src/screens/restore/restore_options_page.dart index a0f3a597e..454d124da 100644 --- a/lib/src/screens/restore/restore_options_page.dart +++ b/lib/src/screens/restore/restore_options_page.dart @@ -7,6 +7,7 @@ import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart'; import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; import 'package:cake_wallet/src/widgets/option_tile.dart'; import 'package:cake_wallet/themes/extensions/option_tile_theme.dart'; +import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/permission_handler.dart'; import 'package:cake_wallet/utils/responsive_layout_util.dart'; import 'package:cake_wallet/utils/show_pop_up.dart'; @@ -56,17 +57,18 @@ class RestoreOptionsPage extends BasePage { description: S.of(context).restore_description_from_backup, ), ), - Padding( - padding: EdgeInsets.only(top: 24), - child: OptionTile( - onPressed: () => Navigator.pushNamed( - context, Routes.restoreWalletFromHardwareWallet, - arguments: isNewInstall), - image: imageLedger, - title: S.of(context).restore_title_from_hardware_wallet, - description: S.of(context).restore_description_from_hardware_wallet, + if (DeviceInfo.instance.isMobile) + Padding( + padding: EdgeInsets.only(top: 24), + child: OptionTile( + onPressed: () => Navigator.pushNamed( + context, Routes.restoreWalletFromHardwareWallet, + arguments: isNewInstall), + image: imageLedger, + title: S.of(context).restore_title_from_hardware_wallet, + description: S.of(context).restore_description_from_hardware_wallet, + ), ), - ), Padding( padding: EdgeInsets.only(top: 24), child: OptionTile( diff --git a/lib/src/screens/settings/privacy_page.dart b/lib/src/screens/settings/privacy_page.dart index 7e7f3589b..0eaf3ffbd 100644 --- a/lib/src/screens/settings/privacy_page.dart +++ b/lib/src/screens/settings/privacy_page.dart @@ -103,6 +103,14 @@ class PrivacyPage extends BasePage { _privacySettingsViewModel.setUsePolygonScan(value); }, ), + if (_privacySettingsViewModel.canUseTronGrid) + SettingsSwitcherCell( + title: S.current.trongrid_history, + value: _privacySettingsViewModel.useTronGrid, + onValueChange: (BuildContext _, bool value) { + _privacySettingsViewModel.setUseTronGrid(value); + }, + ), SettingsCellWithArrow( title: S.current.domain_looks_up, handler: (context) => Navigator.of(context).pushNamed(Routes.domainLookupsPage), diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index cd9b44391..ada08c1b6 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -99,6 +99,7 @@ abstract class SettingsStoreBase with Store { required this.pinNativeTokenAtTop, required this.useEtherscan, required this.usePolygonScan, + required this.useTronGrid, required this.defaultNanoRep, required this.defaultBananoRep, required this.lookupsTwitter, @@ -397,6 +398,11 @@ abstract class SettingsStoreBase with Store { (bool usePolygonScan) => _sharedPreferences.setBool(PreferencesKey.usePolygonScan, usePolygonScan)); + reaction( + (_) => useTronGrid, + (bool useTronGrid) => + _sharedPreferences.setBool(PreferencesKey.useTronGrid, useTronGrid)); + reaction((_) => defaultNanoRep, (String nanoRep) => _sharedPreferences.setString(PreferencesKey.defaultNanoRep, nanoRep)); @@ -674,6 +680,9 @@ abstract class SettingsStoreBase with Store { @observable bool usePolygonScan; + @observable + bool useTronGrid; + @observable String defaultNanoRep; @@ -846,6 +855,7 @@ abstract class SettingsStoreBase with Store { : defaultSeedPhraseLength; final useEtherscan = sharedPreferences.getBool(PreferencesKey.useEtherscan) ?? true; final usePolygonScan = sharedPreferences.getBool(PreferencesKey.usePolygonScan) ?? true; + final useTronGrid = sharedPreferences.getBool(PreferencesKey.useTronGrid) ?? true; final defaultNanoRep = sharedPreferences.getString(PreferencesKey.defaultNanoRep) ?? ""; final defaultBananoRep = sharedPreferences.getString(PreferencesKey.defaultBananoRep) ?? ""; final lookupsTwitter = sharedPreferences.getBool(PreferencesKey.lookupsTwitter) ?? true; @@ -1090,6 +1100,7 @@ abstract class SettingsStoreBase with Store { pinNativeTokenAtTop: pinNativeTokenAtTop, useEtherscan: useEtherscan, usePolygonScan: usePolygonScan, + useTronGrid: useTronGrid, defaultNanoRep: defaultNanoRep, defaultBananoRep: defaultBananoRep, lookupsTwitter: lookupsTwitter, @@ -1227,6 +1238,7 @@ abstract class SettingsStoreBase with Store { pinNativeTokenAtTop = sharedPreferences.getBool(PreferencesKey.pinNativeTokenAtTop) ?? true; useEtherscan = sharedPreferences.getBool(PreferencesKey.useEtherscan) ?? true; usePolygonScan = sharedPreferences.getBool(PreferencesKey.usePolygonScan) ?? true; + useTronGrid = sharedPreferences.getBool(PreferencesKey.useTronGrid) ?? true; defaultNanoRep = sharedPreferences.getString(PreferencesKey.defaultNanoRep) ?? ""; defaultBananoRep = sharedPreferences.getString(PreferencesKey.defaultBananoRep) ?? ""; lookupsTwitter = sharedPreferences.getBool(PreferencesKey.lookupsTwitter) ?? true; diff --git a/lib/tron/cw_tron.dart b/lib/tron/cw_tron.dart index 6e4b0a7b0..52b4f59f7 100644 --- a/lib/tron/cw_tron.dart +++ b/lib/tron/cw_tron.dart @@ -111,4 +111,9 @@ class CWTron extends Tron { @override String? getTronTRC20EstimatedFee(WalletBase wallet) => (wallet as TronWallet).trc20EstimatedFee; + + @override + void updateTronGridUsageState(WalletBase wallet, bool isEnabled) { + (wallet as TronWallet).updateScanProviderUsageState(isEnabled); + } } diff --git a/lib/view_model/hardware_wallet/ledger_view_model.dart b/lib/view_model/hardware_wallet/ledger_view_model.dart index 453df44db..06ddaf275 100644 --- a/lib/view_model/hardware_wallet/ledger_view_model.dart +++ b/lib/view_model/hardware_wallet/ledger_view_model.dart @@ -2,27 +2,34 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/ethereum/ethereum.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/polygon/polygon.dart'; +import 'package:cake_wallet/utils/device_info.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:ledger_flutter/ledger_flutter.dart'; import 'package:permission_handler/permission_handler.dart'; class LedgerViewModel { - final Ledger ledger = Ledger( - options: LedgerOptions( - scanMode: ScanMode.balanced, - maxScanDuration: const Duration(minutes: 5), - ), - onPermissionRequest: (_) async { - Map statuses = await [ - Permission.bluetoothScan, - Permission.bluetoothConnect, - Permission.bluetoothAdvertise, - ].request(); + late final Ledger ledger; - return statuses.values.where((status) => status.isDenied).isEmpty; - }, - ); + LedgerViewModel() { + if (DeviceInfo.instance.isMobile) { + ledger = Ledger( + options: LedgerOptions( + scanMode: ScanMode.balanced, + maxScanDuration: const Duration(minutes: 5), + ), + onPermissionRequest: (_) async { + Map statuses = await [ + Permission.bluetoothScan, + Permission.bluetoothConnect, + Permission.bluetoothAdvertise, + ].request(); + + return statuses.values.where((status) => status.isDenied).isEmpty; + }, + ); + } + } Future connectLedger(LedgerDevice device) async { await ledger.connect(device); diff --git a/lib/view_model/link_view_model.dart b/lib/view_model/link_view_model.dart index 714b57e53..99aed486e 100644 --- a/lib/view_model/link_view_model.dart +++ b/lib/view_model/link_view_model.dart @@ -7,19 +7,14 @@ import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/utils/payment_request.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; -import 'package:mobx/mobx.dart'; -part 'link_view_model.g.dart'; - -class LinkViewModel = LinkViewModelBase with _$LinkViewModel; - -abstract class LinkViewModelBase with Store { - LinkViewModelBase({ +class LinkViewModel { + LinkViewModel({ required this.settingsStore, required this.appStore, required this.authenticationStore, required this.navigatorKey, - }) {} + }); final SettingsStore settingsStore; final AppStore appStore; diff --git a/lib/view_model/settings/privacy_settings_view_model.dart b/lib/view_model/settings/privacy_settings_view_model.dart index 9ebbd92bb..9f0ffa14c 100644 --- a/lib/view_model/settings/privacy_settings_view_model.dart +++ b/lib/view_model/settings/privacy_settings_view_model.dart @@ -3,6 +3,7 @@ import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/ethereum/ethereum.dart'; import 'package:cake_wallet/polygon/polygon.dart'; import 'package:cake_wallet/store/settings_store.dart'; +import 'package:cake_wallet/tron/tron.dart'; import 'package:cw_core/balance.dart'; import 'package:cw_core/transaction_history.dart'; import 'package:cw_core/transaction_info.dart'; @@ -70,6 +71,9 @@ abstract class PrivacySettingsViewModelBase with Store { @computed bool get usePolygonScan => _settingsStore.usePolygonScan; + @computed + bool get useTronGrid => _settingsStore.useTronGrid; + @computed bool get lookupTwitter => _settingsStore.lookupsTwitter; @@ -92,6 +96,8 @@ abstract class PrivacySettingsViewModelBase with Store { bool get canUsePolygonScan => _wallet.type == WalletType.polygon; + bool get canUseTronGrid => _wallet.type == WalletType.tron; + @action void setShouldSaveRecipientAddress(bool value) => _settingsStore.shouldSaveRecipientAddress = value; @@ -143,4 +149,10 @@ abstract class PrivacySettingsViewModelBase with Store { _settingsStore.usePolygonScan = value; polygon!.updatePolygonScanUsageState(_wallet, value); } + + @action + void setUseTronGrid(bool value) { + _settingsStore.useTronGrid = value; + tron!.updateTronGridUsageState(_wallet, value); + } } diff --git a/macos/Podfile.lock b/macos/Podfile.lock index f1f72a818..3299cd5bd 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -122,10 +122,10 @@ SPEC CHECKSUMS: OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c package_info: 6eba2fd8d3371dda2d85c8db6fe97488f24b74b2 package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce - path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c + path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 share_plus_macos: 853ee48e7dce06b633998ca0735d482dd671ade4 - shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 + shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 url_launcher_macos: d2691c7dd33ed713bf3544850a623080ec693d95 wakelock_plus: 4783562c9a43d209c458cb9b30692134af456269 diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 911fa9fcc..d14d203c6 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -207,7 +207,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 33CC10EC2044A3C60003C045 = { diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 8536e9a81..fd9942aa8 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ @@ -31,7 +31,7 @@ @@ -54,7 +54,7 @@ @@ -71,7 +71,7 @@ diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index ab6579eef..137e34ef8 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "يجب أن تكون قيمة المبلغ أكبر من أو تساوي ${minAmount} ${fiatCurrency}", "more_options": "المزيد من الخيارات", "name": "ﻢﺳﺍ", - "nano_gpt_thanks_message": "شكرا لاستخدام nanogpt! تذكر أن تعود إلى المتصفح بعد اكتمال معاملتك!", - "nanogpt_subtitle": "جميع النماذج الأحدث (GPT-4 ، Claude). \\ nno اشتراك ، ادفع مع Crypto.", "nano_current_rep": "الممثل الحالي", + "nano_gpt_thanks_message": "شكرا لاستخدام nanogpt! تذكر أن تعود إلى المتصفح بعد اكتمال معاملتك!", "nano_pick_new_rep": "اختر ممثلًا جديدًا", + "nanogpt_subtitle": "جميع النماذج الأحدث (GPT-4 ، Claude). \\ nno اشتراك ، ادفع مع Crypto.", "narrow": "ضيق", "new_first_wallet_text": "حافظ بسهولة على أمان العملة المشفرة", "new_node_testing": "تجربة العقدة الجديدة", @@ -745,6 +745,7 @@ "transaction_sent_notice": "إذا لم تستمر الشاشة بعد دقيقة واحدة ، فتحقق من مستكشف البلوك والبريد الإلكتروني.", "transactions": "المعاملات", "transactions_by_date": "المعاملات حسب التاريخ", + "trongrid_history": "تاريخ ترونغريد", "trusted": "موثوق به", "tx_commit_exception_no_dust_on_change": "يتم رفض المعاملة مع هذا المبلغ. باستخدام هذه العملات المعدنية ، يمكنك إرسال ${min} دون تغيير أو ${max} الذي يعيد التغيير.", "tx_commit_failed": "فشل ارتكاب المعاملة. يرجى الاتصال بالدعم.", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index 6b6a8be1a..ae2877ab1 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Сумата трябва да бъде най-малко ${minAmount} ${fiatCurrency}", "more_options": "Още настройки", "name": "Име", - "nano_gpt_thanks_message": "Благодаря, че използвахте Nanogpt! Не забравяйте да се върнете обратно към браузъра, след като транзакцията ви приключи!", - "nanogpt_subtitle": "Всички най-нови модели (GPT-4, Claude). \\ Nno абонамент, платете с Crypto.", "nano_current_rep": "Настоящ представител", + "nano_gpt_thanks_message": "Благодаря, че използвахте Nanogpt! Не забравяйте да се върнете обратно към браузъра, след като транзакцията ви приключи!", "nano_pick_new_rep": "Изберете нов представител", + "nanogpt_subtitle": "Всички най-нови модели (GPT-4, Claude). \\ Nno абонамент, платете с Crypto.", "narrow": "Тесен", "new_first_wallet_text": "Лесно пазете криптовалутата си в безопасност", "new_node_testing": "Тестване на нов node", @@ -745,6 +745,7 @@ "transaction_sent_notice": "Ако процесът продължи повече от 1 минута, проверете някой block explorer и своя имейл.", "transactions": "Транзакции", "transactions_by_date": "Транзакции по дата", + "trongrid_history": "Trongrid History", "trusted": "Надежден", "tx_commit_exception_no_dust_on_change": "Сделката се отхвърля с тази сума. С тези монети можете да изпратите ${min} без промяна или ${max}, която връща промяна.", "tx_commit_failed": "Компетацията на транзакцията не успя. Моля, свържете се с поддръжката.", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 86a61a5af..2f61782c8 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Částka musí být větší nebo rovna ${minAmount} ${fiatCurrency}", "more_options": "Více možností", "name": "název", - "nano_gpt_thanks_message": "Děkujeme za používání Nanogpt! Nezapomeňte se po dokončení transakce vydat zpět do prohlížeče!", - "nanogpt_subtitle": "Všechny nejnovější modely (GPT-4, Claude). \\ Nno předplatné, plaťte krypto.", "nano_current_rep": "Současný zástupce", + "nano_gpt_thanks_message": "Děkujeme za používání Nanogpt! Nezapomeňte se po dokončení transakce vydat zpět do prohlížeče!", "nano_pick_new_rep": "Vyberte nového zástupce", + "nanogpt_subtitle": "Všechny nejnovější modely (GPT-4, Claude). \\ Nno předplatné, plaťte krypto.", "narrow": "Úzký", "new_first_wallet_text": "Snadno udržujte svou kryptoměnu v bezpečí", "new_node_testing": "Testování nového uzlu", @@ -745,6 +745,7 @@ "transaction_sent_notice": "Pokud proces nepokročí během 1 minuty, zkontrolujte block explorer a svůj e-mail.", "transactions": "Transakce", "transactions_by_date": "Transakce podle data", + "trongrid_history": "Trongridní historie", "trusted": "Důvěřovat", "tx_commit_exception_no_dust_on_change": "Transakce je zamítnuta s touto částkou. S těmito mincemi můžete odeslat ${min} bez změny nebo ${max}, které se vrátí změna.", "tx_commit_failed": "Transakce COMPORT selhala. Kontaktujte prosím podporu.", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index c0639d88d..edfc152e1 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Der Wert des Betrags muss größer oder gleich ${minAmount} ${fiatCurrency} sein", "more_options": "Weitere Optionen", "name": "Name", - "nano_gpt_thanks_message": "Danke, dass du Nanogpt benutzt hast! Denken Sie daran, nach Abschluss Ihrer Transaktion zurück zum Browser zu gehen!", - "nanogpt_subtitle": "Alle neuesten Modelle (GPT-4, Claude).", "nano_current_rep": "Aktueller Vertreter", + "nano_gpt_thanks_message": "Danke, dass du Nanogpt benutzt hast! Denken Sie daran, nach Abschluss Ihrer Transaktion zurück zum Browser zu gehen!", "nano_pick_new_rep": "Wählen Sie einen neuen Vertreter aus", + "nanogpt_subtitle": "Alle neuesten Modelle (GPT-4, Claude).", "narrow": "Eng", "new_first_wallet_text": "Bewahren Sie Ihre Kryptowährung einfach sicher auf", "new_node_testing": "Neuen Knoten testen", @@ -746,6 +746,7 @@ "transaction_sent_notice": "Wenn der Bildschirm nach 1 Minute nicht weitergeht, überprüfen Sie einen Block-Explorer und Ihre E-Mail.", "transactions": "Transaktionen", "transactions_by_date": "Transaktionen nach Datum", + "trongrid_history": "Tronglidgeschichte", "trusted": "Vertrauenswürdige", "tx_commit_exception_no_dust_on_change": "Die Transaktion wird diesen Betrag abgelehnt. Mit diesen Münzen können Sie ${min} ohne Veränderung oder ${max} senden, die Änderungen zurückgeben.", "tx_commit_failed": "Transaktionsausschüsse ist fehlgeschlagen. Bitte wenden Sie sich an Support.", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 2ee31b491..636689380 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Value of the amount must be more or equal to ${minAmount} ${fiatCurrency}", "more_options": "More Options", "name": "Name", - "nano_gpt_thanks_message": "Thanks for using NanoGPT! Remember to head back to the browser after your transaction completes!", - "nanogpt_subtitle": "All the newest models (GPT-4, Claude).\\nNo subscription, pay with crypto.", "nano_current_rep": "Current Representative", + "nano_gpt_thanks_message": "Thanks for using NanoGPT! Remember to head back to the browser after your transaction completes!", "nano_pick_new_rep": "Pick a new representative", + "nanogpt_subtitle": "All the newest models (GPT-4, Claude).\\nNo subscription, pay with crypto.", "narrow": "Narrow", "new_first_wallet_text": "Keep your crypto safe, piece of cake", "new_node_testing": "New node testing", @@ -745,6 +745,7 @@ "transaction_sent_notice": "If the screen doesn’t proceed after 1 minute, check a block explorer and your email.", "transactions": "Transactions", "transactions_by_date": "Transactions by date", + "trongrid_history": "TronGrid history", "trusted": "Trusted", "tx_commit_exception_no_dust_on_change": "The transaction is rejected with this amount. With these coins you can send ${min} without change or ${max} that returns change.", "tx_commit_failed": "Transaction commit failed. Please contact support.", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 8e4177298..b3f89fc2e 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "El valor de la cantidad debe ser mayor o igual a ${minAmount} ${fiatCurrency}", "more_options": "Más Opciones", "name": "Nombre", - "nano_gpt_thanks_message": "¡Gracias por usar nanogpt! ¡Recuerde regresar al navegador después de que se complete su transacción!", - "nanogpt_subtitle": "Todos los modelos más nuevos (GPT-4, Claude). \\ Nno suscripción, pague con cripto.", "nano_current_rep": "Representante actual", + "nano_gpt_thanks_message": "¡Gracias por usar nanogpt! ¡Recuerde regresar al navegador después de que se complete su transacción!", "nano_pick_new_rep": "Elija un nuevo representante", + "nanogpt_subtitle": "Todos los modelos más nuevos (GPT-4, Claude). \\ Nno suscripción, pague con cripto.", "narrow": "Angosto", "new_first_wallet_text": "Mantenga fácilmente su criptomoneda segura", "new_node_testing": "Prueba de nuevos nodos", @@ -746,6 +746,7 @@ "transaction_sent_notice": "Si la pantalla no continúa después de 1 minuto, revisa un explorador de bloques y tu correo electrónico.", "transactions": "Actas", "transactions_by_date": "Transacciones por fecha", + "trongrid_history": "Historia trongrid", "trusted": "de confianza", "tx_commit_exception_no_dust_on_change": "La transacción se rechaza con esta cantidad. Con estas monedas puede enviar ${min} sin cambios o ${max} que devuelve el cambio.", "tx_commit_failed": "La confirmación de transacción falló. Póngase en contacto con el soporte.", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 4c589b27f..a624e487c 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Le montant doit être au moins égal à ${minAmount} ${fiatCurrency}", "more_options": "Plus d'options", "name": "Nom", - "nano_gpt_thanks_message": "Merci d'avoir utilisé Nanogpt! N'oubliez pas de retourner au navigateur une fois votre transaction terminée!", - "nanogpt_subtitle": "Tous les modèles les plus récents (GPT-4, Claude). \\ NNO abonnement, payez avec crypto.", "nano_current_rep": "Représentant actuel", + "nano_gpt_thanks_message": "Merci d'avoir utilisé Nanogpt! N'oubliez pas de retourner au navigateur une fois votre transaction terminée!", "nano_pick_new_rep": "Choisissez un nouveau représentant", + "nanogpt_subtitle": "Tous les modèles les plus récents (GPT-4, Claude). \\ NNO abonnement, payez avec crypto.", "narrow": "Étroit", "new_first_wallet_text": "Gardez facilement votre crypto-monnaie en sécurité", "new_node_testing": "Test du nouveau nœud", @@ -745,6 +745,7 @@ "transaction_sent_notice": "Si l'écran ne continue pas après 1 minute, vérifiez un explorateur de blocs et votre e-mail.", "transactions": "Transactions", "transactions_by_date": "Transactions par date", + "trongrid_history": "Histoire de la trongride", "trusted": "de confiance", "tx_commit_exception_no_dust_on_change": "La transaction est rejetée avec ce montant. Avec ces pièces, vous pouvez envoyer ${min} sans changement ou ${max} qui renvoie le changement.", "tx_commit_failed": "La validation de la transaction a échoué. Veuillez contacter l'assistance.", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 3fe21b3f1..68635aa5c 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Darajar adadin dole ne ya zama fiye ko daidai da ${minAmount} ${fiatCurrency}", "more_options": "Ƙarin Zaɓuɓɓuka", "name": "Suna", - "nano_gpt_thanks_message": "Na gode da amfani da Nanogpt! Ka tuna da komawa zuwa mai bincike bayan ma'amalar ka ta cika!", - "nanogpt_subtitle": "Duk sabbin samfuran (GPT-4, CLODE). \\ NNO biyan kuɗi, biya tare da crypto.", "nano_current_rep": "Wakilin Yanzu", + "nano_gpt_thanks_message": "Na gode da amfani da Nanogpt! Ka tuna da komawa zuwa mai bincike bayan ma'amalar ka ta cika!", "nano_pick_new_rep": "Dauki sabon wakili", + "nanogpt_subtitle": "Duk sabbin samfuran (GPT-4, CLODE). \\ NNO biyan kuɗi, biya tare da crypto.", "narrow": "kunkuntar", "new_first_wallet_text": "A sauƙaƙe kiyaye kuzarin ku", "new_node_testing": "Sabbin gwajin kumburi", @@ -747,6 +747,7 @@ "transaction_sent_notice": "Idan allon bai ci gaba ba bayan minti 1, duba mai binciken toshewa da imel ɗin ku.", "transactions": "Ma'amaloli", "transactions_by_date": "Ma'amaloli ta kwanan wata", + "trongrid_history": "Tarihin Trongrid", "trusted": "Amintacce", "tx_commit_exception_no_dust_on_change": "An ƙi ma'amala da wannan adadin. Tare da waɗannan tsabar kudi Zaka iya aika ${min}, ba tare da canji ba ko ${max} wanda ya dawo canzawa.", "tx_commit_failed": "Ma'amala ya kasa. Da fatan za a tuntuɓi goyan baya.", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index e2eb28aa2..027b5448d 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "राशि का मूल्य अधिक है या करने के लिए बराबर होना चाहिए ${minAmount} ${fiatCurrency}", "more_options": "और विकल्प", "name": "नाम", - "nano_gpt_thanks_message": "Nanogpt का उपयोग करने के लिए धन्यवाद! अपने लेन -देन के पूरा होने के बाद ब्राउज़र पर वापस जाना याद रखें!", - "nanogpt_subtitle": "सभी नवीनतम मॉडल (GPT-4, क्लाउड)। \\ nno सदस्यता, क्रिप्टो के साथ भुगतान करें।", "nano_current_rep": "वर्तमान प्रतिनिधि", + "nano_gpt_thanks_message": "Nanogpt का उपयोग करने के लिए धन्यवाद! अपने लेन -देन के पूरा होने के बाद ब्राउज़र पर वापस जाना याद रखें!", "nano_pick_new_rep": "एक नया प्रतिनिधि चुनें", + "nanogpt_subtitle": "सभी नवीनतम मॉडल (GPT-4, क्लाउड)। \\ nno सदस्यता, क्रिप्टो के साथ भुगतान करें।", "narrow": "सँकरा", "new_first_wallet_text": "आसानी से अपनी क्रिप्टोक्यूरेंसी को सुरक्षित रखें", "new_node_testing": "नई नोड परीक्षण", @@ -747,6 +747,7 @@ "transaction_sent_notice": "अगर 1 मिनट के बाद भी स्क्रीन आगे नहीं बढ़ती है, तो ब्लॉक एक्सप्लोरर और अपना ईमेल देखें।", "transactions": "लेन-देन", "transactions_by_date": "तारीख से लेन-देन", + "trongrid_history": "ट्रॉन्ग्रिड का इतिहास", "trusted": "भरोसा", "tx_commit_exception_no_dust_on_change": "लेनदेन को इस राशि से खारिज कर दिया जाता है। इन सिक्कों के साथ आप चेंज या ${min} के बिना ${max} को भेज सकते हैं जो परिवर्तन लौटाता है।", "tx_commit_failed": "लेन -देन प्रतिबद्ध विफल। कृपया संपर्क समर्थन करें।", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 079de0c4f..5edbc3633 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Vrijednost iznosa mora biti veća ili jednaka ${minAmount} ${fiatCurrency}", "more_options": "Više opcija", "name": "Ime", - "nano_gpt_thanks_message": "Hvala što ste koristili nanogpt! Ne zaboravite da se vratite u preglednik nakon što vam se transakcija završi!", - "nanogpt_subtitle": "Svi najnoviji modeli (GPT-4, Claude). \\ NNO pretplata, plaćajte kripto.", "nano_current_rep": "Trenutni predstavnik", + "nano_gpt_thanks_message": "Hvala što ste koristili nanogpt! Ne zaboravite da se vratite u preglednik nakon što vam se transakcija završi!", "nano_pick_new_rep": "Odaberite novog predstavnika", + "nanogpt_subtitle": "Svi najnoviji modeli (GPT-4, Claude). \\ NNO pretplata, plaćajte kripto.", "narrow": "Usko", "new_first_wallet_text": "Jednostavno čuvajte svoju kripto valutu", "new_node_testing": "Provjera novog nodea", @@ -745,6 +745,7 @@ "transaction_sent_notice": "Ako se zaslon ne nastavi nakon 1 minute, provjerite block explorer i svoju e-poštu.", "transactions": "Transakcije", "transactions_by_date": "Transakcije prema datumu", + "trongrid_history": "Povijest Trongrida", "trusted": "vjerovao", "tx_commit_exception_no_dust_on_change": "Transakcija se odbija s tim iznosom. Pomoću ovih kovanica možete poslati ${min} bez promjene ili ${max} koja vraća promjenu.", "tx_commit_failed": "Obveza transakcije nije uspjela. Molimo kontaktirajte podršku.", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index ae9e4e38f..2551506c0 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Nilai jumlah harus lebih atau sama dengan ${minAmount} ${fiatCurrency}", "more_options": "Opsi Lainnya", "name": "Nama", - "nano_gpt_thanks_message": "Terima kasih telah menggunakan Nanogpt! Ingatlah untuk kembali ke browser setelah transaksi Anda selesai!", - "nanogpt_subtitle": "Semua model terbaru (GPT-4, Claude). \\ Nno langganan, bayar dengan crypto.", "nano_current_rep": "Perwakilan saat ini", + "nano_gpt_thanks_message": "Terima kasih telah menggunakan Nanogpt! Ingatlah untuk kembali ke browser setelah transaksi Anda selesai!", "nano_pick_new_rep": "Pilih perwakilan baru", + "nanogpt_subtitle": "Semua model terbaru (GPT-4, Claude). \\ Nno langganan, bayar dengan crypto.", "narrow": "Sempit", "new_first_wallet_text": "Dengan mudah menjaga cryptocurrency Anda aman", "new_node_testing": "Pengujian node baru", @@ -748,6 +748,7 @@ "transaction_sent_notice": "Jika layar tidak bergerak setelah 1 menit, periksa block explorer dan email Anda.", "transactions": "Transaksi", "transactions_by_date": "Transaksi berdasarkan tanggal", + "trongrid_history": "Sejarah Trongrid", "trusted": "Dipercayai", "tx_commit_exception_no_dust_on_change": "Transaksi ditolak dengan jumlah ini. Dengan koin ini Anda dapat mengirim ${min} tanpa perubahan atau ${max} yang mengembalikan perubahan.", "tx_commit_failed": "Transaksi Gagal. Silakan hubungi Dukungan.", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 5fa1b52ef..9bb2ca1eb 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -367,10 +367,10 @@ "moonpay_alert_text": "Il valore dell'importo deve essere maggiore o uguale a ${minAmount} ${fiatCurrency}", "more_options": "Altre opzioni", "name": "Nome", - "nano_gpt_thanks_message": "Grazie per aver usato il nanogpt! Ricorda di tornare al browser dopo il completamento della transazione!", - "nanogpt_subtitle": "Tutti i modelli più recenti (GPT-4, Claude). Abbonamento nno, paga con cripto.", "nano_current_rep": "Rappresentante attuale", + "nano_gpt_thanks_message": "Grazie per aver usato il nanogpt! Ricorda di tornare al browser dopo il completamento della transazione!", "nano_pick_new_rep": "Scegli un nuovo rappresentante", + "nanogpt_subtitle": "Tutti i modelli più recenti (GPT-4, Claude). Abbonamento nno, paga con cripto.", "narrow": "Stretto", "new_first_wallet_text": "Mantieni facilmente la tua criptovaluta al sicuro", "new_node_testing": "Test novo nodo", @@ -747,6 +747,7 @@ "transaction_sent_notice": "Se lo schermo non procede dopo 1 minuto, controlla un block explorer e la tua email.", "transactions": "Transazioni", "transactions_by_date": "Transazioni per data", + "trongrid_history": "Storia del trongride", "trusted": "di fiducia", "tx_commit_exception_no_dust_on_change": "La transazione viene respinta con questo importo. Con queste monete è possibile inviare ${min} senza modifiche o ${max} che restituisce il cambiamento.", "tx_commit_failed": "Commit di transazione non riuscita. Si prega di contattare il supporto.", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index a01df3c07..55af8cbd1 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -367,10 +367,10 @@ "moonpay_alert_text": "金額の値は以上でなければなりません ${minAmount} ${fiatCurrency}", "more_options": "その他のオプション", "name": "名前", - "nano_gpt_thanks_message": "NanoGptを使用してくれてありがとう!トランザクションが完了したら、ブラウザに戻ることを忘れないでください!", - "nanogpt_subtitle": "すべての最新モデル(GPT-4、Claude)。\\ nnoサブスクリプション、暗号で支払います。", "nano_current_rep": "現在の代表", + "nano_gpt_thanks_message": "NanoGptを使用してくれてありがとう!トランザクションが完了したら、ブラウザに戻ることを忘れないでください!", "nano_pick_new_rep": "新しい代表者を選びます", + "nanogpt_subtitle": "すべての最新モデル(GPT-4、Claude)。\\ nnoサブスクリプション、暗号で支払います。", "narrow": "狭い", "new_first_wallet_text": "暗号通貨を簡単に安全に保ちます", "new_node_testing": "新しいノードのテスト", @@ -746,6 +746,7 @@ "transaction_sent_notice": "1分経っても画面が進まない場合は、ブロックエクスプローラーとメールアドレスを確認してください。", "transactions": "取引", "transactions_by_date": "日付ごとの取引", + "trongrid_history": "トロンリッドの歴史", "trusted": "信頼できる", "tx_commit_exception_no_dust_on_change": "この金額ではトランザクションは拒否されます。 これらのコインを使用すると、おつりなしの ${min} またはおつりを返す ${max} を送信できます。", "tx_commit_failed": "トランザクションコミットは失敗しました。サポートに連絡してください。", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 53cbeb01f..3f710becb 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "금액은 다음보다 크거나 같아야합니다 ${minAmount} ${fiatCurrency}", "more_options": "추가 옵션", "name": "이름", - "nano_gpt_thanks_message": "Nanogpt를 사용해 주셔서 감사합니다! 거래가 완료된 후 브라우저로 돌아가는 것을 잊지 마십시오!", - "nanogpt_subtitle": "모든 최신 모델 (GPT-4, Claude). \\ nno 구독, Crypto로 지불하십시오.", "nano_current_rep": "현재 대표", + "nano_gpt_thanks_message": "Nanogpt를 사용해 주셔서 감사합니다! 거래가 완료된 후 브라우저로 돌아가는 것을 잊지 마십시오!", "nano_pick_new_rep": "새로운 담당자를 선택하십시오", + "nanogpt_subtitle": "모든 최신 모델 (GPT-4, Claude). \\ nno 구독, Crypto로 지불하십시오.", "narrow": "좁은", "new_first_wallet_text": "cryptocurrency를 쉽게 안전하게 유지하십시오", "new_node_testing": "새로운 노드 테스트", @@ -746,6 +746,7 @@ "transaction_sent_notice": "1분 후에도 화면이 진행되지 않으면 블록 익스플로러와 이메일을 확인하세요.", "transactions": "업무", "transactions_by_date": "날짜 별 거래", + "trongrid_history": "트롱 트리드 역사", "trusted": "신뢰할 수 있는", "tx_commit_exception_no_dust_on_change": "이 금액으로 거래가 거부되었습니다. 이 코인을 사용하면 거스름돈 없이 ${min}를 보내거나 거스름돈을 반환하는 ${max}를 보낼 수 있습니다.", "tx_commit_failed": "거래 커밋이 실패했습니다. 지원에 연락하십시오.", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index bb2099b15..63c7f4903 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "ပမာဏ၏တန်ဖိုးသည် ${minAmount} ${fiatCurrency} နှင့် ပိုနေရမည်", "more_options": "နောက်ထပ် ရွေးချယ်စရာများ", "name": "နာမည်", - "nano_gpt_thanks_message": "nanogpt ကိုသုံးပြီးကျေးဇူးတင်ပါတယ် သင်၏ငွေပေးငွေယူပြီးနောက် browser သို့ပြန်သွားရန်သတိရပါ။", - "nanogpt_subtitle": "အားလုံးနောက်ဆုံးပေါ်မော်ဒယ်များ (GPT-4, Claude) ။ \\ nno subscription, crypto နှင့်အတူပေးဆောင်။", "nano_current_rep": "လက်ရှိကိုယ်စားလှယ်", + "nano_gpt_thanks_message": "nanogpt ကိုသုံးပြီးကျေးဇူးတင်ပါတယ် သင်၏ငွေပေးငွေယူပြီးနောက် browser သို့ပြန်သွားရန်သတိရပါ။", "nano_pick_new_rep": "အသစ်တစ်ခုကိုရွေးပါ", + "nanogpt_subtitle": "အားလုံးနောက်ဆုံးပေါ်မော်ဒယ်များ (GPT-4, Claude) ။ \\ nno subscription, crypto နှင့်အတူပေးဆောင်။", "narrow": "ကျဉ်းသော", "new_first_wallet_text": "သင့်ရဲ့ cryptocurrencrencres ကိုအလွယ်တကူလုံခြုံစွာထားရှိပါ", "new_node_testing": "နှာခေါင်း အသစ်စမ်းသပ်ခြင်း။", @@ -745,6 +745,7 @@ "transaction_sent_notice": "မျက်နှာပြင်သည် ၁ မိနစ်အကြာတွင် ဆက်လက်မလုပ်ဆောင်ပါက၊ ပိတ်ဆို့ရှာဖွေသူနှင့် သင့်အီးမေးလ်ကို စစ်ဆေးပါ။", "transactions": "ငွေပေးငွေယူ", "transactions_by_date": "ရက်စွဲအလိုက် ငွေလွှဲမှုများ", + "trongrid_history": "Trongrid သမိုင်း", "trusted": "ယုံတယ်။", "tx_commit_exception_no_dust_on_change": "အဆိုပါငွေပေးငွေယူကဒီပမာဏနှင့်အတူပယ်ချခံရသည်။ ဤဒင်္ဂါးပြားများနှင့်အတူပြောင်းလဲမှုကိုပြန်လည်ပြောင်းလဲခြင်းသို့မဟုတ် ${min} မပါဘဲ ${max} ပေးပို့နိုင်သည်။", "tx_commit_failed": "ငွေပေးငွေယူကျူးလွန်မှုပျက်ကွက်။ ကျေးဇူးပြုပြီးပံ့ပိုးမှုဆက်သွယ်ပါ။", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index ca9b5a79f..c75309aa6 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Waarde van het bedrag moet meer of gelijk zijn aan ${minAmount} ${fiatCurrency}", "more_options": "Meer opties", "name": "Naam", - "nano_gpt_thanks_message": "Bedankt voor het gebruik van Nanogpt! Vergeet niet om terug te gaan naar de browser nadat uw transactie is voltooid!", - "nanogpt_subtitle": "Alle nieuwste modellen (GPT-4, Claude). \\ Nno-abonnement, betalen met crypto.", "nano_current_rep": "Huidige vertegenwoordiger", + "nano_gpt_thanks_message": "Bedankt voor het gebruik van Nanogpt! Vergeet niet om terug te gaan naar de browser nadat uw transactie is voltooid!", "nano_pick_new_rep": "Kies een nieuwe vertegenwoordiger", + "nanogpt_subtitle": "Alle nieuwste modellen (GPT-4, Claude). \\ Nno-abonnement, betalen met crypto.", "narrow": "Smal", "new_first_wallet_text": "Houd uw cryptocurrency gemakkelijk veilig", "new_node_testing": "Nieuwe knooppunttest", @@ -745,6 +745,7 @@ "transaction_sent_notice": "Als het scherm na 1 minuut niet verder gaat, controleer dan een blokverkenner en je e-mail.", "transactions": "Transacties", "transactions_by_date": "Transacties op datum", + "trongrid_history": "Trongrid geschiedenis", "trusted": "vertrouwd", "tx_commit_exception_no_dust_on_change": "De transactie wordt afgewezen met dit bedrag. Met deze munten kunt u ${min} verzenden zonder verandering of ${max} die wijziging retourneert.", "tx_commit_failed": "Transactiebewissing is mislukt. Neem contact op met de ondersteuning.", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 44e8c0b95..c78daa836 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Wartość kwoty musi być większa lub równa ${minAmount} ${fiatCurrency}", "more_options": "Więcej opcji", "name": "Nazwa", - "nano_gpt_thanks_message": "Dzięki za użycie Nanogpt! Pamiętaj, aby wrócić do przeglądarki po zakończeniu transakcji!", - "nanogpt_subtitle": "Wszystkie najnowsze modele (GPT-4, Claude). \\ Nno subskrypcja, płacą za pomocą kryptografii.", "nano_current_rep": "Obecny przedstawiciel", + "nano_gpt_thanks_message": "Dzięki za użycie Nanogpt! Pamiętaj, aby wrócić do przeglądarki po zakończeniu transakcji!", "nano_pick_new_rep": "Wybierz nowego przedstawiciela", + "nanogpt_subtitle": "Wszystkie najnowsze modele (GPT-4, Claude). \\ Nno subskrypcja, płacą za pomocą kryptografii.", "narrow": "Wąski", "new_first_wallet_text": "Łatwo zapewnić bezpieczeństwo kryptowalut", "new_node_testing": "Testowanie nowych węzłów", @@ -745,6 +745,7 @@ "transaction_sent_notice": "Jeśli ekran nie zmieni się po 1 minucie, sprawdź eksplorator bloków i swój e-mail.", "transactions": "Transakcje", "transactions_by_date": "Transakcje według daty", + "trongrid_history": "Historia Trongrida", "trusted": "Zaufany", "tx_commit_exception_no_dust_on_change": "Transakcja jest odrzucana z tą kwotą. Za pomocą tych monet możesz wysłać ${min} bez zmiany lub ${max}, które zwraca zmianę.", "tx_commit_failed": "Zatwierdzenie transakcji nie powiodło się. Skontaktuj się z obsługą.", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index b8805e789..710fd5eea 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -367,10 +367,10 @@ "moonpay_alert_text": "O valor do montante deve ser maior ou igual a ${minAmount} ${fiatCurrency}", "more_options": "Mais opções", "name": "Nome", - "nano_gpt_thanks_message": "Obrigado por usar o Nanogpt! Lembre -se de voltar para o navegador após a conclusão da transação!", - "nanogpt_subtitle": "Todos os modelos mais recentes (GPT-4, Claude). \\ Nno assinatura, pagam com criptografia.", "nano_current_rep": "Representante atual", + "nano_gpt_thanks_message": "Obrigado por usar o Nanogpt! Lembre -se de voltar para o navegador após a conclusão da transação!", "nano_pick_new_rep": "Escolha um novo representante", + "nanogpt_subtitle": "Todos os modelos mais recentes (GPT-4, Claude). \\ Nno assinatura, pagam com criptografia.", "narrow": "Estreito", "new_first_wallet_text": "Mantenha sua criptomoeda facilmente segura", "new_node_testing": "Teste de novo nó", @@ -747,6 +747,7 @@ "transaction_sent_notice": "Se a tela não prosseguir após 1 minuto, verifique um explorador de blocos e seu e-mail.", "transactions": "Transações", "transactions_by_date": "Transações por data", + "trongrid_history": "História de Trongrid", "trusted": "confiável", "tx_commit_exception_no_dust_on_change": "A transação é rejeitada com esse valor. Com essas moedas, você pode enviar ${min} sem alteração ou ${max} que retorna alterações.", "tx_commit_failed": "A confirmação da transação falhou. Entre em contato com o suporte.", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 32f513fe5..4780dde5d 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Сумма должна быть больше или равна ${minAmount} ${fiatCurrency}", "more_options": "Дополнительные параметры", "name": "Имя", - "nano_gpt_thanks_message": "Спасибо за использование Nanogpt! Не забудьте вернуться в браузер после завершения транзакции!", - "nanogpt_subtitle": "Все новейшие модели (GPT-4, Claude). \\ Nno Подписка, платите с крипто.", "nano_current_rep": "Нынешний представитель", + "nano_gpt_thanks_message": "Спасибо за использование Nanogpt! Не забудьте вернуться в браузер после завершения транзакции!", "nano_pick_new_rep": "Выберите нового представителя", + "nanogpt_subtitle": "Все новейшие модели (GPT-4, Claude). \\ Nno Подписка, платите с крипто.", "narrow": "Узкий", "new_first_wallet_text": "Легко сохранить свою криптовалюту в безопасности", "new_node_testing": "Тестирование новой ноды", @@ -746,6 +746,7 @@ "transaction_sent_notice": "Если экран не отображается через 1 минуту, проверьте обозреватель блоков и свою электронную почту.", "transactions": "Транзакции", "transactions_by_date": "Сортировать по дате", + "trongrid_history": "История Тронгрида", "trusted": "доверенный", "tx_commit_exception_no_dust_on_change": "Транзакция отклоняется с этой суммой. С этими монетами вы можете отправлять ${min} без изменения или ${max}, которые возвращают изменение.", "tx_commit_failed": "Комплект транзакции не удался. Пожалуйста, свяжитесь с поддержкой.", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 18b9adce9..945cf88de 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "มูลค่าของจำนวนต้องมากกว่าหรือเท่ากับ ${minAmount} ${fiatCurrency}", "more_options": "ตัวเลือกเพิ่มเติม", "name": "ชื่อ", - "nano_gpt_thanks_message": "ขอบคุณที่ใช้ Nanogpt! อย่าลืมกลับไปที่เบราว์เซอร์หลังจากการทำธุรกรรมของคุณเสร็จสิ้น!", - "nanogpt_subtitle": "รุ่นใหม่ล่าสุดทั้งหมด (GPT-4, Claude). การสมัครสมาชิก \\ nno, จ่ายด้วย crypto", "nano_current_rep": "ตัวแทนปัจจุบัน", + "nano_gpt_thanks_message": "ขอบคุณที่ใช้ Nanogpt! อย่าลืมกลับไปที่เบราว์เซอร์หลังจากการทำธุรกรรมของคุณเสร็จสิ้น!", "nano_pick_new_rep": "เลือกตัวแทนใหม่", + "nanogpt_subtitle": "รุ่นใหม่ล่าสุดทั้งหมด (GPT-4, Claude). การสมัครสมาชิก \\ nno, จ่ายด้วย crypto", "narrow": "แคบ", "new_first_wallet_text": "ทำให้สกุลเงินดิจิตอลของคุณปลอดภัยได้อย่างง่ายดาย", "new_node_testing": "การทดสอบโหนดใหม่", @@ -745,6 +745,7 @@ "transaction_sent_notice": "ถ้าหน้าจอไม่ขึ้นหลังจาก 1 นาทีแล้ว ให้ตรวจสอบ block explorer และอีเมลของคุณ", "transactions": "ธุรกรรม", "transactions_by_date": "ธุรกรรมตามวันที่", + "trongrid_history": "ประวัติศาสตร์ Trongrid", "trusted": "มั่นคง", "tx_commit_exception_no_dust_on_change": "ธุรกรรมถูกปฏิเสธด้วยจำนวนเงินนี้ ด้วยเหรียญเหล่านี้คุณสามารถส่ง ${min} โดยไม่ต้องเปลี่ยนแปลงหรือ ${max} ที่ส่งคืนการเปลี่ยนแปลง", "tx_commit_failed": "การทำธุรกรรมล้มเหลว กรุณาติดต่อฝ่ายสนับสนุน", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index 76a94bbe2..6f20a274f 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Ang halaga ng halaga ay dapat na higit pa o katumbas ng ${minAmount} ${fiatCurrency}", "more_options": "Higit pang mga pagpipilian", "name": "Pangalan", - "nano_gpt_thanks_message": "Salamat sa paggamit ng nanogpt! Tandaan na bumalik sa browser matapos makumpleto ang iyong transaksyon!", - "nanogpt_subtitle": "Ang lahat ng mga pinakabagong modelo (GPT-4, Claude). \\ Nno subscription, magbayad gamit ang crypto.", "nano_current_rep": "Kasalukuyang kinatawan", + "nano_gpt_thanks_message": "Salamat sa paggamit ng nanogpt! Tandaan na bumalik sa browser matapos makumpleto ang iyong transaksyon!", "nano_pick_new_rep": "Pumili ng isang bagong kinatawan", + "nanogpt_subtitle": "Ang lahat ng mga pinakabagong modelo (GPT-4, Claude). \\ Nno subscription, magbayad gamit ang crypto.", "narrow": "Makitid", "new_first_wallet_text": "Panatilihing ligtas ang iyong crypto, piraso ng cake", "new_node_testing": "Bagong pagsubok sa node", @@ -745,6 +745,7 @@ "transaction_sent_notice": "Kung ang screen ay hindi magpatuloy pagkatapos ng 1 minuto, suriin ang isang block explorer at ang iyong email.", "transactions": "Mga Transaksyon", "transactions_by_date": "Mga Transaksyon ayon sa Petsa", + "trongrid_history": "Kasaysayan ng Trongrid", "trusted": "Pinagkakatiwalaan", "tx_commit_exception_no_dust_on_change": "Ang transaksyon ay tinanggihan sa halagang ito. Sa mga barya na ito maaari kang magpadala ng ${min} nang walang pagbabago o ${max} na nagbabalik ng pagbabago.", "tx_commit_failed": "Nabigo ang transaksyon sa transaksyon. Mangyaring makipag -ugnay sa suporta.", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 62e541ded..e53f0a2bf 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Tutar ${minAmount} ${fiatCurrency} miktarına eşit veya daha fazla olmalıdır", "more_options": "Daha Fazla Seçenek", "name": "İsim", - "nano_gpt_thanks_message": "Nanogpt kullandığınız için teşekkürler! İşleminiz tamamlandıktan sonra tarayıcıya geri dönmeyi unutmayın!", - "nanogpt_subtitle": "En yeni modeller (GPT-4, Claude). \\ Nno aboneliği, kripto ile ödeme yapın.", "nano_current_rep": "Mevcut temsilci", + "nano_gpt_thanks_message": "Nanogpt kullandığınız için teşekkürler! İşleminiz tamamlandıktan sonra tarayıcıya geri dönmeyi unutmayın!", "nano_pick_new_rep": "Yeni bir temsilci seçin", + "nanogpt_subtitle": "En yeni modeller (GPT-4, Claude). \\ Nno aboneliği, kripto ile ödeme yapın.", "narrow": "Dar", "new_first_wallet_text": "Kripto para biriminizi kolayca güvende tutun", "new_node_testing": "Yeni düğüm test ediliyor", @@ -745,6 +745,7 @@ "transaction_sent_notice": "Ekran 1 dakika sonra ilerlemezse, blok gezgininden ve e-postanızdan kontrol edin.", "transactions": "İşlemler", "transactions_by_date": "Tarihe göre transferler", + "trongrid_history": "Trongrid tarihi", "trusted": "Güvenilir", "tx_commit_exception_no_dust_on_change": "İşlem bu miktarla reddedilir. Bu madeni paralarla değişiklik yapmadan ${min} veya değişikliği döndüren ${max} gönderebilirsiniz.", "tx_commit_failed": "İşlem taahhüdü başarısız oldu. Lütfen Destek ile iletişime geçin.", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 6184fed11..c2f95e560 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "Значення суми має бути більшим або дорівнювати ${minAmount} ${fiatCurrency}", "more_options": "Більше параметрів", "name": "Ім'я", - "nano_gpt_thanks_message": "Дякуємо за використання наногпта! Не забудьте повернутися до браузера після завершення транзакції!", - "nanogpt_subtitle": "Усі найновіші моделі (GPT-4, Claude). \\ Nno підписка, оплата криптовалютою.", "nano_current_rep": "Поточний представник", + "nano_gpt_thanks_message": "Дякуємо за використання наногпта! Не забудьте повернутися до браузера після завершення транзакції!", "nano_pick_new_rep": "Виберіть нового представника", + "nanogpt_subtitle": "Усі найновіші моделі (GPT-4, Claude). \\ Nno підписка, оплата криптовалютою.", "narrow": "вузькі", "new_first_wallet_text": "Легко зберігайте свою криптовалюту в безпеці", "new_node_testing": "Тестування нового вузла", @@ -746,6 +746,7 @@ "transaction_sent_notice": "Якщо екран не відображається через 1 хвилину, перевірте провідник блоків і свою електронну пошту.", "transactions": "Транзакції", "transactions_by_date": "Сортувати по даті", + "trongrid_history": "Тронгрідська історія", "trusted": "довіряють", "tx_commit_exception_no_dust_on_change": "Транзакція відхилена цією сумою. За допомогою цих монет ви можете надіслати ${min} без змін або ${max}, що повертає зміни.", "tx_commit_failed": "Транзакційна комісія не вдалося. Будь ласка, зв'яжіться з підтримкою.", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index dadd3505b..17d8e691e 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "رقم کی قدر ${minAmount} ${fiatCurrency} کے برابر یا زیادہ ہونی چاہیے۔", "more_options": "مزید زرائے", "name": "ﻡﺎﻧ", - "nano_gpt_thanks_message": "نانوگپٹ استعمال کرنے کا شکریہ! اپنے لین دین کی تکمیل کے بعد براؤزر کی طرف واپس جانا یاد رکھیں!", - "nanogpt_subtitle": "تمام تازہ ترین ماڈل (GPT-4 ، کلاڈ)۔ n n no سبسکرپشن ، کریپٹو کے ساتھ ادائیگی کریں۔", "nano_current_rep": "موجودہ نمائندہ", + "nano_gpt_thanks_message": "نانوگپٹ استعمال کرنے کا شکریہ! اپنے لین دین کی تکمیل کے بعد براؤزر کی طرف واپس جانا یاد رکھیں!", "nano_pick_new_rep": "ایک نیا نمائندہ منتخب کریں", + "nanogpt_subtitle": "تمام تازہ ترین ماڈل (GPT-4 ، کلاڈ)۔ n n no سبسکرپشن ، کریپٹو کے ساتھ ادائیگی کریں۔", "narrow": "تنگ", "new_first_wallet_text": "آسانی سے اپنے cryptocurrency محفوظ رکھیں", "new_node_testing": "نیا نوڈ ٹیسٹنگ", @@ -747,6 +747,7 @@ "transaction_sent_notice": "اگر اسکرین 1 منٹ کے بعد آگے نہیں بڑھتی ہے، تو بلاک ایکسپلورر اور اپنا ای میل چیک کریں۔", "transactions": "لین دین", "transactions_by_date": "تاریخ کے لحاظ سے لین دین", + "trongrid_history": "ٹرانگریڈ ہسٹری", "trusted": "قابل اعتماد", "tx_commit_exception_no_dust_on_change": "اس رقم سے لین دین کو مسترد کردیا گیا ہے۔ ان سککوں کے ذریعہ آپ بغیر کسی تبدیلی کے ${min} یا ${max} بھیج سکتے ہیں جو لوٹتے ہیں۔", "tx_commit_failed": "ٹرانزیکشن کمٹ ناکام ہوگیا۔ براہ کرم سپورٹ سے رابطہ کریں۔", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index d9fa48a45..5838b1dba 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -367,10 +367,10 @@ "moonpay_alert_text": "Iye owó kò gbọ́dọ̀ kéré ju ${minAmount} ${fiatCurrency}", "more_options": "Ìyàn àfikún", "name": "Oruko", - "nano_gpt_thanks_message": "O ṣeun fun lilo Nonnogt! Ranti lati tẹle pada si ẹrọ lilọ kiri ayelujara lẹhin iṣowo rẹ pari!", - "nanogpt_subtitle": "Gbogbo awọn awoṣe tuntun (GPT-4, Claude). \\ Nno alabapin kan, sanwo pẹlu Crypto.", "nano_current_rep": "Aṣoju lọwọlọwọ", + "nano_gpt_thanks_message": "O ṣeun fun lilo Nonnogt! Ranti lati tẹle pada si ẹrọ lilọ kiri ayelujara lẹhin iṣowo rẹ pari!", "nano_pick_new_rep": "Mu aṣoju tuntun kan", + "nanogpt_subtitle": "Gbogbo awọn awoṣe tuntun (GPT-4, Claude). \\ Nno alabapin kan, sanwo pẹlu Crypto.", "narrow": "Taara", "new_first_wallet_text": "Ni rọọrun jẹ ki o jẹ ki o jẹ ki o jẹ ki a mu", "new_node_testing": "A ń dán apẹka títun wò", @@ -746,6 +746,7 @@ "transaction_sent_notice": "Tí aṣàfihàn kò bá tẹ̀síwájú l'áàárín ìṣẹ́jú kan, ẹ tọ́ olùṣèwádìí àkójọpọ̀ àti ímeèlì yín wò.", "transactions": "Àwọn àránṣẹ́", "transactions_by_date": "Àwọn àránṣẹ́ t'á ti fi aago ṣa", + "trongrid_history": "Itan Trongrid", "trusted": "A ti fọkàn ẹ̀ tán", "tx_commit_exception_no_dust_on_change": "Iṣowo naa ti kọ pẹlu iye yii. Pẹlu awọn owó wọnyi o le firanṣẹ ${min} laisi ayipada tabi ${max} ni iyipada iyipada.", "tx_commit_failed": "Idunadura iṣowo kuna. Jọwọ kan si atilẹyin.", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 089d5fa74..4c7a10883 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -366,10 +366,10 @@ "moonpay_alert_text": "金额的价值必须大于或等于 ${minAmount} ${fiatCurrency}", "more_options": "更多选项", "name": "姓名", - "nano_gpt_thanks_message": "感谢您使用Nanogpt!事务完成后,请记住回到浏览器!", - "nanogpt_subtitle": "所有最新型号(GPT-4,Claude)。\\ nno订阅,用加密货币付款。", "nano_current_rep": "当前代表", + "nano_gpt_thanks_message": "感谢您使用Nanogpt!事务完成后,请记住回到浏览器!", "nano_pick_new_rep": "选择新代表", + "nanogpt_subtitle": "所有最新型号(GPT-4,Claude)。\\ nno订阅,用加密货币付款。", "narrow": "狭窄的", "new_first_wallet_text": "轻松确保您的加密货币安全", "new_node_testing": "新节点测试", @@ -745,6 +745,7 @@ "transaction_sent_notice": "如果屏幕在 1 分钟后没有继续,请检查区块浏览器和您的电子邮件。", "transactions": "交易情况", "transactions_by_date": "按日期交易", + "trongrid_history": "Trongrid历史", "trusted": "值得信赖", "tx_commit_exception_no_dust_on_change": "交易被此金额拒绝。使用这些硬币,您可以发送${min}无需更改或返回${max}的变化。", "tx_commit_failed": "交易承诺失败。请联系支持。", diff --git a/scripts/android/app_env.sh b/scripts/android/app_env.sh index 52f32b297..77ee02b9c 100644 --- a/scripts/android/app_env.sh +++ b/scripts/android/app_env.sh @@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN) APP_ANDROID_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.12.3" -MONERO_COM_BUILD_NUMBER=84 +MONERO_COM_VERSION="1.13.0" +MONERO_COM_BUILD_NUMBER=85 MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_PACKAGE="com.monero.app" MONERO_COM_SCHEME="monero.com" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.15.6" -CAKEWALLET_BUILD_NUMBER=207 +CAKEWALLET_VERSION="4.16.0" +CAKEWALLET_BUILD_NUMBER=208 CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" CAKEWALLET_SCHEME="cakewallet" diff --git a/scripts/ios/app_env.sh b/scripts/ios/app_env.sh index 90f7d807c..e772ea128 100644 --- a/scripts/ios/app_env.sh +++ b/scripts/ios/app_env.sh @@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN) APP_IOS_TYPE=$1 MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.12.3" -MONERO_COM_BUILD_NUMBER=82 +MONERO_COM_VERSION="1.13.0" +MONERO_COM_BUILD_NUMBER=83 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="4.15.6" -CAKEWALLET_BUILD_NUMBER=232 +CAKEWALLET_VERSION="4.16.0" +CAKEWALLET_BUILD_NUMBER=234 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" HAVEN_NAME="Haven" diff --git a/scripts/macos/app_env.sh b/scripts/macos/app_env.sh index 758bfe900..95201dc02 100755 --- a/scripts/macos/app_env.sh +++ b/scripts/macos/app_env.sh @@ -16,13 +16,13 @@ if [ -n "$1" ]; then fi MONERO_COM_NAME="Monero.com" -MONERO_COM_VERSION="1.2.3" -MONERO_COM_BUILD_NUMBER=16 +MONERO_COM_VERSION="1.3.0" +MONERO_COM_BUILD_NUMBER=17 MONERO_COM_BUNDLE_ID="com.cakewallet.monero" CAKEWALLET_NAME="Cake Wallet" -CAKEWALLET_VERSION="1.8.6" -CAKEWALLET_BUILD_NUMBER=67 +CAKEWALLET_VERSION="1.9.0" +CAKEWALLET_BUILD_NUMBER=69 CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then diff --git a/tool/configure.dart b/tool/configure.dart index f2391103d..64f43d349 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -1112,6 +1112,8 @@ abstract class Tron { String? getTronNativeEstimatedFee(WalletBase wallet); String? getTronTRC20EstimatedFee(WalletBase wallet); + + void updateTronGridUsageState(WalletBase wallet, bool isEnabled); } """; From c35929f28e563e26b64184e4ea724dedd01544cc Mon Sep 17 00:00:00 2001 From: Omar Hatem Date: Wed, 8 May 2024 21:04:25 +0300 Subject: [PATCH 2/3] update flutter secure storage (#1437) * update flutter secure storage * fix flutter secure storage version --- pubspec_base.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pubspec_base.yaml b/pubspec_base.yaml index ddf0bd2e0..02e61e0b4 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -15,8 +15,8 @@ dependencies: git: url: https://github.com/cake-tech/flutter_secure_storage.git path: flutter_secure_storage - ref: cake-8.0.0 - version: 8.0.0 + ref: cake-9.0.0 + version: 9.0.0 # provider: ^6.0.3 rxdart: ^0.27.4 yaml: ^3.1.1 From bfb78eded98085b8f0a65f233b332490d8e4e5a7 Mon Sep 17 00:00:00 2001 From: Adegoke David <64401859+Blazebrain@users.noreply.github.com> Date: Wed, 8 May 2024 21:23:27 +0100 Subject: [PATCH 3/3] CW-599-Extract-Secure-Storage (#1353) * feat: Modify app to depend on secure storage abstraction instead of the direct package * chore: Revert command * Update configure.dart [skip ci] * Update configure.dart * Fix conflicts * clean up and fixes * minor fix --------- Co-authored-by: Omar Hatem --- .gitignore | 1 + lib/core/auth_service.dart | 14 +-- lib/core/backup_service.dart | 19 ++- lib/core/key_service.dart | 19 ++- lib/core/secure_storage.dart | 38 ------ lib/core/wallet_creation_service.dart | 4 +- lib/di.dart | 50 ++++++-- lib/entities/default_settings_migration.dart | 15 +-- lib/entities/fs_migration.dart | 66 ++++------ lib/entities/get_encryption_key.dart | 5 +- lib/entities/preferences_key.dart | 6 +- lib/entities/secret_store_key.dart | 8 +- lib/ionia/ionia_service.dart | 4 +- lib/main.dart | 9 +- .../support_chat/support_chat_page.dart | 4 +- .../support_chat/widgets/chatwoot_widget.dart | 5 +- lib/store/secret_store.dart | 5 +- lib/store/settings_store.dart | 49 ++++---- lib/store/yat/yat_store.dart | 4 +- lib/view_model/backup_view_model.dart | 5 +- .../edit_backup_password_view_model.dart | 5 +- pubspec_base.yaml | 6 - tool/configure.dart | 117 ++++++++++++++++++ 23 files changed, 259 insertions(+), 199 deletions(-) delete mode 100644 lib/core/secure_storage.dart diff --git a/.gitignore b/.gitignore index 24b7291f8..d0952ca98 100644 --- a/.gitignore +++ b/.gitignore @@ -156,6 +156,7 @@ assets/images/app_logo.png macos/Runner/Info.plist macos/Runner/DebugProfile.entitlements macos/Runner/Release.entitlements +lib/core/secure_storage.dart macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png diff --git a/lib/core/auth_service.dart b/lib/core/auth_service.dart index 66943bb7f..791701395 100644 --- a/lib/core/auth_service.dart +++ b/lib/core/auth_service.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:io'; import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/core/totp_request_details.dart'; @@ -7,7 +6,6 @@ import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/src/screens/auth/auth_page.dart'; import 'package:flutter/material.dart'; import 'package:mobx/mobx.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/entities/secret_store_key.dart'; @@ -35,14 +33,14 @@ class AuthService with Store { Routes.restoreOptions, ]; - final FlutterSecureStorage secureStorage; + final SecureStorage secureStorage; final SharedPreferences sharedPreferences; final SettingsStore settingsStore; Future setPassword(String password) async { final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); final encodedPassword = encodedPinCode(pin: password); - await writeSecureStorage(secureStorage, key: key, value: encodedPassword); + await secureStorage.write(key: key, value: encodedPassword); } Future canAuthenticate() async { @@ -61,7 +59,7 @@ class AuthService with Store { Future authenticate(String pin) async { final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); - final encodedPin = await readSecureStorage(secureStorage, key); + final encodedPin = await secureStorage.read(key: key); final decodedPin = decodedPinCode(pin: encodedPin!); return decodedPin == pin; @@ -69,11 +67,7 @@ class AuthService with Store { void saveLastAuthTime() { int timestamp = DateTime.now().millisecondsSinceEpoch; - writeSecureStorage( - secureStorage, - key: SecureKey.lastAuthTimeMilliseconds, - value: timestamp.toString(), - ); + secureStorage.write(key: SecureKey.lastAuthTimeMilliseconds, value: timestamp.toString()); } Future requireAuth() async { diff --git a/lib/core/backup_service.dart b/lib/core/backup_service.dart index d1092b024..d0d9a8a26 100644 --- a/lib/core/backup_service.dart +++ b/lib/core/backup_service.dart @@ -7,7 +7,6 @@ import 'package:cake_wallet/utils/device_info.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:flutter/foundation.dart'; import 'package:hive/hive.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:path_provider/path_provider.dart'; import 'package:cryptography/cryptography.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -25,7 +24,7 @@ import 'package:cake_backup/backup.dart' as cake_backup; class BackupService { BackupService( - this._flutterSecureStorage, this._walletInfoSource, this._keyService, this._sharedPreferences) + this._secureStorage, this._walletInfoSource, this._keyService, this._sharedPreferences) : _cipher = Cryptography.instance.chacha20Poly1305Aead(), _correctWallets = []; @@ -35,7 +34,7 @@ class BackupService { static const _v2 = 2; final Cipher _cipher; - final FlutterSecureStorage _flutterSecureStorage; + final SecureStorage _secureStorage; final SharedPreferences _sharedPreferences; final Box _walletInfoSource; final KeyService _keyService; @@ -374,15 +373,14 @@ class BackupService { final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword); final backupPassword = keychainJSON[backupPasswordKey] as String; - await writeSecureStorage(_flutterSecureStorage, key: backupPasswordKey, value: backupPassword); + await _secureStorage.write(key: backupPasswordKey, value: backupPassword); keychainWalletsInfo.forEach((dynamic rawInfo) async { final info = rawInfo as Map; await importWalletKeychainInfo(info); }); - await writeSecureStorage(_flutterSecureStorage, - key: pinCodeKey, value: encodedPinCode(pin: decodedPin)); + await _secureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin)); keychainDumpFile.deleteSync(); } @@ -401,15 +399,14 @@ class BackupService { final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword); final backupPassword = keychainJSON[backupPasswordKey] as String; - await writeSecureStorage(_flutterSecureStorage, key: backupPasswordKey, value: backupPassword); + await _secureStorage.write(key: backupPasswordKey, value: backupPassword); keychainWalletsInfo.forEach((dynamic rawInfo) async { final info = rawInfo as Map; await importWalletKeychainInfo(info); }); - await writeSecureStorage(_flutterSecureStorage, - key: pinCodeKey, value: encodedPinCode(pin: decodedPin)); + await _secureStorage.write(key: pinCodeKey, value: encodedPinCode(pin: decodedPin)); keychainDumpFile.deleteSync(); } @@ -429,7 +426,7 @@ class BackupService { Future _exportKeychainDumpV2(String password, {String keychainSalt = secrets.backupKeychainSalt}) async { final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); - final encodedPin = await _flutterSecureStorage.read(key: key); + final encodedPin = await _secureStorage.read(key: key); final decodedPin = decodedPinCode(pin: encodedPin!); final wallets = await Future.wait(_walletInfoSource.values.map((walletInfo) async { return { @@ -439,7 +436,7 @@ class BackupService { }; })); final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword); - final backupPassword = await _flutterSecureStorage.read(key: backupPasswordKey); + final backupPassword = await _secureStorage.read(key: backupPasswordKey); final data = utf8.encode( json.encode({'pin': decodedPin, 'wallets': wallets, backupPasswordKey: backupPassword})); final encrypted = await _encryptV2(Uint8List.fromList(data), '$keychainSalt$password'); diff --git a/lib/core/key_service.dart b/lib/core/key_service.dart index ba2da4de6..71fb5a4fc 100644 --- a/lib/core/key_service.dart +++ b/lib/core/key_service.dart @@ -1,31 +1,30 @@ import 'package:cake_wallet/core/secure_storage.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:cake_wallet/entities/secret_store_key.dart'; import 'package:cake_wallet/entities/encrypt.dart'; class KeyService { KeyService(this._secureStorage); - final FlutterSecureStorage _secureStorage; + final SecureStorage _secureStorage; Future getWalletPassword({required String walletName}) async { - final key = generateStoreKeyFor( - key: SecretStoreKey.moneroWalletPassword, walletName: walletName); - final encodedPassword = await readSecureStorage(_secureStorage, key); + final key = + generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName); + final encodedPassword = await _secureStorage.read(key: key); return decodeWalletPassword(password: encodedPassword!); } Future saveWalletPassword({required String walletName, required String password}) async { - final key = generateStoreKeyFor( - key: SecretStoreKey.moneroWalletPassword, walletName: walletName); + final key = + generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName); final encodedPassword = encodeWalletPassword(password: password); - await writeSecureStorage(_secureStorage, key: key, value: encodedPassword); + await _secureStorage.write(key: key, value: encodedPassword); } Future deleteWalletPassword({required String walletName}) async { - final key = generateStoreKeyFor( - key: SecretStoreKey.moneroWalletPassword, walletName: walletName); + final key = + generateStoreKeyFor(key: SecretStoreKey.moneroWalletPassword, walletName: walletName); await _secureStorage.delete(key: key); } diff --git a/lib/core/secure_storage.dart b/lib/core/secure_storage.dart deleted file mode 100644 index 5afb36d29..000000000 --- a/lib/core/secure_storage.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -// For now, we can create a utility function to handle this. -// -// However, we could look into abstracting the entire FlutterSecureStorage package -// so the app doesn't depend on the package directly but an absraction. -// It'll make these kind of modifications to read/write come from a single point. - -Future readSecureStorage(FlutterSecureStorage secureStorage, String key) async { - String? result; - const maxWait = Duration(seconds: 3); - const checkInterval = Duration(milliseconds: 200); - - DateTime start = DateTime.now(); - - while (result == null && DateTime.now().difference(start) < maxWait) { - result = await secureStorage.read(key: key); - - if (result != null) { - break; - } - - await Future.delayed(checkInterval); - } - - return result; -} - -Future writeSecureStorage(FlutterSecureStorage secureStorage, - {required String key, required String value}) async { - // delete the value before writing on macOS because of a weird bug - // https://github.com/mogol/flutter_secure_storage/issues/581 - if (Platform.isMacOS) { - await secureStorage.delete(key: key); - } - await secureStorage.write(key: key, value: value); -} diff --git a/lib/core/wallet_creation_service.dart b/lib/core/wallet_creation_service.dart index 646e47537..a55e9ee3f 100644 --- a/lib/core/wallet_creation_service.dart +++ b/lib/core/wallet_creation_service.dart @@ -1,8 +1,8 @@ +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/store/settings_store.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cake_wallet/entities/preferences_key.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:hive/hive.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:cake_wallet/core/key_service.dart'; @@ -25,7 +25,7 @@ class WalletCreationService { } WalletType type; - final FlutterSecureStorage secureStorage; + final SecureStorage secureStorage; final SharedPreferences sharedPreferences; final SettingsStore settingsStore; final KeyService keyService; diff --git a/lib/di.dart b/lib/di.dart index 20157b0e0..3ee57cb53 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -236,6 +236,32 @@ import 'package:get_it/get_it.dart'; import 'package:hive/hive.dart'; import 'package:mobx/mobx.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:cake_wallet/core/secure_storage.dart'; +import 'package:cake_wallet/core/wallet_creation_service.dart'; +import 'package:cake_wallet/store/app_store.dart'; +import 'package:cw_core/wallet_type.dart'; +import 'package:cake_wallet/view_model/wallet_new_vm.dart'; +import 'package:cake_wallet/store/authentication_store.dart'; +import 'package:cake_wallet/store/dashboard/trades_store.dart'; +import 'package:cake_wallet/store/dashboard/trade_filter_store.dart'; +import 'package:cake_wallet/store/dashboard/transaction_filter_store.dart'; +import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart'; +import 'package:cake_wallet/store/templates/send_template_store.dart'; +import 'package:cake_wallet/store/templates/exchange_template_store.dart'; +import 'package:cake_wallet/entities/template.dart'; +import 'package:cake_wallet/exchange/exchange_template.dart'; +import 'package:cake_wallet/.secrets.g.dart' as secrets; +import 'package:cake_wallet/src/screens/dashboard/pages/address_page.dart'; +import 'package:cake_wallet/anypay/anypay_api.dart'; +import 'package:cake_wallet/view_model/ionia/ionia_gift_card_details_view_model.dart'; +import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.dart'; +import 'package:cake_wallet/view_model/ionia/ionia_payment_status_view_model.dart'; +import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart'; +import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart'; +import 'package:cake_wallet/src/screens/receive/fullscreen_qr_page.dart'; +import 'package:cake_wallet/core/wallet_loading_service.dart'; +import 'package:cw_core/crypto_currency.dart'; +import 'package:cake_wallet/entities/qr_view_data.dart'; import 'buy/dfx/dfx_buy_provider.dart'; import 'core/totp_request_details.dart'; @@ -268,7 +294,7 @@ Future setup({ required Box ordersSource, required Box unspentCoinsInfoSource, required Box anonpayInvoiceInfoSource, - required FlutterSecureStorage secureStorage, + required SecureStorage secureStorage, required GlobalKey navigatorKey, }) async { _walletInfoSource = walletInfoSource; @@ -285,7 +311,7 @@ Future setup({ if (!_isSetupFinished) { getIt.registerSingletonAsync(() => SharedPreferences.getInstance()); - getIt.registerSingleton(secureStorage); + getIt.registerSingleton(secureStorage); } if (!_isSetupFinished) { getIt.registerFactory(() => BackgroundTasks()); @@ -333,22 +359,22 @@ Future setup({ getIt.registerSingleton( ExchangeTemplateStore(templateSource: _exchangeTemplates)); getIt.registerSingleton( - YatStore(appStore: getIt.get(), secureStorage: getIt.get()) + YatStore(appStore: getIt.get(), secureStorage: getIt.get()) ..init()); getIt.registerSingleton( AnonpayTransactionsStore(anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource)); - 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( initialType: type, keyService: getIt.get(), - secureStorage: getIt.get(), + secureStorage: getIt.get(), sharedPreferences: getIt.get(), settingsStore: getIt.get(), walletInfoSource: _walletInfoSource)); @@ -403,7 +429,7 @@ Future setup({ getIt.registerFactory( () => AuthService( - secureStorage: getIt.get(), + secureStorage: getIt.get(), sharedPreferences: getIt.get(), settingsStore: getIt.get(), ), @@ -980,16 +1006,16 @@ Future setup({ trades: _tradesSource, settingsStore: getIt.get())); - getIt.registerFactory(() => BackupService(getIt.get(), _walletInfoSource, + getIt.registerFactory(() => BackupService(getIt.get(), _walletInfoSource, getIt.get(), getIt.get())); getIt.registerFactory(() => BackupViewModel( - getIt.get(), getIt.get(), getIt.get())); + getIt.get(), getIt.get(), getIt.get())); getIt.registerFactory(() => BackupPage(getIt.get())); getIt.registerFactory(() => - EditBackupPasswordViewModel(getIt.get(), getIt.get())); + EditBackupPasswordViewModel(getIt.get(), getIt.get())); getIt.registerFactory(() => EditBackupPasswordPage(getIt.get())); @@ -1038,7 +1064,7 @@ Future setup({ getIt.registerFactory(() => SupportPage(getIt.get())); getIt.registerFactory(() => SupportChatPage(getIt.get(), - secureStorage: getIt.get())); + secureStorage: getIt.get())); getIt.registerFactory(() => SupportOtherLinksPage(getIt.get())); @@ -1080,7 +1106,7 @@ Future setup({ getIt.registerFactory(() => AnyPayApi()); getIt.registerFactory( - () => IoniaService(getIt.get(), getIt.get())); + () => IoniaService(getIt.get(), getIt.get())); getIt.registerFactory(() => IoniaAnyPay( getIt.get(), getIt.get(), getIt.get().wallet!)); diff --git a/lib/entities/default_settings_migration.dart b/lib/entities/default_settings_migration.dart index 77db474a9..e67bd2fc6 100644 --- a/lib/entities/default_settings_migration.dart +++ b/lib/entities/default_settings_migration.dart @@ -1,10 +1,10 @@ import 'dart:io' show Directory, File, Platform; import 'package:cake_wallet/bitcoin/bitcoin.dart'; +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/entities/exchange_api_mode.dart'; import 'package:cake_wallet/entities/fiat_api_mode.dart'; import 'package:cw_core/pathForWallet.dart'; import 'package:cake_wallet/entities/secret_store_key.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:hive/hive.dart'; import 'package:path_provider/path_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -42,7 +42,7 @@ const newCakeWalletBitcoinUri = 'btc-electrum.cakewallet.com:50002'; Future defaultSettingsMigration( {required int version, required SharedPreferences sharedPreferences, - required FlutterSecureStorage secureStorage, + required SecureStorage secureStorage, required Box nodes, required Box powNodes, required Box walletInfoSource, @@ -485,7 +485,7 @@ Node? getTronDefaultNode({required Box nodes}) { Future insecureStorageMigration({ required SharedPreferences sharedPreferences, - required FlutterSecureStorage secureStorage, + required SecureStorage secureStorage, }) async { bool? allowBiometricalAuthentication = sharedPreferences.getBool(SecureKey.allowBiometricalAuthenticationKey); @@ -559,7 +559,7 @@ Future insecureStorageMigration({ } } -Future rewriteSecureStoragePin({required FlutterSecureStorage secureStorage}) async { +Future rewriteSecureStoragePin({required SecureStorage secureStorage}) async { // the bug only affects ios/mac: if (!Platform.isIOS && !Platform.isMacOS) { return; @@ -585,8 +585,9 @@ Future rewriteSecureStoragePin({required FlutterSecureStorage secureStorag await secureStorage.write( key: keyForPinCode, value: encodedPin, - iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock), - mOptions: MacOsOptions(accessibility: KeychainAccessibility.first_unlock), + // TODO: find a way to add those with the generated secure storage + // iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock), + // mOptions: MacOsOptions(accessibility: KeychainAccessibility.first_unlock), ); } @@ -720,7 +721,7 @@ Future updateDisplayModes(SharedPreferences sharedPreferences) async { await sharedPreferences.setInt(PreferencesKey.currentBalanceDisplayModeKey, balanceDisplayMode); } -Future generateBackupPassword(FlutterSecureStorage secureStorage) async { +Future generateBackupPassword(SecureStorage secureStorage) async { final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword); if ((await secureStorage.read(key: key))?.isNotEmpty ?? false) { diff --git a/lib/entities/fs_migration.dart b/lib/entities/fs_migration.dart index 869ed66ff..14237f080 100644 --- a/lib/entities/fs_migration.dart +++ b/lib/entities/fs_migration.dart @@ -2,7 +2,6 @@ import 'dart:io'; import 'dart:convert'; import 'package:cake_wallet/core/secure_storage.dart'; import 'package:collection/collection.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:hive/hive.dart'; import 'package:path_provider/path_provider.dart'; @@ -11,8 +10,7 @@ import 'package:cake_wallet/entities/contact.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cake_wallet/entities/encrypt.dart'; import 'package:cake_wallet/entities/fiat_currency.dart'; -import 'package:cake_wallet/entities/ios_legacy_helper.dart' - as ios_legacy_helper; +import 'package:cake_wallet/entities/ios_legacy_helper.dart' as ios_legacy_helper; import 'package:cake_wallet/entities/preferences_key.dart'; import 'package:cake_wallet/entities/secret_store_key.dart'; import 'package:cw_core/wallet_info.dart'; @@ -30,8 +28,8 @@ Future migrate_android_v1() async { await android_migrate_wallets(appDocDir: appDocDir); } -Future ios_migrate_v1(Box walletInfoSource, - Box tradeSource, Box contactSource) async { +Future ios_migrate_v1( + Box walletInfoSource, Box tradeSource, Box contactSource) async { final prefs = await SharedPreferences.getInstance(); if (prefs.getBool('ios_migration_v1_completed') ?? false) { @@ -67,10 +65,7 @@ Future ios_migrate_user_defaults() async { if (activeCurrency != null) { final convertedCurrency = convertFiatLegacy(activeCurrency); - if (convertedCurrency != null) { - await prefs.setString( - 'current_fiat_currency', convertedCurrency.serialize()); - } + await prefs.setString('current_fiat_currency', convertedCurrency.serialize()); } //translate fee priority @@ -81,24 +76,21 @@ Future ios_migrate_user_defaults() async { } //translate current balance mode - final currentBalanceMode = - await ios_legacy_helper.getInt('display_balance_mode'); + final currentBalanceMode = await ios_legacy_helper.getInt('display_balance_mode'); if (currentBalanceMode != null) { await prefs.setInt('current_balance_display_mode', currentBalanceMode); } //translate should save recipient address - final shouldSave = - await ios_legacy_helper.getBool('should_save_recipient_address'); - + final shouldSave = await ios_legacy_helper.getBool('should_save_recipient_address'); + if (shouldSave != null) { await prefs.setBool('save_recipient_address', shouldSave); } //translate biometric - final biometricOn = - await ios_legacy_helper.getBool('biometric_authentication_on'); - + final biometricOn = await ios_legacy_helper.getBool('biometric_authentication_on'); + if (biometricOn != null) { await prefs.setBool('allow_biometrical_authentication', biometricOn); } @@ -137,9 +129,8 @@ Future ios_migrate_pin() async { return; } - final flutterSecureStorage = FlutterSecureStorage(); - final pinPassword = await flutterSecureStorage.read( - key: 'pin_password', iOptions: IOSOptions()); + final flutterSecureStorage = secureStorageShared; + final pinPassword = await flutterSecureStorage.readNoIOptions(key: 'pin_password'); // No pin if (pinPassword == null) { await prefs.setBool('ios_migration_pin_completed', true); @@ -148,7 +139,7 @@ Future ios_migrate_pin() async { final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); final encodedPassword = encodedPinCode(pin: pinPassword); - await writeSecureStorage(flutterSecureStorage, key: key, value: encodedPassword); + await flutterSecureStorage.write(key: key, value: encodedPassword); await prefs.setBool('ios_migration_pin_completed', true); } @@ -161,7 +152,7 @@ Future ios_migrate_wallet_passwords() async { } final appDocDir = await getApplicationDocumentsDirectory(); - final flutterSecureStorage = FlutterSecureStorage(); + final flutterSecureStorage = secureStorageShared; final keyService = KeyService(flutterSecureStorage); final walletsDir = Directory('${appDocDir.path}/wallets'); final moneroWalletsDir = Directory('${walletsDir.path}/monero'); @@ -176,10 +167,8 @@ Future ios_migrate_wallet_passwords() async { if (item is Directory) { final name = item.path.split('/').last; final oldKey = 'wallet_monero_' + name + '_password'; - final password = await flutterSecureStorage.read( - key: oldKey, iOptions: IOSOptions()); - await keyService.saveWalletPassword( - walletName: name, password: password!); + final password = await flutterSecureStorage.readNoIOptions(key: oldKey); + await keyService.saveWalletPassword(walletName: name, password: password!); } } catch (e) { print(e.toString()); @@ -311,18 +300,14 @@ Future ios_migrate_wallet_info(Box walletsInfoSource) async { return null; } - final config = json.decode(configFile.readAsStringSync()) - as Map; - final isRecovery = config['isRecovery'] as bool ?? false; + final config = json.decode(configFile.readAsStringSync()) as Map; + final isRecovery = config['isRecovery'] as bool? ?? false; final dateAsDouble = config['date'] as double; final timestamp = dateAsDouble.toInt() * 1000; final date = DateTime.fromMillisecondsSinceEpoch(timestamp); - final id = walletTypeToString(WalletType.monero).toLowerCase() + - '_' + - name; - final exist = walletsInfoSource.values - .firstWhereOrNull((el) => el.id == id) != null; - + final id = walletTypeToString(WalletType.monero).toLowerCase() + '_' + name; + final exist = walletsInfoSource.values.firstWhereOrNull((el) => el.id == id) != null; + if (exist) { return null; } @@ -373,12 +358,10 @@ Future ios_migrate_trades_list(Box tradeSource) async { } final content = file.readAsBytesSync(); - final flutterSecureStorage = FlutterSecureStorage(); - final masterPassword = await flutterSecureStorage.read( - key: 'master_password', iOptions: IOSOptions()); + final flutterSecureStorage = secureStorageShared; + final masterPassword = await flutterSecureStorage.readNoIOptions(key: 'master_password'); final key = masterPassword!.replaceAll('-', ''); - final decoded = - await ios_legacy_helper.decrypt(content, key: key, salt: secrets.salt); + final decoded = await ios_legacy_helper.decrypt(content, key: key, salt: secrets.salt); final decodedJson = json.decode(decoded) as List; final trades = decodedJson.map((dynamic el) { final elAsMap = el as Map; @@ -441,8 +424,7 @@ Future ios_migrate_address_book(Box contactSource) async { final address = _item["address"] as String; final name = _item["name"] as String; - return Contact( - address: address, name: name, type: CryptoCurrency.fromString(type)); + return Contact(address: address, name: name, type: CryptoCurrency.fromString(type)); }); await contactSource.addAll(contacts); diff --git a/lib/entities/get_encryption_key.dart b/lib/entities/get_encryption_key.dart index 04c3a65f7..618066cb8 100644 --- a/lib/entities/get_encryption_key.dart +++ b/lib/entities/get_encryption_key.dart @@ -1,9 +1,8 @@ import 'package:cake_wallet/core/secure_storage.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:cw_core/cake_hive.dart'; Future> getEncryptionKey( - {required String forKey, required FlutterSecureStorage secureStorage}) async { + {required String forKey, required SecureStorage secureStorage}) async { final stringifiedKey = await secureStorage.read(key: 'transactionDescriptionsBoxKey'); List key; @@ -11,7 +10,7 @@ Future> getEncryptionKey( key = CakeHive.generateSecureKey(); final keyStringified = key.join(','); String storageKey = 'transactionDescriptionsBoxKey'; - await writeSecureStorage(secureStorage, key: storageKey, value: keyStringified); + await secureStorage.write(key: storageKey, value: keyStringified); } else { key = stringifiedKey.split(',').map((i) => int.parse(i)).toList(); } diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart index cf9ae3019..79177178c 100644 --- a/lib/entities/preferences_key.dart +++ b/lib/entities/preferences_key.dart @@ -61,9 +61,9 @@ class PreferencesKey { static const defaultBananoRep = 'default_banano_representative'; static const lookupsTwitter = 'looks_up_twitter'; static const lookupsMastodon = 'looks_up_mastodon'; - static const lookupsYatService = 'looks_up_mastodon'; - static const lookupsUnstoppableDomains = 'looks_up_mastodon'; - static const lookupsOpenAlias = 'looks_up_mastodon'; + static const lookupsYatService = 'looks_up_yat'; + static const lookupsUnstoppableDomains = 'looks_up_unstoppable_domain'; + static const lookupsOpenAlias = 'looks_up_open_alias'; static const lookupsENS = 'looks_up_ens'; static String moneroWalletUpdateV1Key(String name) => diff --git a/lib/entities/secret_store_key.dart b/lib/entities/secret_store_key.dart index 2ee490c74..df6347cca 100644 --- a/lib/entities/secret_store_key.dart +++ b/lib/entities/secret_store_key.dart @@ -1,4 +1,4 @@ -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:shared_preferences/shared_preferences.dart'; enum SecretStoreKey { moneroWalletPassword, pinCodePassword, backupPassword } @@ -66,7 +66,7 @@ class SecureKey { static const lastAuthTimeMilliseconds = 'last_auth_time_milliseconds'; static Future getInt({ - required FlutterSecureStorage secureStorage, + required SecureStorage secureStorage, required SharedPreferences sharedPreferences, required String key, }) async { @@ -76,7 +76,7 @@ class SecureKey { } static Future getBool({ - required FlutterSecureStorage secureStorage, + required SecureStorage secureStorage, required SharedPreferences sharedPreferences, required String key, }) async { @@ -91,7 +91,7 @@ class SecureKey { } static Future getString({ - required FlutterSecureStorage secureStorage, + required SecureStorage secureStorage, required SharedPreferences sharedPreferences, required String key, }) async { diff --git a/lib/ionia/ionia_service.dart b/lib/ionia/ionia_service.dart index 0396ed7c1..821824a87 100644 --- a/lib/ionia/ionia_service.dart +++ b/lib/ionia/ionia_service.dart @@ -1,7 +1,7 @@ +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/ionia/ionia_merchant.dart'; import 'package:cake_wallet/ionia/ionia_order.dart'; import 'package:cake_wallet/ionia/ionia_virtual_card.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/ionia/ionia_api.dart'; import 'package:cake_wallet/ionia/ionia_gift_card.dart'; @@ -16,7 +16,7 @@ class IoniaService { static String get clientId => secrets.ioniaClientId; - final FlutterSecureStorage secureStorage; + final SecureStorage secureStorage; final IoniaApi ioniaApi; // Create user diff --git a/lib/main.dart b/lib/main.dart index 2a4e12236..fa71da31d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart'; import 'package:cake_wallet/core/auth_service.dart'; +import 'package:cake_wallet/core/secure_storage.dart'; import 'package:cake_wallet/entities/language_service.dart'; import 'package:cake_wallet/buy/order.dart'; import 'package:cake_wallet/locales/locale.dart'; @@ -18,7 +19,6 @@ import 'package:hive/hive.dart'; import 'package:cake_wallet/di.dart'; import 'package:path_provider/path_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:cake_wallet/themes/theme_base.dart'; import 'package:cake_wallet/router.dart' as Router; @@ -138,9 +138,8 @@ Future initializeAppConfigs() async { CakeHive.registerAdapter(AnonpayInvoiceInfoAdapter()); } - final secureStorage = FlutterSecureStorage( - iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock), - ); + final secureStorage = secureStorageShared; + final transactionDescriptionsBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: TransactionDescription.boxKey); final tradesBoxKey = await getEncryptionKey(secureStorage: secureStorage, forKey: Trade.boxKey); @@ -191,7 +190,7 @@ Future initialSetup( required Box