From 891622c06c1bfcc172a4148f93560ec0e2c8b7de Mon Sep 17 00:00:00 2001 From: nicolas-meilan Date: Mon, 23 Sep 2024 15:47:51 -0300 Subject: [PATCH] fix Ledger hid - Fix error on hw usb connection - Add timer to dispatch error by time https://github.com/LedgerHQ/ledger-live/issues/7786 --- .../@ledgerhq/react-native-hid+6.32.3.patch | 38 +++++++++++++++++++ src/web3/wallet/wallet.ts | 25 +++++++----- 2 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 patches/@ledgerhq/react-native-hid+6.32.3.patch diff --git a/patches/@ledgerhq/react-native-hid+6.32.3.patch b/patches/@ledgerhq/react-native-hid+6.32.3.patch new file mode 100644 index 0000000..74f988f --- /dev/null +++ b/patches/@ledgerhq/react-native-hid+6.32.3.patch @@ -0,0 +1,38 @@ +diff --git a/node_modules/@ledgerhq/react-native-hid/android/src/main/java/com/ledgerwallet/hid/ReactHIDModule.java b/node_modules/@ledgerhq/react-native-hid/android/src/main/java/com/ledgerwallet/hid/ReactHIDModule.java +index 349bf3982c..7ead607ea7 100755 +--- a/node_modules/@ledgerhq/react-native-hid/android/src/main/java/com/ledgerwallet/hid/ReactHIDModule.java ++++ b/node_modules/@ledgerhq/react-native-hid/android/src/main/java/com/ledgerwallet/hid/ReactHIDModule.java +@@ -7,6 +7,7 @@ import android.content.Intent; + import android.content.IntentFilter; + import android.hardware.usb.UsbDevice; + import android.hardware.usb.UsbManager; ++import android.os.Build; + + import androidx.annotation.NonNull; + +@@ -58,7 +59,11 @@ public class ReactHIDModule extends ReactContextBaseJavaModule { + .emit(event, buildMapFromDevice(device)); + } + }; +- getReactApplicationContext().registerReceiver(receiver, filter); ++ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { ++ getReactApplicationContext().registerReceiver(receiver, filter, Context.RECEIVER_NOT_EXPORTED); ++ } else { ++ getReactApplicationContext().registerReceiver(receiver, filter); ++ } + } + + private WritableMap buildMapFromDevice(UsbDevice device) { +@@ -213,7 +218,11 @@ public class ReactHIDModule extends ReactContextBaseJavaModule { + unregisterReceiver(this); + } + }; +- getReactApplicationContext().registerReceiver(receiver, intFilter); ++ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { ++ getReactApplicationContext().registerReceiver(receiver, intFilter, Context.RECEIVER_NOT_EXPORTED); ++ } else { ++ getReactApplicationContext().registerReceiver(receiver, intFilter); ++ } + } + + private void unregisterReceiver(BroadcastReceiver receiver) { diff --git a/src/web3/wallet/wallet.ts b/src/web3/wallet/wallet.ts index c64d817..9919379 100644 --- a/src/web3/wallet/wallet.ts +++ b/src/web3/wallet/wallet.ts @@ -22,6 +22,7 @@ import { isBeEnabled, BE_DISABLED, } from '@system/bluetooth'; +import { delay } from '@utils/time'; import { erc20BlockchainsConfigurationPropagation } from '@utils/web3'; // export const BTC_DERIVATION_PATH = "m/44'/0'/0'/0"; // m/purpose'/coin_type'/account'/change/index @@ -30,7 +31,8 @@ export const BASE_ADDRESS_INDEX = 0; const SEED_24_WORDS_STRENGTH = 256; const SEED_12_WORDS_STRENGTH = 128; -const HW_BLUETOOTH_MAX_TIME = 15000; +const HW_BLUETOOTH_MAX_TIME = 15; +const HW_USB_MAX_TIME = 5; type BlockchainWalletConfig = { [blockchain in Blockchains]: { @@ -176,33 +178,38 @@ const getBluetoothHw = async () => { } }, }); - - const timeRef = setTimeout(() => { + delay(HW_BLUETOOTH_MAX_TIME).then(() => { if (procesingConnection) { timeExceeded = true; - clearTimeout(timeRef); return; } try { suscription.unsubscribe(); } catch (error) { } - clearTimeout(timeRef); resolve(null); - }, HW_BLUETOOTH_MAX_TIME); + }); }); return [selectedHw]; }; +const usbHwTimerErrorHandler = async (): Promise => { + await delay(HW_USB_MAX_TIME); + + return new Promise((_, reject) => reject(HW_USB_MAX_TIME)); +}; + export const connectHw = async (bluetoothConnection: boolean = false): Promise => { const transportToUse = bluetoothConnection ? TransportBLE : TransportHID; const [firstHw] = await (bluetoothConnection ? getBluetoothHw() : transportToUse.list()); if (!firstHw) throw new Error(NO_LEDGER_CONNECTED_ERROR); - let transport = null; + let transport: TransportBLE | TransportHID | null = null; try { - transport = await transportToUse.open(firstHw); + transport = await (bluetoothConnection + ? transportToUse.open(firstHw) + : Promise.race([transportToUse.open(firstHw), usbHwTimerErrorHandler()])); } catch (_) { // Retry connection one time try { transport = await transportToUse.open(firstHw); @@ -231,7 +238,7 @@ export const getHwWalletAddress = async ( const walletIndex = (index || BASE_ADDRESS_INDEX) > 0 ? index : 0; const derivationPath = `${walletConfig.derivationPath}/${walletIndex}`; const transport = await connectHw(bluetoothConnection); - + try { const ledgerApp = new (walletConfig.ledgerApp)(transport); const { address } = await ledgerApp.getAddress(derivationPath, true);