From 3b83b85c6ce822d68a8787142773c5cab30e0e44 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Tue, 26 Nov 2024 18:47:07 +0100 Subject: [PATCH 01/13] Fix sending for monero ledger --- cw_monero/lib/api/transaction_history.dart | 11 +++- cw_monero/lib/ledger.dart | 59 ++++++++++++++++++++-- lib/src/screens/send/send_page.dart | 5 +- 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart index 662eb1bb55..51b2128a07 100644 --- a/cw_monero/lib/api/transaction_history.dart +++ b/cw_monero/lib/api/transaction_history.dart @@ -195,9 +195,16 @@ String? commitTransactionFromPointerAddress({required int address, required bool commitTransaction(transactionPointer: monero.PendingTransaction.fromAddress(address), useUR: useUR); String? commitTransaction({required monero.PendingTransaction transactionPointer, required bool useUR}) { + final transactionPointerAddress = transactionPointer.address; final txCommit = useUR - ? monero.PendingTransaction_commitUR(transactionPointer, 120) - : monero.PendingTransaction_commit(transactionPointer, filename: '', overwrite: false); + ? monero.PendingTransaction_commitUR(transactionPointer, 120) + : Isolate.run(() { + monero.PendingTransaction_commit( + Pointer.fromAddress(transactionPointerAddress), + filename: '', + overwrite: false, + ); + }); String? error = (() { final status = monero.PendingTransaction_status(transactionPointer.cast()); diff --git a/cw_monero/lib/ledger.dart b/cw_monero/lib/ledger.dart index c947d09449..2dbd7b029b 100644 --- a/cw_monero/lib/ledger.dart +++ b/cw_monero/lib/ledger.dart @@ -6,7 +6,6 @@ import 'package:ffi/ffi.dart'; import 'package:ledger_flutter_plus/ledger_flutter_plus.dart'; import 'package:ledger_flutter_plus/ledger_flutter_plus_dart.dart'; import 'package:monero/monero.dart' as monero; -// import 'package:polyseed/polyseed.dart'; LedgerConnection? gLedger; @@ -28,9 +27,9 @@ void enableLedgerExchange(monero.wallet ptr, LedgerConnection connection) { ptr, emptyPointer.cast(), 0); malloc.free(emptyPointer); - // print("> ${ledgerRequest.toHexString()}"); + _logLedgerCommand(ledgerRequest, false); final response = await exchange(connection, ledgerRequest); - // print("< ${response.toHexString()}"); + _logLedgerCommand(response, true); final Pointer result = malloc(response.length); for (var i = 0; i < response.length; i++) { @@ -82,3 +81,57 @@ class ExchangeOperation extends LedgerRawOperation { @override Future> write(ByteDataWriter writer) async => [inputData]; } + +void _logLedgerCommand(Uint8List command, [bool isResponse = true]) { + String toHexString(Uint8List data) => + data.map((e) => e.toRadixString(16).padLeft(2, '0')).join(); + + const ledgerMoneroCommands = { + 0x00: "INS_NONE", + 0x02: "NS_RESET", + 0x20: "INS_GET_KEY", + 0x21: "INS_DISPLAY_ADDRESS", + 0x22: "INS_PUT_KEY", + 0x24: "INS_GET_CHACHA8_PREKEY", + 0x26: "INS_VERIFY_KEY", + 0x28: "INS_MANAGE_SEEDWORDS", + 0x30: "INS_SECRET_KEY_TO_PUBLIC_KEY", + 0x32: "INS_GEN_KEY_DERIVATION", + 0x34: "INS_DERIVATION_TO_SCALAR", + 0x36: "INS_DERIVE_PUBLIC_KEY", + 0x38: "INS_DERIVE_SECRET_KEY", + 0x3A: "INS_GEN_KEY_IMAGE", + 0x3B: "INS_DERIVE_VIEW_TAG", + 0x3C: "INS_SECRET_KEY_ADD", + 0x3E: "INS_SECRET_KEY_SUB", + 0x40: "INS_GENERATE_KEYPAIR", + 0x42: "INS_SECRET_SCAL_MUL_KEY", + 0x44: "INS_SECRET_SCAL_MUL_BASE", + 0x46: "INS_DERIVE_SUBADDRESS_PUBLIC_KEY", + 0x48: "INS_GET_SUBADDRESS", + 0x4A: "INS_GET_SUBADDRESS_SPEND_PUBLIC_KEY", + 0x4C: "INS_GET_SUBADDRESS_SECRET_KEY", + 0x70: "INS_OPEN_TX", + 0x72: "INS_SET_SIGNATURE_MODE", + 0x74: "INS_GET_ADDITIONAL_KEY", + 0x76: "INS_STEALTH", + 0x77: "INS_GEN_COMMITMENT_MASK", + 0x78: "INS_BLIND", + 0x7A: "INS_UNBLIND", + 0x7B: "INS_GEN_TXOUT_KEYS", + 0x7D: "INS_PREFIX_HASH", + 0x7C: "INS_VALIDATE", + 0x7E: "INS_MLSAG", + 0x7F: "INS_CLSAG", + 0x80: "INS_CLOSE_TX", + 0xA0: "INS_GET_TX_PROOF", + 0xC0: "INS_GET_RESPONSE" + }; + + if (isResponse) { + print("< ${toHexString(command)}"); + } else { + print( + "> ${ledgerMoneroCommands[command[1]]} ${toHexString(command.sublist(2))}"); + } +} diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 7003ceafbb..6045ba0f67 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -611,7 +611,10 @@ class SendPage extends BasePage { alertTitle: S.of(context).proceed_on_device, alertContent: S.of(context).proceed_on_device_description, buttonText: S.of(context).cancel, - buttonAction: () => Navigator.of(context).pop()); + buttonAction: () { + sendViewModel.state = InitialExecutionState(); + Navigator.of(context).pop(); + }); }); }); } From 78f1d654b7d389475e89fd85086e9d6d7ee367a5 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Wed, 27 Nov 2024 17:34:52 +0100 Subject: [PATCH 02/13] Ignore no tx keys found error --- cw_monero/lib/api/transaction_history.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart index 51b2128a07..48ce8838ad 100644 --- a/cw_monero/lib/api/transaction_history.dart +++ b/cw_monero/lib/api/transaction_history.dart @@ -223,7 +223,7 @@ String? commitTransaction({required monero.PendingTransaction transactionPointer })(); } - if (error != null) { + if (error != null && error != "no tx keys found for this txid") { throw CreationTransactionException(message: error); } if (useUR) { From 57e65a02c4b41bb0deae7ce44c4328d646d37028 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Thu, 28 Nov 2024 05:31:19 +0200 Subject: [PATCH 03/13] re-add Monero to Ledger enabled wallets --- cw_core/lib/hardware/device_connection_type.dart | 2 +- lib/src/screens/restore/restore_options_page.dart | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/cw_core/lib/hardware/device_connection_type.dart b/cw_core/lib/hardware/device_connection_type.dart index 466d58e2a9..76a501af13 100644 --- a/cw_core/lib/hardware/device_connection_type.dart +++ b/cw_core/lib/hardware/device_connection_type.dart @@ -7,7 +7,7 @@ enum DeviceConnectionType { static List supportedConnectionTypes(WalletType walletType, [bool isIOS = false]) { switch (walletType) { - // case WalletType.monero: + case WalletType.monero: case WalletType.bitcoin: case WalletType.litecoin: case WalletType.ethereum: diff --git a/lib/src/screens/restore/restore_options_page.dart b/lib/src/screens/restore/restore_options_page.dart index d1d419d609..299846a72d 100644 --- a/lib/src/screens/restore/restore_options_page.dart +++ b/lib/src/screens/restore/restore_options_page.dart @@ -56,9 +56,8 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> { } if (isMoneroOnly) { - // return DeviceConnectionType.supportedConnectionTypes(WalletType.monero, Platform.isIOS) - // .isNotEmpty; - return false; + return DeviceConnectionType.supportedConnectionTypes(WalletType.monero, Platform.isIOS) + .isNotEmpty; } return true; From 81d8d36c144f7c978e0b23930f6128b262d5fb43 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Mon, 2 Dec 2024 12:48:40 +0100 Subject: [PATCH 04/13] Fix No Element Exception on requireHardwareWalletConnection check --- cw_monero/lib/monero_wallet_service.dart | 60 ++++++++++++------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart index 6f49640be7..fc1923c957 100644 --- a/cw_monero/lib/monero_wallet_service.dart +++ b/cw_monero/lib/monero_wallet_service.dart @@ -1,5 +1,7 @@ import 'dart:ffi'; import 'dart:io'; + +import 'package:cw_core/get_height_by_date.dart'; import 'package:cw_core/monero_wallet_utils.dart'; import 'package:cw_core/pathForWallet.dart'; import 'package:cw_core/unspent_coins_info.dart'; @@ -8,7 +10,6 @@ import 'package:cw_core/wallet_credentials.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_service.dart'; import 'package:cw_core/wallet_type.dart'; -import 'package:cw_core/get_height_by_date.dart'; import 'package:cw_monero/api/account_list.dart'; import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager; import 'package:cw_monero/api/wallet_manager.dart'; @@ -16,8 +17,8 @@ import 'package:cw_monero/ledger.dart'; import 'package:cw_monero/monero_wallet.dart'; import 'package:hive/hive.dart'; import 'package:ledger_flutter_plus/ledger_flutter_plus.dart'; -import 'package:polyseed/polyseed.dart'; import 'package:monero/monero.dart' as monero; +import 'package:polyseed/polyseed.dart'; class MoneroNewWalletCredentials extends WalletCredentials { MoneroNewWalletCredentials( @@ -132,14 +133,12 @@ class MoneroWalletService extends WalletService< try { final path = await pathForWallet(name: name, type: getType()); - if (walletFilesExist(path)) { - await repairOldAndroidWallet(name); - } + if (walletFilesExist(path)) await repairOldAndroidWallet(name); await monero_wallet_manager .openWalletAsync({'path': path, 'password': password}); - final walletInfo = walletInfoSource.values.firstWhere( - (info) => info.id == WalletBase.idFor(name, getType())); + final walletInfo = walletInfoSource.values + .firstWhere((info) => info.id == WalletBase.idFor(name, getType())); final wallet = MoneroWallet( walletInfo: walletInfo, unspentCoinsInfo: unspentCoinsInfoSource, @@ -203,7 +202,7 @@ class MoneroWalletService extends WalletService< @override Future rename(String currentName, String password, String newName) async { final currentWalletInfo = walletInfoSource.values.firstWhere( - (info) => info.id == WalletBase.idFor(currentName, getType())); + (info) => info.id == WalletBase.idFor(currentName, getType())); final currentWallet = MoneroWallet( walletInfo: currentWalletInfo, unspentCoinsInfo: unspentCoinsInfoSource, @@ -254,14 +253,14 @@ class MoneroWalletService extends WalletService< final password = credentials.password; final height = credentials.height; - if (wptr == null ) monero_wallet_manager.createWalletPointer(); + if (wptr == null) monero_wallet_manager.createWalletPointer(); enableLedgerExchange(wptr!, credentials.ledgerConnection); await monero_wallet_manager.restoreWalletFromHardwareWallet( - path: path, - password: password!, - restoreHeight: height!, - deviceName: 'Ledger'); + path: path, + password: password!, + restoreHeight: height!, + deviceName: 'Ledger'); final wallet = MoneroWallet( walletInfo: credentials.walletInfo!, @@ -278,7 +277,8 @@ class MoneroWalletService extends WalletService< } @override - Future restoreFromSeed(MoneroRestoreWalletFromSeedCredentials credentials, + Future restoreFromSeed( + MoneroRestoreWalletFromSeedCredentials credentials, {bool? isTestnet}) async { // Restore from Polyseed if (Polyseed.isValidSeed(credentials.mnemonic)) { @@ -312,7 +312,8 @@ class MoneroWalletService extends WalletService< final path = await pathForWallet(name: credentials.name, type: getType()); final polyseedCoin = PolyseedCoin.POLYSEED_MONERO; final lang = PolyseedLang.getByPhrase(credentials.mnemonic); - final polyseed = Polyseed.decode(credentials.mnemonic, lang, polyseedCoin); + final polyseed = + Polyseed.decode(credentials.mnemonic, lang, polyseedCoin); return _restoreFromPolyseed( path, credentials.password!, polyseed, credentials.walletInfo!, lang); @@ -354,24 +355,18 @@ class MoneroWalletService extends WalletService< Future repairOldAndroidWallet(String name) async { try { - if (!Platform.isAndroid) { - return; - } + if (!Platform.isAndroid) return; final oldAndroidWalletDirPath = await outdatedAndroidPathForWalletDir(name: name); final dir = Directory(oldAndroidWalletDirPath); - if (!dir.existsSync()) { - return; - } + if (!dir.existsSync()) return; final newWalletDirPath = await pathForWalletDir(name: name, type: getType()); dir.listSync().forEach((f) { final file = File(f.path); - final name = f.path - .split('/') - .last; + final name = f.path.split('/').last; final newPath = newWalletDirPath + '/$name'; final newFile = File(newPath); @@ -390,9 +385,7 @@ class MoneroWalletService extends WalletService< try { final path = await pathForWallet(name: name, type: getType()); - if (walletFilesExist(path)) { - await repairOldAndroidWallet(name); - } + if (walletFilesExist(path)) await repairOldAndroidWallet(name); await monero_wallet_manager.openWalletAsync({'path': path, 'password': password}); final walletInfo = walletInfoSource.values @@ -411,8 +404,15 @@ class MoneroWalletService extends WalletService< @override bool requireHardwareWalletConnection(String name) { - final walletInfo = walletInfoSource.values - .firstWhere((info) => info.id == WalletBase.idFor(name, getType())); - return walletInfo.isHardwareWallet; + bool checkWalletInfo(WalletInfo info) => + info.id == WalletBase.idFor(name, getType()); + + if (walletInfoSource.values.any(checkWalletInfo)) { + return walletInfoSource.values + .firstWhere(checkWalletInfo) + .isHardwareWallet; + } + + return false; } } From 8cc43000a75d6df8309e1a7e5cd292450e3633f7 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Tue, 3 Dec 2024 12:24:01 +0100 Subject: [PATCH 05/13] Fix Showing connection screen again --- .../on_authentication_state_change.dart | 26 +++++++++++-------- lib/store/authentication_store.dart | 8 +++++- lib/view_model/wallet_creation_vm.dart | 3 +-- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart index 88b03ca59c..be9b30fc51 100644 --- a/lib/reactions/on_authentication_state_change.dart +++ b/lib/reactions/on_authentication_state_change.dart @@ -44,13 +44,17 @@ void startAuthenticationStateChange( } catch (error, stack) { loginError = error; await ExceptionHandler.resetLastPopupDate(); - await ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack)); + await ExceptionHandler.onError( + FlutterErrorDetails(exception: error, stack: stack)); } return; } - if (state == AuthenticationState.allowed) { - if (requireHardwareWalletConnection()) { + if ([AuthenticationState.allowed, AuthenticationState.allowedCreate] + .contains(state)) { + if (requireHardwareWalletConnection() && + state == AuthenticationState.allowed) { + print("onAuthTriggerd"); await navigatorKey.currentState!.pushNamedAndRemoveUntil( Routes.connectDevices, (route) => false, @@ -58,14 +62,14 @@ void startAuthenticationStateChange( walletType: WalletType.monero, onConnectDevice: (context, ledgerVM) async { monero!.setGlobalLedgerConnection(ledgerVM.connection); - showPopUp( - context: context, - builder: (BuildContext context) => AlertWithOneAction( - alertTitle: S.of(context).proceed_on_device, - alertContent: S.of(context).proceed_on_device_description, - buttonText: S.of(context).cancel, - buttonAction: () => Navigator.of(context).pop()), - ); + showPopUp( + context: context, + builder: (BuildContext context) => AlertWithOneAction( + alertTitle: S.of(context).proceed_on_device, + alertContent: S.of(context).proceed_on_device_description, + buttonText: S.of(context).cancel, + buttonAction: () => Navigator.of(context).pop()), + ); await loadCurrentWallet(); getIt.get().resetCurrentSheet(); await navigatorKey.currentState! diff --git a/lib/store/authentication_store.dart b/lib/store/authentication_store.dart index 815b1ed602..db4c4861ec 100644 --- a/lib/store/authentication_store.dart +++ b/lib/store/authentication_store.dart @@ -4,7 +4,7 @@ part 'authentication_store.g.dart'; class AuthenticationStore = AuthenticationStoreBase with _$AuthenticationStore; -enum AuthenticationState { uninitialized, installed, allowed, _reset } +enum AuthenticationState { uninitialized, installed, allowed, allowedCreate, _reset } abstract class AuthenticationStoreBase with Store { AuthenticationStoreBase() : state = AuthenticationState.uninitialized; @@ -23,4 +23,10 @@ abstract class AuthenticationStoreBase with Store { state = AuthenticationState._reset; state = AuthenticationState.allowed; } + + @action + void allowedCreate() { + state = AuthenticationState._reset; + state = AuthenticationState.allowedCreate; + } } diff --git a/lib/view_model/wallet_creation_vm.dart b/lib/view_model/wallet_creation_vm.dart index 17a8d6d28e..6e48eb0a8a 100644 --- a/lib/view_model/wallet_creation_vm.dart +++ b/lib/view_model/wallet_creation_vm.dart @@ -8,7 +8,6 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/nano/nano.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/settings_store.dart'; -import 'package:cake_wallet/view_model/restore/restore_mode.dart'; import 'package:cake_wallet/view_model/restore/restore_wallet.dart'; import 'package:cake_wallet/view_model/seed_settings_view_model.dart'; import 'package:cw_core/pathForWallet.dart'; @@ -113,7 +112,7 @@ abstract class WalletCreationVMBase with Store { await _walletInfoSource.add(walletInfo); await _appStore.changeCurrentWallet(wallet); getIt.get().registerSyncTask(); - _appStore.authenticationStore.allowed(); + _appStore.authenticationStore.allowedCreate(); state = ExecutedSuccessfullyState(); } catch (e, s) { print("error: $e"); From 1cb91e3295d5666ef6d0fd0cb0e61e9cb179310d Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Tue, 3 Dec 2024 18:22:40 +0100 Subject: [PATCH 06/13] Maybe fix Race condition --- lib/reactions/on_authentication_state_change.dart | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/reactions/on_authentication_state_change.dart b/lib/reactions/on_authentication_state_change.dart index be9b30fc51..c05f6fb0dc 100644 --- a/lib/reactions/on_authentication_state_change.dart +++ b/lib/reactions/on_authentication_state_change.dart @@ -52,9 +52,8 @@ void startAuthenticationStateChange( if ([AuthenticationState.allowed, AuthenticationState.allowedCreate] .contains(state)) { - if (requireHardwareWalletConnection() && - state == AuthenticationState.allowed) { - print("onAuthTriggerd"); + if (state == AuthenticationState.allowed && + requireHardwareWalletConnection()) { await navigatorKey.currentState!.pushNamedAndRemoveUntil( Routes.connectDevices, (route) => false, From 1978501998c40f359b2b87b7b35c948b0495e1c2 Mon Sep 17 00:00:00 2001 From: Czarek Nakamoto Date: Fri, 6 Dec 2024 08:20:32 -0600 Subject: [PATCH 07/13] fix namespace --- android/app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index c192111176..a332cfe2ae 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -44,7 +44,7 @@ android { disable 'InvalidPackage' } - namespace appProperties['id'] + namespace com.cakewallet.cake_wallet defaultConfig { applicationId appProperties['id'] @@ -99,4 +99,4 @@ configurations { implementation.exclude module:'proto-google-common-protos' implementation.exclude module:'protolite-well-known-types' implementation.exclude module:'protobuf-javalite' -} \ No newline at end of file +} From 3e7f540bf3d9ccc12bb9929fe2b5d445b6e8555b Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Mon, 9 Dec 2024 16:51:25 +0100 Subject: [PATCH 08/13] Maybe fix Race condition and add missing pop --- cw_monero/lib/monero_wallet_service.dart | 16 ++++++---------- .../screens/wallet_list/wallet_list_page.dart | 10 ++++++---- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart index 84a695b0c0..81a7ec7502 100644 --- a/cw_monero/lib/monero_wallet_service.dart +++ b/cw_monero/lib/monero_wallet_service.dart @@ -15,6 +15,7 @@ import 'package:cw_monero/api/wallet_manager.dart' as monero_wallet_manager; import 'package:cw_monero/api/wallet_manager.dart'; import 'package:cw_monero/ledger.dart'; import 'package:cw_monero/monero_wallet.dart'; +import 'package:collection/collection.dart'; import 'package:hive/hive.dart'; import 'package:ledger_flutter_plus/ledger_flutter_plus.dart'; import 'package:monero/monero.dart' as monero; @@ -404,15 +405,10 @@ class MoneroWalletService extends WalletService< @override bool requireHardwareWalletConnection(String name) { - bool checkWalletInfo(WalletInfo info) => - info.id == WalletBase.idFor(name, getType()); - - if (walletInfoSource.values.any(checkWalletInfo)) { - return walletInfoSource.values - .firstWhere(checkWalletInfo) - .isHardwareWallet; - } - - return false; + return walletInfoSource.values + .firstWhereOrNull( + (info) => info.id == WalletBase.idFor(name, getType())) + ?.isHardwareWallet ?? + false; } } diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart index f7e6515de4..53c7939c0a 100644 --- a/lib/src/screens/wallet_list/wallet_list_page.dart +++ b/lib/src/screens/wallet_list/wallet_list_page.dart @@ -422,8 +422,9 @@ class WalletListBodyState extends State { if (!isAuthenticatedSuccessfully) return; try { - if (widget.walletListViewModel - .requireHardwareWalletConnection(wallet)) { + final requireHardwareWalletConnection = widget.walletListViewModel + .requireHardwareWalletConnection(wallet); + if (requireHardwareWalletConnection) { await Navigator.of(context).pushNamed( Routes.connectDevices, arguments: ConnectDevicePageParams( @@ -445,8 +446,6 @@ class WalletListBodyState extends State { ); } - - changeProcessText( S.of(context).wallet_list_loading_wallet(wallet.name)); await widget.walletListViewModel.loadWallet(wallet); @@ -456,6 +455,9 @@ class WalletListBodyState extends State { if (responsiveLayoutUtil.shouldRenderMobileUI) { WidgetsBinding.instance.addPostFrameCallback((_) { if (this.mounted) { + if (requireHardwareWalletConnection) { + Navigator.of(context).pop(); + } widget.onWalletLoaded.call(context); } }); From 8aac560c866e5f13a84f10950683669beea45411 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Thu, 12 Dec 2024 17:59:22 +0100 Subject: [PATCH 09/13] Minor fixes --- .../connect_device/connect_device_page.dart | 20 ++++++++++++++++--- .../hardware_wallet/ledger_view_model.dart | 20 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/lib/src/screens/connect_device/connect_device_page.dart b/lib/src/screens/connect_device/connect_device_page.dart index c2cc40229a..faee63ee86 100644 --- a/lib/src/screens/connect_device/connect_device_page.dart +++ b/lib/src/screens/connect_device/connect_device_page.dart @@ -21,11 +21,13 @@ class ConnectDevicePageParams { final WalletType walletType; final OnConnectDevice onConnectDevice; final bool allowChangeWallet; + final bool allowBack; ConnectDevicePageParams({ required this.walletType, required this.onConnectDevice, this.allowChangeWallet = false, + this.allowBack = true, }); } @@ -33,19 +35,31 @@ class ConnectDevicePage extends BasePage { final WalletType walletType; final OnConnectDevice onConnectDevice; final bool allowChangeWallet; + final bool allowBack; final LedgerViewModel ledgerVM; ConnectDevicePage(ConnectDevicePageParams params, this.ledgerVM) : walletType = params.walletType, onConnectDevice = params.onConnectDevice, - allowChangeWallet = params.allowChangeWallet; + allowChangeWallet = params.allowChangeWallet, + allowBack = params.allowBack; @override String get title => S.current.restore_title_from_hardware_wallet; @override - Widget body(BuildContext context) => ConnectDevicePageBody( - walletType, onConnectDevice, allowChangeWallet, ledgerVM); + Widget? leading(BuildContext context) => + allowBack ? super.leading(context) : null; + + @override + Widget body(BuildContext context) => PopScope( + canPop: allowBack, + child: ConnectDevicePageBody( + walletType, + onConnectDevice, + allowChangeWallet, + ledgerVM, + )); } class ConnectDevicePageBody extends StatefulWidget { diff --git a/lib/view_model/hardware_wallet/ledger_view_model.dart b/lib/view_model/hardware_wallet/ledger_view_model.dart index 3cd131efa7..743ba5c297 100644 --- a/lib/view_model/hardware_wallet/ledger_view_model.dart +++ b/lib/view_model/hardware_wallet/ledger_view_model.dart @@ -4,13 +4,17 @@ import 'dart:io'; 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/main.dart'; import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/polygon/polygon.dart'; +import 'package:cake_wallet/routes.dart'; +import 'package:cake_wallet/src/screens/connect_device/connect_device_page.dart'; import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/wallet_type_utils.dart'; import 'package:cw_core/hardware/device_connection_type.dart'; import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_type.dart'; +import 'package:flutter/widgets.dart'; import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as sdk; import 'package:mobx/mobx.dart'; @@ -86,6 +90,8 @@ abstract class LedgerViewModelBase with Store { Future connectLedger(sdk.LedgerDevice device, WalletType type) async { if (isConnected) { try { + await _connectionChangeListener?.cancel(); + _connectionChangeListener = null; await _connection!.disconnect(); } catch (_) {} } @@ -93,6 +99,8 @@ abstract class LedgerViewModelBase with Store { ? ledgerPlusBLE : ledgerPlusUSB; + await ledger.stopScanning(); + if (_connectionChangeListener == null) { _connectionChangeListener = ledger.deviceStateChanges.listen((event) { print('Ledger Device State Changed: $event'); @@ -100,6 +108,18 @@ abstract class LedgerViewModelBase with Store { _connection = null; if (type == WalletType.monero) { monero!.resetLedgerConnection(); + + Navigator.of( navigatorKey.currentContext!).pushNamed( + Routes.connectDevices, + arguments: ConnectDevicePageParams( + walletType: WalletType.monero, + allowChangeWallet: true, + allowBack: false, + onConnectDevice: (context, ledgerVM) async { + Navigator.of(context).pop(); + }, + ), + ); } } }); From 3d96e37db784d5fcf6e05e53bd55bed09e56ac11 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Thu, 12 Dec 2024 18:07:28 +0100 Subject: [PATCH 10/13] Minor fixes --- cw_monero/lib/ledger.dart | 95 ++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 42 deletions(-) diff --git a/cw_monero/lib/ledger.dart b/cw_monero/lib/ledger.dart index c3747a251d..b95c655a07 100644 --- a/cw_monero/lib/ledger.dart +++ b/cw_monero/lib/ledger.dart @@ -2,6 +2,8 @@ import 'dart:async'; import 'dart:ffi'; import 'dart:typed_data'; +import 'package:collection/collection.dart'; +import 'package:cw_core/utils/print_verbose.dart'; import 'package:ffi/ffi.dart'; import 'package:ledger_flutter_plus/ledger_flutter_plus.dart'; import 'package:ledger_flutter_plus/ledger_flutter_plus_dart.dart'; @@ -31,6 +33,13 @@ void enableLedgerExchange(monero.wallet ptr, LedgerConnection connection) { final response = await exchange(connection, ledgerRequest); _logLedgerCommand(response, true); + if (ListEquality().equals(response, [0x55, 0x15])) { + await connection.disconnect(); + // // TODO: Show POPUP pls unlock your device + // await Future.delayed(Duration(seconds: 15)); + // response = await exchange(connection, ledgerRequest); + } + final Pointer result = malloc(response.length); for (var i = 0; i < response.length; i++) { result.asTypedList(response.length)[i] = response[i]; @@ -82,56 +91,58 @@ class ExchangeOperation extends LedgerRawOperation { Future> write(ByteDataWriter writer) async => [inputData]; } +const _ledgerMoneroCommands = { + 0x00: "INS_NONE", + 0x02: "INS_RESET", + 0x20: "INS_GET_KEY", + 0x21: "INS_DISPLAY_ADDRESS", + 0x22: "INS_PUT_KEY", + 0x24: "INS_GET_CHACHA8_PREKEY", + 0x26: "INS_VERIFY_KEY", + 0x28: "INS_MANAGE_SEEDWORDS", + 0x30: "INS_SECRET_KEY_TO_PUBLIC_KEY", + 0x32: "INS_GEN_KEY_DERIVATION", + 0x34: "INS_DERIVATION_TO_SCALAR", + 0x36: "INS_DERIVE_PUBLIC_KEY", + 0x38: "INS_DERIVE_SECRET_KEY", + 0x3A: "INS_GEN_KEY_IMAGE", + 0x3B: "INS_DERIVE_VIEW_TAG", + 0x3C: "INS_SECRET_KEY_ADD", + 0x3E: "INS_SECRET_KEY_SUB", + 0x40: "INS_GENERATE_KEYPAIR", + 0x42: "INS_SECRET_SCAL_MUL_KEY", + 0x44: "INS_SECRET_SCAL_MUL_BASE", + 0x46: "INS_DERIVE_SUBADDRESS_PUBLIC_KEY", + 0x48: "INS_GET_SUBADDRESS", + 0x4A: "INS_GET_SUBADDRESS_SPEND_PUBLIC_KEY", + 0x4C: "INS_GET_SUBADDRESS_SECRET_KEY", + 0x70: "INS_OPEN_TX", + 0x72: "INS_SET_SIGNATURE_MODE", + 0x74: "INS_GET_ADDITIONAL_KEY", + 0x76: "INS_STEALTH", + 0x77: "INS_GEN_COMMITMENT_MASK", + 0x78: "INS_BLIND", + 0x7A: "INS_UNBLIND", + 0x7B: "INS_GEN_TXOUT_KEYS", + 0x7D: "INS_PREFIX_HASH", + 0x7C: "INS_VALIDATE", + 0x7E: "INS_MLSAG", + 0x7F: "INS_CLSAG", + 0x80: "INS_CLOSE_TX", + 0xA0: "INS_GET_TX_PROOF", + 0xC0: "INS_GET_RESPONSE" +}; + void _logLedgerCommand(Uint8List command, [bool isResponse = true]) { String toHexString(Uint8List data) => data.map((e) => e.toRadixString(16).padLeft(2, '0')).join(); - const ledgerMoneroCommands = { - 0x00: "INS_NONE", - 0x02: "NS_RESET", - 0x20: "INS_GET_KEY", - 0x21: "INS_DISPLAY_ADDRESS", - 0x22: "INS_PUT_KEY", - 0x24: "INS_GET_CHACHA8_PREKEY", - 0x26: "INS_VERIFY_KEY", - 0x28: "INS_MANAGE_SEEDWORDS", - 0x30: "INS_SECRET_KEY_TO_PUBLIC_KEY", - 0x32: "INS_GEN_KEY_DERIVATION", - 0x34: "INS_DERIVATION_TO_SCALAR", - 0x36: "INS_DERIVE_PUBLIC_KEY", - 0x38: "INS_DERIVE_SECRET_KEY", - 0x3A: "INS_GEN_KEY_IMAGE", - 0x3B: "INS_DERIVE_VIEW_TAG", - 0x3C: "INS_SECRET_KEY_ADD", - 0x3E: "INS_SECRET_KEY_SUB", - 0x40: "INS_GENERATE_KEYPAIR", - 0x42: "INS_SECRET_SCAL_MUL_KEY", - 0x44: "INS_SECRET_SCAL_MUL_BASE", - 0x46: "INS_DERIVE_SUBADDRESS_PUBLIC_KEY", - 0x48: "INS_GET_SUBADDRESS", - 0x4A: "INS_GET_SUBADDRESS_SPEND_PUBLIC_KEY", - 0x4C: "INS_GET_SUBADDRESS_SECRET_KEY", - 0x70: "INS_OPEN_TX", - 0x72: "INS_SET_SIGNATURE_MODE", - 0x74: "INS_GET_ADDITIONAL_KEY", - 0x76: "INS_STEALTH", - 0x77: "INS_GEN_COMMITMENT_MASK", - 0x78: "INS_BLIND", - 0x7A: "INS_UNBLIND", - 0x7B: "INS_GEN_TXOUT_KEYS", - 0x7D: "INS_PREFIX_HASH", - 0x7C: "INS_VALIDATE", - 0x7E: "INS_MLSAG", - 0x7F: "INS_CLSAG", - 0x80: "INS_CLOSE_TX", - 0xA0: "INS_GET_TX_PROOF", - 0xC0: "INS_GET_RESPONSE" - }; + if (isResponse) { printV("< ${toHexString(command)}"); } else { printV( - "> ${ledgerMoneroCommands[command[1]]} ${toHexString(command.sublist(2))}"); + "> ${_ledgerMoneroCommands[command[1]]} ${toHexString(command.sublist(2))}"); } } From 883ecec564057ec514b2b323fdad34b890f7ad50 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Fri, 13 Dec 2024 11:00:09 +0100 Subject: [PATCH 11/13] Fix minor localization --- .../connect_device/connect_device_page.dart | 16 +++++++++------- .../hardware_wallet/ledger_view_model.dart | 2 +- res/values/strings_ar.arb | 1 + res/values/strings_bg.arb | 1 + res/values/strings_cs.arb | 1 + res/values/strings_de.arb | 1 + res/values/strings_en.arb | 1 + res/values/strings_es.arb | 1 + res/values/strings_fr.arb | 1 + res/values/strings_ha.arb | 1 + res/values/strings_hi.arb | 1 + res/values/strings_hr.arb | 1 + res/values/strings_hy.arb | 1 + res/values/strings_id.arb | 1 + res/values/strings_it.arb | 1 + res/values/strings_ja.arb | 1 + res/values/strings_ko.arb | 1 + res/values/strings_my.arb | 1 + res/values/strings_nl.arb | 1 + res/values/strings_pl.arb | 1 + res/values/strings_pt.arb | 1 + res/values/strings_ru.arb | 1 + res/values/strings_th.arb | 1 + res/values/strings_tl.arb | 1 + res/values/strings_tr.arb | 1 + res/values/strings_uk.arb | 1 + res/values/strings_ur.arb | 1 + res/values/strings_vi.arb | 1 + res/values/strings_yo.arb | 1 + res/values/strings_zh.arb | 1 + 30 files changed, 38 insertions(+), 8 deletions(-) diff --git a/lib/src/screens/connect_device/connect_device_page.dart b/lib/src/screens/connect_device/connect_device_page.dart index a8b4fdaa1e..ea97b864f3 100644 --- a/lib/src/screens/connect_device/connect_device_page.dart +++ b/lib/src/screens/connect_device/connect_device_page.dart @@ -22,13 +22,13 @@ class ConnectDevicePageParams { final WalletType walletType; final OnConnectDevice onConnectDevice; final bool allowChangeWallet; - final bool allowBack; + final bool isReconnect; ConnectDevicePageParams({ required this.walletType, required this.onConnectDevice, this.allowChangeWallet = false, - this.allowBack = true, + this.isReconnect = false, }); } @@ -36,25 +36,27 @@ class ConnectDevicePage extends BasePage { final WalletType walletType; final OnConnectDevice onConnectDevice; final bool allowChangeWallet; - final bool allowBack; + final bool isReconnect; final LedgerViewModel ledgerVM; ConnectDevicePage(ConnectDevicePageParams params, this.ledgerVM) : walletType = params.walletType, onConnectDevice = params.onConnectDevice, allowChangeWallet = params.allowChangeWallet, - allowBack = params.allowBack; + isReconnect = params.isReconnect; @override - String get title => S.current.restore_title_from_hardware_wallet; + String get title => isReconnect + ? S.current.reconnect_your_hardware_wallet + : S.current.restore_title_from_hardware_wallet; @override Widget? leading(BuildContext context) => - allowBack ? super.leading(context) : null; + !isReconnect ? super.leading(context) : null; @override Widget body(BuildContext context) => PopScope( - canPop: allowBack, + canPop: !isReconnect, child: ConnectDevicePageBody( walletType, onConnectDevice, diff --git a/lib/view_model/hardware_wallet/ledger_view_model.dart b/lib/view_model/hardware_wallet/ledger_view_model.dart index fa882e9cad..ddc74d3794 100644 --- a/lib/view_model/hardware_wallet/ledger_view_model.dart +++ b/lib/view_model/hardware_wallet/ledger_view_model.dart @@ -115,7 +115,7 @@ abstract class LedgerViewModelBase with Store { arguments: ConnectDevicePageParams( walletType: WalletType.monero, allowChangeWallet: true, - allowBack: false, + isReconnect: true, onConnectDevice: (context, ledgerVM) async { Navigator.of(context).pop(); }, diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index bd7fa47d77..e413daf3a5 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -538,6 +538,7 @@ "recipient_address": "عنوان المستلم", "reconnect": "أعد الاتصال", "reconnect_alert_text": "هل أنت متأكد من رغبتك في إعادة الاتصال؟", + "reconnect_your_hardware_wallet": "أعد توصيل محفظة الأجهزة الخاصة بك", "reconnection": "إعادة الاتصال", "red_dark_theme": "موضوع الظلام الأحمر", "red_light_theme": "موضوع الضوء الأحمر", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index bff37e95c2..c04acbbe8d 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -538,6 +538,7 @@ "recipient_address": "Адрес на получател", "reconnect": "Reconnect", "reconnect_alert_text": "Сигурни ли сте, че искате да се свържете отново?", + "reconnect_your_hardware_wallet": "Свържете отново хардуерния си портфейл", "reconnection": "Свързване отново", "red_dark_theme": "Червена тъмна тема", "red_light_theme": "Тема на червената светлина", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index d8025678f8..1c7a1d2fd5 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -538,6 +538,7 @@ "recipient_address": "Adresa příjemce", "reconnect": "Znovu připojit", "reconnect_alert_text": "Opravdu se chcete znovu připojit?", + "reconnect_your_hardware_wallet": "Znovu připojte svou hardwarovou peněženku", "reconnection": "Znovu připojit", "red_dark_theme": "Červené temné téma", "red_light_theme": "Téma červeného světla", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index b3aad50b06..aad8a0645a 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -539,6 +539,7 @@ "recipient_address": "Empfängeradresse", "reconnect": "Erneut verbinden", "reconnect_alert_text": "Sind Sie sicher, dass Sie sich neu verbinden möchten?", + "reconnect_your_hardware_wallet": "Schließen Sie Ihre Hardware -Brieftasche wieder an", "reconnection": "Neu verbinden", "red_dark_theme": "Red Dark Thema", "red_light_theme": "Red Light Thema", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index bd483adb1f..b33647530f 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -538,6 +538,7 @@ "recipient_address": "Recipient address", "reconnect": "Reconnect", "reconnect_alert_text": "Are you sure you want to reconnect?", + "reconnect_your_hardware_wallet": "Reconnect your Hardware Wallet", "reconnection": "Reconnection", "red_dark_theme": "Red Dark Theme", "red_light_theme": "Red Light Theme", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 45b1d279b4..8ef4234e01 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -539,6 +539,7 @@ "recipient_address": "Dirección del receptor", "reconnect": "Volver a conectar", "reconnect_alert_text": "¿Estás seguro de reconectar?", + "reconnect_your_hardware_wallet": "Vuelva a conectar su billetera de hardware", "reconnection": "Reconexión", "red_dark_theme": "Tema rojo oscuro", "red_light_theme": "Tema de la luz roja", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index a359e3630f..d455c48c62 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -538,6 +538,7 @@ "recipient_address": "Adresse bénéficiaire", "reconnect": "Reconnecter", "reconnect_alert_text": "Êtes vous certain de vouloir vous reconnecter ?", + "reconnect_your_hardware_wallet": "Reconnectez votre portefeuille matériel", "reconnection": "Reconnexion", "red_dark_theme": "Thème rouge sombre", "red_light_theme": "Thème rouge clair", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index 48ede7b7c3..ce49b382cc 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -540,6 +540,7 @@ "recipient_address": "Adireshin mai karɓa", "reconnect": "Sake haɗawa", "reconnect_alert_text": "Shin kun tabbata kuna son sake haɗawa?", + "reconnect_your_hardware_wallet": "Sake kunnawa kayan aiki", "reconnection": "Sake haɗawa", "red_dark_theme": "Ja duhu taken", "red_light_theme": "Ja mai haske", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index c2feea9395..0f3cb852be 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -540,6 +540,7 @@ "recipient_address": "प्राप्तकर्ता का पता", "reconnect": "रिकनेक्ट", "reconnect_alert_text": "क्या आप पुन: कनेक्ट होना सुनिश्चित करते हैं?", + "reconnect_your_hardware_wallet": "अपने हार्डवेयर वॉलेट को फिर से कनेक्ट करें", "reconnection": "पुनर्संयोजन", "red_dark_theme": "लाल डार्क थीम", "red_light_theme": "लाल प्रकाश थीम", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index c82e2a5f89..667ba7f39d 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -538,6 +538,7 @@ "recipient_address": "Primateljeva adresa", "reconnect": "Ponovno povezivanje", "reconnect_alert_text": "Jeste li sigurni da se želite ponovno povezati?", + "reconnect_your_hardware_wallet": "Ponovno spojite svoj hardverski novčanik", "reconnection": "Ponovno povezivanje", "red_dark_theme": "Crvena tamna tema", "red_light_theme": "Tema crvenog svjetla", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index d83bc2a3aa..0757d7cc4d 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -538,6 +538,7 @@ "recipient_address": "Ստացողի հասցե", "reconnect": "Վերակապվել", "reconnect_alert_text": "Դուք վստահ եք, որ ուզում եք վերակապվել?", + "reconnect_your_hardware_wallet": "Միացրեք ձեր ապարատային դրամապանակը", "reconnection": "Վերակապում", "red_dark_theme": "Կարմիր մութ տեսք", "red_light_theme": "Կարմիր պայծառ տեսք", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index ca140e63e1..a76d46a614 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -540,6 +540,7 @@ "recipient_address": "Alamat penerima", "reconnect": "Sambungkan kembali", "reconnect_alert_text": "Apakah Anda yakin ingin menyambungkan kembali?", + "reconnect_your_hardware_wallet": "Hubungkan kembali dompet perangkat keras Anda", "reconnection": "Koneksi kembali", "red_dark_theme": "Tema gelap merah", "red_light_theme": "Tema lampu merah", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index f5dbc1c5ab..41a007d31d 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -540,6 +540,7 @@ "recipient_address": "Indirizzo di destinazione", "reconnect": "Riconnetti", "reconnect_alert_text": "Sei sicuro di volerti riconnettere?", + "reconnect_your_hardware_wallet": "Ricollega il tuo portafoglio hardware", "reconnection": "Riconnessione", "red_dark_theme": "Red Dark Theme", "red_light_theme": "Tema della luce rossa", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 182133e68e..1a6d24c619 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -539,6 +539,7 @@ "recipient_address": "受信者のアドレス", "reconnect": "再接続", "reconnect_alert_text": "再接続しますか?", + "reconnect_your_hardware_wallet": "ハードウェアウォレットを再接続します", "reconnection": "再接続", "red_dark_theme": "赤い暗いテーマ", "red_light_theme": "赤色光のテーマ", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 747c316d69..88240973c1 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -539,6 +539,7 @@ "recipient_address": "받는 사람 주소", "reconnect": "다시 연결", "reconnect_alert_text": "다시 연결 하시겠습니까?", + "reconnect_your_hardware_wallet": "하드웨어 지갑을 다시 연결하십시오", "reconnection": "재 연결", "red_dark_theme": "빨간 어두운 테마", "red_light_theme": "빨간불 테마", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index 8fe87b34ca..fa719f9a06 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -538,6 +538,7 @@ "recipient_address": "လက်ခံသူလိပ်စာ", "reconnect": "ပြန်လည်ချိတ်ဆက်ပါ။", "reconnect_alert_text": "ပြန်လည်ချိတ်ဆက်လိုသည်မှာ သေချာပါသလား။ ?", + "reconnect_your_hardware_wallet": "သင့်ရဲ့ hardware ပိုက်ဆံအိတ်ကိုပြန်လည်ချိတ်ဆက်ပါ", "reconnection": "ပြန်လည်ချိတ်ဆက်မှု", "red_dark_theme": "အနီရောင်မှောင်မိုက်ဆောင်ပုဒ်", "red_light_theme": "အနီရောင်အလင်းအကြောင်းအရာ", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index ca7052b0ec..a7e6df79ab 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -538,6 +538,7 @@ "recipient_address": "Adres ontvanger", "reconnect": "Sluit", "reconnect_alert_text": "Weet u zeker dat u opnieuw verbinding wilt maken?", + "reconnect_your_hardware_wallet": "Sluit uw hardware -portemonnee opnieuw aan", "reconnection": "Reconnection", "red_dark_theme": "Rood donker thema", "red_light_theme": "Rood licht thema", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index fad2bb0269..d562700d8a 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -538,6 +538,7 @@ "recipient_address": "Adres odbiorcy", "reconnect": "Połącz ponownie", "reconnect_alert_text": "Czy na pewno ponownie się ponownie połączysz?", + "reconnect_your_hardware_wallet": "Ponownie podłącz portfel sprzętowy", "reconnection": "Ponowne łączenie", "red_dark_theme": "Czerwony Mroczny motyw", "red_light_theme": "Motyw czerwony światło", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index c59afec65f..aad6c648d6 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -540,6 +540,7 @@ "recipient_address": "Endereço do destinatário", "reconnect": "Reconectar", "reconnect_alert_text": "Você tem certeza de que deseja reconectar?", + "reconnect_your_hardware_wallet": "Reconecte sua carteira de hardware", "reconnection": "Reconectar", "red_dark_theme": "Tema escuro vermelho", "red_light_theme": "Tema da luz vermelha", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 94b1c7010f..bb87087969 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -539,6 +539,7 @@ "recipient_address": "Адрес получателя", "reconnect": "Переподключиться", "reconnect_alert_text": "Вы хотите переподключиться?", + "reconnect_your_hardware_wallet": "Воссоедините свой аппаратный кошелек", "reconnection": "Переподключение", "red_dark_theme": "Красная темная тема", "red_light_theme": "Тема красного света", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index f35187cd45..550a1622b6 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -538,6 +538,7 @@ "recipient_address": "ที่อยู่ผู้รับ", "reconnect": "เชื่อมต่อใหม่", "reconnect_alert_text": "คุณแน่ใจหรือไม่ว่าต้องการเชื่อมต่อใหม่?", + "reconnect_your_hardware_wallet": "เชื่อมต่อกระเป๋าเงินฮาร์ดแวร์ของคุณอีกครั้ง", "reconnection": "เชื่อมต่อใหม่", "red_dark_theme": "ธีมสีแดงเข้ม", "red_light_theme": "ธีมแสงสีแดง", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index 290fcf4bfc..d9930211d0 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -538,6 +538,7 @@ "recipient_address": "Address ng tatanggap", "reconnect": "Kumonekta muli", "reconnect_alert_text": "Sigurado ka bang gusto mong kumonekta uli?", + "reconnect_your_hardware_wallet": "Ikonekta muli ang iyong wallet ng hardware", "reconnection": "Muling pagkakakonekta", "red_dark_theme": "Red Dark Theme", "red_light_theme": "Red Light Theme", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 912cd52e45..e73fa46427 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -538,6 +538,7 @@ "recipient_address": "Alıcı adresi", "reconnect": "Yeniden Bağlan", "reconnect_alert_text": "Yeniden bağlanmak istediğinden emin misin?", + "reconnect_your_hardware_wallet": "Donanım cüzdanınızı yeniden bağlayın", "reconnection": "Yeniden bağlantı", "red_dark_theme": "Kırmızı Karanlık Tema", "red_light_theme": "Kırmızı Işık Teması", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index fd03f437e4..0c858b31fb 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -538,6 +538,7 @@ "recipient_address": "Адреса одержувача", "reconnect": "Перепідключитися", "reconnect_alert_text": "Ви хочете перепідключитися?", + "reconnect_your_hardware_wallet": "Повторно підключіть свій апаратний гаманець", "reconnection": "Перепідключення", "red_dark_theme": "Червона темна тема", "red_light_theme": "Тема червоного світла", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index 03140020a3..89695678f7 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -540,6 +540,7 @@ "recipient_address": "وصول کنندہ کا پتہ", "reconnect": "دوبارہ جڑیں۔", "reconnect_alert_text": "کیا آپ واقعی دوبارہ جڑنا چاہتے ہیں؟", + "reconnect_your_hardware_wallet": "اپنے ہارڈ ویئر پرس کو دوبارہ مربوط کریں", "reconnection": "دوبارہ رابطہ", "red_dark_theme": "ریڈ ڈارک تھیم", "red_light_theme": "ریڈ لائٹ تھیم", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index e40edf458c..61c91daf60 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -537,6 +537,7 @@ "recipient_address": "Địa chỉ người nhận", "reconnect": "Kết nối lại", "reconnect_alert_text": "Bạn có chắc chắn muốn kết nối lại không?", + "reconnect_your_hardware_wallet": "Kết nối lại ví phần cứng của bạn", "reconnection": "Kết nối lại", "red_dark_theme": "Chủ đề tối đỏ", "red_light_theme": "Chủ đề sáng đỏ", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index 8b3cdc3587..f710878d98 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -539,6 +539,7 @@ "recipient_address": "Àdírẹ́sì olùgbà", "reconnect": "Ṣe àtúnse", "reconnect_alert_text": "Ṣó dá ẹ lójú pé ẹ fẹ́ ṣe àtúnse?", + "reconnect_your_hardware_wallet": "Ṣe atunṣe apamọwọ ohun elo rẹ", "reconnection": "Àtúnṣe", "red_dark_theme": "Akọle dudu pupa", "red_light_theme": "Akori ina pupa", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 63e92a67d3..d430564142 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -538,6 +538,7 @@ "recipient_address": "收件人地址", "reconnect": "重新连接", "reconnect_alert_text": "您确定要重新连接吗?", + "reconnect_your_hardware_wallet": "重新连接您的硬件钱包", "reconnection": "重新连接", "red_dark_theme": "红色的黑暗主题", "red_light_theme": "红灯主题", From 723185b00faa48c0c6a4b1a69167ad2edc53ffeb Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Fri, 13 Dec 2024 13:35:05 +0100 Subject: [PATCH 12/13] Fix minor localization --- lib/view_model/hardware_wallet/ledger_view_model.dart | 3 +-- res/values/strings_de.arb | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/view_model/hardware_wallet/ledger_view_model.dart b/lib/view_model/hardware_wallet/ledger_view_model.dart index ddc74d3794..4aeb5f36ba 100644 --- a/lib/view_model/hardware_wallet/ledger_view_model.dart +++ b/lib/view_model/hardware_wallet/ledger_view_model.dart @@ -71,7 +71,7 @@ abstract class LedgerViewModelBase with Store { ].request(); return statuses.values.where((status) => status.isDenied).isEmpty; - }); + }, bleOptions: sdk.BluetoothOptions(maxScanDuration: Duration(minutes: 2))); _bleIsInitialized = true; } } @@ -100,7 +100,6 @@ abstract class LedgerViewModelBase with Store { ? ledgerPlusBLE : ledgerPlusUSB; - await ledger.stopScanning(); if (_connectionChangeListener == null) { _connectionChangeListener = ledger.deviceStateChanges.listen((event) { diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index aad8a0645a..ec4d70f649 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -539,7 +539,7 @@ "recipient_address": "Empfängeradresse", "reconnect": "Erneut verbinden", "reconnect_alert_text": "Sind Sie sicher, dass Sie sich neu verbinden möchten?", - "reconnect_your_hardware_wallet": "Schließen Sie Ihre Hardware -Brieftasche wieder an", + "reconnect_your_hardware_wallet": "Hardware-Wallet neu verbinden", "reconnection": "Neu verbinden", "red_dark_theme": "Red Dark Thema", "red_light_theme": "Red Light Thema", @@ -970,4 +970,4 @@ "you_will_get": "Konvertieren zu", "you_will_send": "Konvertieren von", "yy": "YY" -} \ No newline at end of file +} From e0e54f51753aa407e29ecd6eee7a8d7494071e5b Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Fri, 13 Dec 2024 15:26:57 +0100 Subject: [PATCH 13/13] Add Text prompt if device is not showing after 10 seconds. --- .../connect_device/connect_device_page.dart | 47 +++++++++++++------ .../hardware_wallet/ledger_view_model.dart | 30 ++++++++---- res/values/strings_ar.arb | 1 + res/values/strings_bg.arb | 1 + res/values/strings_cs.arb | 1 + res/values/strings_de.arb | 3 +- res/values/strings_en.arb | 1 + res/values/strings_es.arb | 1 + res/values/strings_fr.arb | 1 + res/values/strings_ha.arb | 1 + res/values/strings_hi.arb | 1 + res/values/strings_hr.arb | 1 + res/values/strings_hy.arb | 1 + res/values/strings_id.arb | 1 + res/values/strings_it.arb | 1 + res/values/strings_ja.arb | 1 + res/values/strings_ko.arb | 3 +- res/values/strings_my.arb | 1 + res/values/strings_nl.arb | 1 + res/values/strings_pl.arb | 1 + res/values/strings_pt.arb | 1 + res/values/strings_ru.arb | 1 + res/values/strings_th.arb | 1 + res/values/strings_tl.arb | 1 + res/values/strings_tr.arb | 1 + res/values/strings_uk.arb | 1 + res/values/strings_ur.arb | 1 + res/values/strings_vi.arb | 1 + res/values/strings_yo.arb | 1 + res/values/strings_zh.arb | 1 + 30 files changed, 82 insertions(+), 27 deletions(-) diff --git a/lib/src/screens/connect_device/connect_device_page.dart b/lib/src/screens/connect_device/connect_device_page.dart index ea97b864f3..5e94c78a41 100644 --- a/lib/src/screens/connect_device/connect_device_page.dart +++ b/lib/src/screens/connect_device/connect_device_page.dart @@ -91,6 +91,8 @@ class ConnectDevicePageBodyState extends State { late Timer? _bleStateTimer = null; late StreamSubscription? _bleRefresh = null; + bool longWait = false; + @override void initState() { super.initState(); @@ -105,6 +107,11 @@ class ConnectDevicePageBodyState extends State { _usbRefreshTimer = Timer.periodic(Duration(seconds: 1), (_) => _refreshUsbDevices()); } + + Future.delayed(Duration(seconds: 10), () { + if (widget.ledgerVM.bleIsEnabled && bleDevices.isEmpty) + setState(() => longWait = true); + }); }); } @@ -114,6 +121,8 @@ class ConnectDevicePageBodyState extends State { _bleStateTimer?.cancel(); _usbRefreshTimer?.cancel(); _bleRefresh?.cancel(); + + widget.ledgerVM.stopScanning(); super.dispose(); } @@ -134,12 +143,14 @@ class ConnectDevicePageBodyState extends State { Future _refreshBleDevices() async { try { if (widget.ledgerVM.bleIsEnabled) { - _bleRefresh = widget.ledgerVM - .scanForBleDevices() - .listen((device) => setState(() => bleDevices.add(device))) - ..onError((e) { - throw e.toString(); - }); + _bleRefresh = + widget.ledgerVM.scanForBleDevices().listen((device) => setState(() { + bleDevices.add(device); + if (longWait) longWait = false; + })) + ..onError((e) { + throw e.toString(); + }); _bleRefreshTimer?.cancel(); _bleRefreshTimer = null; } @@ -191,15 +202,21 @@ class ConnectDevicePageBodyState extends State { textAlign: TextAlign.center, ), ), - // DeviceTile( - // onPressed: () => Navigator.of(context).push( - // MaterialPageRoute( - // builder: (BuildContext context) => DebugDevicePage(), - // ), - // ), - // title: "Debug Ledger", - // leading: imageLedger, - // ), + Offstage( + offstage: !longWait, + child: Padding( + padding: EdgeInsets.only(left: 20, right: 20, bottom: 20), + child: Text(S.of(context).if_you_dont_see_your_device, + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Theme.of(context) + .extension()! + .titleColor), + textAlign: TextAlign.center, + ), + ), + ), Observer( builder: (_) => Offstage( offstage: widget.ledgerVM.bleIsEnabled, diff --git a/lib/view_model/hardware_wallet/ledger_view_model.dart b/lib/view_model/hardware_wallet/ledger_view_model.dart index 4aeb5f36ba..b48f641a21 100644 --- a/lib/view_model/hardware_wallet/ledger_view_model.dart +++ b/lib/view_model/hardware_wallet/ledger_view_model.dart @@ -63,15 +63,18 @@ abstract class LedgerViewModelBase with Store { bool _bleIsInitialized = false; Future _initBLE() async { if (bleIsEnabled && !_bleIsInitialized) { - ledgerPlusBLE = sdk.LedgerInterface.ble(onPermissionRequest: (_) async { - Map statuses = await [ - Permission.bluetoothScan, - Permission.bluetoothConnect, - Permission.bluetoothAdvertise, - ].request(); - - return statuses.values.where((status) => status.isDenied).isEmpty; - }, bleOptions: sdk.BluetoothOptions(maxScanDuration: Duration(minutes: 2))); + ledgerPlusBLE = sdk.LedgerInterface.ble( + onPermissionRequest: (_) async { + Map statuses = await [ + Permission.bluetoothScan, + Permission.bluetoothConnect, + Permission.bluetoothAdvertise, + ].request(); + + return statuses.values.where((status) => status.isDenied).isEmpty; + }, + bleOptions: + sdk.BluetoothOptions(maxScanDuration: Duration(minutes: 5))); _bleIsInitialized = true; } } @@ -88,12 +91,19 @@ abstract class LedgerViewModelBase with Store { Stream scanForUsbDevices() => ledgerPlusUSB.scan(); + Future stopScanning() async { + await ledgerPlusBLE.stopScanning(); + if (!Platform.isIOS) { + await ledgerPlusUSB.stopScanning(); + } + } + Future connectLedger(sdk.LedgerDevice device, WalletType type) async { if (isConnected) { try { await _connectionChangeListener?.cancel(); _connectionChangeListener = null; - await _connection!.disconnect(); + await _connection!.disconnect().catchError((_) {}); } catch (_) {} } final ledger = device.connectionType == sdk.ConnectionType.ble diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index e413daf3a5..13e74f0ee5 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -355,6 +355,7 @@ "how_to_use": " ﻞﻤﻌﺘﺴﺗ ﻒﻴﻛ", "how_to_use_card": "كيفية استخدام هذه البطاقة", "id": "رقم المعرف:", + "if_you_dont_see_your_device": "إذا كنت لا ترى جهازك أعلاه ، فيرجى التأكد من أن دفتر الأستاذ الخاص بك مستيقظًا ومؤمنًا!", "ignor": "تجاهل", "import": "ﺩﺭﻮﺘﺴﻳ", "importNFTs": "NFTs ﺩﺍﺮﻴﺘﺳﺍ", diff --git a/res/values/strings_bg.arb b/res/values/strings_bg.arb index c04acbbe8d..c2f68537bb 100644 --- a/res/values/strings_bg.arb +++ b/res/values/strings_bg.arb @@ -355,6 +355,7 @@ "how_to_use": "Как да използвам", "how_to_use_card": "Как се ползва тази карта", "id": "ID: ", + "if_you_dont_see_your_device": "Ако не виждате устройството си по -горе, моля, уверете се, че вашата книга е будна и отключена!", "ignor": "Игнориране", "import": "Импортиране", "importNFTs": "Импортирайте NFT", diff --git a/res/values/strings_cs.arb b/res/values/strings_cs.arb index 1c7a1d2fd5..1c7c5ae95c 100644 --- a/res/values/strings_cs.arb +++ b/res/values/strings_cs.arb @@ -355,6 +355,7 @@ "how_to_use": "Jak používat", "how_to_use_card": "Jak použít tuto kartu", "id": "ID: ", + "if_you_dont_see_your_device": "Pokud vaše zařízení nevidíte výše, ujistěte se, že vaše kniha je vzhůru a odemknutá!", "ignor": "Ignorovat", "import": "Import", "importNFTs": "Importujte NFT", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index ec4d70f649..bbf4f47b30 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -355,6 +355,7 @@ "how_to_use": "Wie benutzt man", "how_to_use_card": "Wie man diese Karte benutzt", "id": "ID: ", + "if_you_dont_see_your_device": "Wenn Sie Ihr Gerät nicht sehen, stellen Sie bitte sicher, dass Ihr Ledger an und entsperrt ist!", "ignor": "Ignorieren", "import": "Importieren", "importNFTs": "NFTs importieren", @@ -502,8 +503,8 @@ "placeholder_transactions": "Ihre Transaktionen werden hier angezeigt", "please_fill_totp": "Bitte geben Sie den 8-stelligen Code ein, der auf Ihrem anderen Gerät vorhanden ist", "please_make_selection": "Bitte treffen Sie unten eine Auswahl zum Erstellen oder Wiederherstellen Ihrer Wallet.", - "Please_reference_document": "Weitere Informationen finden Sie in den Dokumenten unten.", "please_reference_document": "Bitte verweisen Sie auf die folgenden Dokumente, um weitere Informationen zu erhalten.", + "Please_reference_document": "Weitere Informationen finden Sie in den Dokumenten unten.", "please_select": "Bitte auswählen:", "please_select_backup_file": "Bitte wählen Sie die Sicherungsdatei und geben Sie das Sicherungskennwort ein.", "please_try_to_connect_to_another_node": "Bitte versuchen Sie, sich mit einem anderen Knoten zu verbinden", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index b33647530f..27ee744135 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -355,6 +355,7 @@ "how_to_use": "How to use", "how_to_use_card": "How to use this card", "id": "ID: ", + "if_you_dont_see_your_device": "If you don't see your device above, please be sure your Ledger is awake and unlocked!", "ignor": "Ignore", "import": "Import", "importNFTs": "Import NFTs", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 8ef4234e01..e3730e8658 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -355,6 +355,7 @@ "how_to_use": "Cómo utilizar", "how_to_use_card": "Cómo usar esta tarjeta", "id": "ID: ", + "if_you_dont_see_your_device": "Si no ve su dispositivo arriba, ¡asegúrese de que su libro mayor esté despierto y desbloqueado!", "ignor": "Pasar por alto", "import": "Importar", "importNFTs": "Importar NFT", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index d455c48c62..48ba52b5dc 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -355,6 +355,7 @@ "how_to_use": "Comment utiliser", "how_to_use_card": "Comment utiliser cette carte", "id": "ID : ", + "if_you_dont_see_your_device": "Si vous ne voyez pas votre appareil ci-dessus, assurez-vous que votre grand livre est éveillé et déverrouillé!", "ignor": "Ignorer", "import": "Importer", "importNFTs": "Importer des NFT", diff --git a/res/values/strings_ha.arb b/res/values/strings_ha.arb index ce49b382cc..ff647314cc 100644 --- a/res/values/strings_ha.arb +++ b/res/values/strings_ha.arb @@ -355,6 +355,7 @@ "how_to_use": "Yadda ake amfani da shi", "how_to_use_card": "Yadda ake amfani da wannan kati", "id": "ID:", + "if_you_dont_see_your_device": "Idan baku ga na'urarka da ke sama ba, da fatan za a tabbata Ledger dinku yana farkawa kuma a buɗe!", "ignor": "Yi watsi da shi", "import": "Shigo da", "importNFTs": "Shigo da NFTs", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 0f3cb852be..64b906f324 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -355,6 +355,7 @@ "how_to_use": "का उपयोग कैसे करें", "how_to_use_card": "इस कार्ड का उपयोग कैसे करें", "id": "ID: ", + "if_you_dont_see_your_device": "यदि आप अपने डिवाइस को ऊपर नहीं देखते हैं, तो कृपया सुनिश्चित करें कि आपका लेजर जागृत और अनलॉक हो गया है!", "ignor": "नज़रअंदाज़ करना", "import": "आयात", "importNFTs": "एनएफटी आयात करें", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 667ba7f39d..5358da62fd 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -355,6 +355,7 @@ "how_to_use": "Kako koristiti", "how_to_use_card": "Kako koristiti ovu karticu", "id": "ID: ", + "if_you_dont_see_your_device": "Ako svoj uređaj ne vidite gore, budite sigurni da je vaša knjiga budna i otključana!", "ignor": "Zanemariti", "import": "Uvoz", "importNFTs": "Uvoz NFT-ova", diff --git a/res/values/strings_hy.arb b/res/values/strings_hy.arb index 0757d7cc4d..12651834ed 100644 --- a/res/values/strings_hy.arb +++ b/res/values/strings_hy.arb @@ -355,6 +355,7 @@ "how_to_use": "Ինչպես օգտագործել", "how_to_use_card": "Ինչպես օգտագործել այս քարտը", "id": "ID: ", + "if_you_dont_see_your_device": "Եթե ​​ձեր սարքը վերեւում չեք տեսնում, համոզվեք, որ ձեր Ledger- ը արթուն է եւ բացված:", "ignor": "Անտեսել", "import": "Ներմուծել", "importNFTs": "Ներմուծել NFT-ներ", diff --git a/res/values/strings_id.arb b/res/values/strings_id.arb index a76d46a614..405760effb 100644 --- a/res/values/strings_id.arb +++ b/res/values/strings_id.arb @@ -355,6 +355,7 @@ "how_to_use": "Cara Penggunaan", "how_to_use_card": "Bagaimana menggunakan kartu ini", "id": "ID: ", + "if_you_dont_see_your_device": "Jika Anda tidak melihat perangkat Anda di atas, pastikan buku besar Anda terjaga dan tidak terkunci!", "ignor": "Abaikan", "import": "Impor", "importNFTs": "Impor NFT", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 41a007d31d..0dde11106c 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -356,6 +356,7 @@ "how_to_use": "Come usare", "how_to_use_card": "Come usare questa carta", "id": "ID: ", + "if_you_dont_see_your_device": "Se non vedi il tuo dispositivo sopra, assicurati che il tuo libro mastro sia sveglio e sbloccato!", "ignor": "Ignorare", "import": "Importare", "importNFTs": "Importa NFT", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 1a6d24c619..56e5f10814 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -356,6 +356,7 @@ "how_to_use": "使い方", "how_to_use_card": "このカードの使用方法", "id": "ID: ", + "if_you_dont_see_your_device": "上記のデバイスが表示されない場合は、元帳が目を覚ましてロック解除されていることを確認してください!", "ignor": "無視", "import": "輸入", "importNFTs": "NFTのインポート", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 88240973c1..a04d028eb7 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -355,6 +355,7 @@ "how_to_use": "사용하는 방법", "how_to_use_card": "이 카드를 사용하는 방법", "id": "ID: ", + "if_you_dont_see_your_device": "위의 장치가 표시되지 않으면 원장이 깨어 있고 잠금 해제되었는지 확인하십시오!", "ignor": "무시하다", "import": "수입", "importNFTs": "NFT 가져오기", @@ -502,8 +503,8 @@ "placeholder_transactions": "거래가 여기에 표시됩니다", "please_fill_totp": "다른 기기에 있는 8자리 코드를 입력하세요.", "please_make_selection": "아래에서 선택하십시오 지갑 만들기 또는 복구.", - "please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.", "Please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.", + "please_reference_document": "자세한 내용은 아래 문서를 참조하십시오.", "please_select": "선택 해주세요:", "please_select_backup_file": "백업 파일을 선택하고 백업 암호를 입력하십시오.", "please_try_to_connect_to_another_node": "다른 노드에 연결을 시도하십시오", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index fa719f9a06..6182c833db 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -355,6 +355,7 @@ "how_to_use": "အသုံးပြုနည်း", "how_to_use_card": "ဒီကတ်ကို ဘယ်လိုသုံးမလဲ။", "id": "ID:", + "if_you_dont_see_your_device": "သင်၏စက်ကိုအထက်တွင်မတွေ့ပါကသင်၏ Ledger သည်နိုးလာပြီးသော့ဖွင့်နေသည်ကိုသေချာပါစေ။", "ignor": "လျစ်လျူရှုပါ။", "import": "သွင်းကုန်", "importNFTs": "NFTs များကို တင်သွင်းပါ။", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index a7e6df79ab..82a26bdb0c 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -355,6 +355,7 @@ "how_to_use": "Hoe te gebruiken", "how_to_use_card": "Hoe deze kaart te gebruiken", "id": "ID: ", + "if_you_dont_see_your_device": "Als u uw apparaat hierboven niet ziet, zorg er dan voor dat uw grootboek wakker is en ontgrendeld is!", "ignor": "Negeren", "import": "Importeren", "importNFTs": "NFT's importeren", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index d562700d8a..7a70ac94f2 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -355,6 +355,7 @@ "how_to_use": "Jak używać", "how_to_use_card": "Jak korzystać z tej karty?", "id": "ID: ", + "if_you_dont_see_your_device": "Jeśli nie widzisz swojego urządzenia powyżej, upewnij się, że Twoja księga nie śpi i odblokowana!", "ignor": "Ignorować", "import": "Import", "importNFTs": "Importuj NFT", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index aad6c648d6..286642e843 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -355,6 +355,7 @@ "how_to_use": "Como usar", "how_to_use_card": "Como usar este cartão", "id": "ID: ", + "if_you_dont_see_your_device": "Se você não vê seu dispositivo acima, certifique -se de que seu livro esteja acordado e desbloqueado!", "ignor": "Ignorar", "import": "Importar", "importNFTs": "Importar NFTs", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index bb87087969..879633dfed 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -355,6 +355,7 @@ "how_to_use": "Как использовать", "how_to_use_card": "Как использовать эту карту", "id": "ID: ", + "if_you_dont_see_your_device": "Если вы не видите свое устройство выше, пожалуйста, убедитесь, что ваша бухгалтерская книга бодрствует и разблокирована!", "ignor": "Игнорировать", "import": "Импортировать", "importNFTs": "Импортировать NFT", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 550a1622b6..d67a4e87a5 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -355,6 +355,7 @@ "how_to_use": "วิธีใช้", "how_to_use_card": "วิธีใช้บัตรนี้", "id": "ID: ", + "if_you_dont_see_your_device": "หากคุณไม่เห็นอุปกรณ์ของคุณด้านบนโปรดตรวจสอบให้แน่ใจว่าบัญชีแยกประเภทของคุณตื่นและปลดล็อค!", "ignor": "ละเว้น", "import": "นำเข้า", "importNFTs": "นำเข้า NFT", diff --git a/res/values/strings_tl.arb b/res/values/strings_tl.arb index d9930211d0..2a318175f1 100644 --- a/res/values/strings_tl.arb +++ b/res/values/strings_tl.arb @@ -355,6 +355,7 @@ "how_to_use": "Paano gamitin", "how_to_use_card": "Paano gamitin ang card na ito", "id": "ID: ", + "if_you_dont_see_your_device": "Kung hindi mo nakikita ang iyong aparato sa itaas, siguraduhin na ang iyong ledger ay gising at naka -lock!", "ignor": "Huwag pansinin", "import": "Mag-import", "importNFTs": "Mag-import ng mga NFT", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index e73fa46427..0c726c808e 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -355,6 +355,7 @@ "how_to_use": "Nasıl kullanılır", "how_to_use_card": "Bu kart nasıl kullanılır", "id": "ID: ", + "if_you_dont_see_your_device": "Cihazınızı yukarıda görmüyorsanız, lütfen defterinizin uyanık olduğundan ve kilidinin açıldığından emin olun!", "ignor": "Yoksay", "import": "İçe aktarmak", "importNFTs": "NFT'leri içe aktar", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 0c858b31fb..45398ce13e 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -355,6 +355,7 @@ "how_to_use": "Як використовувати", "how_to_use_card": "Як використовувати цю картку", "id": "ID: ", + "if_you_dont_see_your_device": "Якщо ви не бачите свого пристрою вище, будь ласка, переконайтеся, що ваша книга прокинеться і розблокована!", "ignor": "Ігнорувати", "import": "Імпорт", "importNFTs": "Імпорт NFT", diff --git a/res/values/strings_ur.arb b/res/values/strings_ur.arb index 89695678f7..91a6bb5027 100644 --- a/res/values/strings_ur.arb +++ b/res/values/strings_ur.arb @@ -355,6 +355,7 @@ "how_to_use": " ﮧﻘﯾﺮﻃ ﺎﮐ ﮯﻧﺮﮐ ﻝﺎﻤﻌﺘﺳﺍ", "how_to_use_card": "اس کارڈ کو استعمال کرنے کا طریقہ", "id": "ID:", + "if_you_dont_see_your_device": "اگر آپ اوپر اپنا آلہ نہیں دیکھتے ہیں تو ، براہ کرم یقینی بنائیں کہ آپ کا لیجر بیدار اور غیر مقفل ہے!", "ignor": "نظر انداز کرنا", "import": " ۔ﮟﯾﺮﮐ ﺪﻣﺁﺭﺩ", "importNFTs": "NFTs ۔ﮟﯾﺮﮐ ﺪﻣﺁﺭﺩ", diff --git a/res/values/strings_vi.arb b/res/values/strings_vi.arb index 61c91daf60..604bf64f9c 100644 --- a/res/values/strings_vi.arb +++ b/res/values/strings_vi.arb @@ -354,6 +354,7 @@ "how_to_use": "Cách sử dụng", "how_to_use_card": "Cách sử dụng thẻ này", "id": "ID: ", + "if_you_dont_see_your_device": "Nếu bạn không thấy thiết bị của mình ở trên, xin hãy chắc chắn rằng sổ cái của bạn đã tỉnh táo và mở khóa!", "ignor": "Bỏ qua", "import": "Nhập", "importNFTs": "Nhập NFT", diff --git a/res/values/strings_yo.arb b/res/values/strings_yo.arb index f710878d98..f0fb65a50a 100644 --- a/res/values/strings_yo.arb +++ b/res/values/strings_yo.arb @@ -356,6 +356,7 @@ "how_to_use": "Bawo ni lati lo", "how_to_use_card": "Báyìí ni wọ́n ṣe ń lo káàdì yìí.", "id": "Àmì Ìdánimọ̀: ", + "if_you_dont_see_your_device": "Ti o ko ba ri ẹrọ rẹ loke, jọwọ rii daju pe a le jiji rẹ ati ṣiṣi!", "ignor": "Ṣàìfiyèsí", "import": "gbe wọle", "importNFTs": "Gbe awọn NFT wọle", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index d430564142..a382ac84a5 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -355,6 +355,7 @@ "how_to_use": "如何使用", "how_to_use_card": "如何使用这张卡", "id": "ID: ", + "if_you_dont_see_your_device": "如果您在上面看不到设备,请确保您的分类帐已经清醒并解锁!", "ignor": "忽视", "import": "进口", "importNFTs": "导入 NFT",