Skip to content

Commit

Permalink
feat: ledger firmware upgrade alert (#276)
Browse files Browse the repository at this point in the history
* feat: init

* fix: alert
  • Loading branch information
heisenberg-2077 authored Jun 5, 2024
1 parent e398d6b commit cf8f912
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 8 deletions.
9 changes: 8 additions & 1 deletion apps/mobile/src/assets/locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,8 @@
"ethereum_app_not_installed_error": "Please install the Ethereum app on your Ledger device.",
"ethereum_app_unconfirmed_error": "You have denied the request to open the Ethereum app.",
"ethereum_app_open_error": "Please install/accept Ethereum app on your Ledger device.",
"running_app_close_error": "Failed to close the running app on your Ledger device."
"running_app_close_error": "Failed to close the running app on your Ledger device.",
"firmwareOrAppUpdateRequired": "Please update the firmware and Ethereum App on your Ledger"
},
"openEthApp": {
"title": "Connect Ledger",
Expand Down Expand Up @@ -2113,6 +2114,12 @@
"message": "Rabby Wallet uses bluetooth access to connect Ledger",
"open_settings": "OK",
"cancel": "Don't Allow"
},
"update_firmware_alert": {
"title": "Ledger Firmware Outdated",
"message": "Check out how to update Ledger firmware from Ledger support",
"update": "Update",
"cancel": "Cancel"
}
}
}
10 changes: 8 additions & 2 deletions apps/mobile/src/components/ConnectLedger/ConnectLedger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,18 @@ export const ConnectLedger: React.FC<{
});
} catch (err: any) {
// maybe session is disconnect, just try to reconnect
if (loopCountRef.current < 3) {
if (!err.message && loopCountRef.current < 3) {
loopCountRef.current++;
console.log('checkEthApp isConnected error', err);
return await checkEthApp();
}
toast.show(t('page.newAddress.ledger.error.lockedOrNoEthApp'));

if (err.message !== LEDGER_ERROR_CODES.FIRMWARE_OR_APP_UPDATE_REQUIRED) {
toast.show(
err.message || t('page.newAddress.ledger.error.lockedOrNoEthApp'),
);
}

setCurrentScreen('select');
console.error('checkEthApp', err);
throw err;
Expand Down
12 changes: 12 additions & 0 deletions apps/mobile/src/core/apis/ledger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import TransportBLE from '@ledgerhq/react-native-hw-transport-ble';
import { LedgerHDPathType } from '@rabby-wallet/eth-keyring-ledger/dist/utils';
import PQueue from 'p-queue/dist/index';
import { t } from 'i18next';
import { ledgerErrorHandler, LEDGER_ERROR_CODES } from '@/hooks/ledger/error';
import { UpdateFirmwareAlert } from '@/utils/bluetoothPermissions';

let queue: PQueue;
setTimeout(() => {
Expand Down Expand Up @@ -151,6 +153,16 @@ export async function importFirstAddress({
export async function checkEthApp(cb: (result: boolean) => void) {
const keyring = await getKeyring<LedgerKeyring>(KEYRING_TYPE.LedgerKeyring);

try {
await keyring.makeApp();
} catch (e: any) {
const message = ledgerErrorHandler(e);

if (message === LEDGER_ERROR_CODES.FIRMWARE_OR_APP_UPDATE_REQUIRED) {
UpdateFirmwareAlert();
throw new Error(message);
}
}
const { appName } = await keyring.getAppAndVersion();

if (appName === 'BOLOS') {
Expand Down
4 changes: 4 additions & 0 deletions apps/mobile/src/hooks/ledger/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export enum LEDGER_ERROR_CODES {
UNKNOWN = 'unknown',
DISCONNECTED = 'disconnected',
LOCKED_OR_NO_ETH_APP = 'locked_or_no_eth_app',
FIRMWARE_OR_APP_UPDATE_REQUIRED = 'firmware_or_app_update_required',
}

/**
Expand All @@ -16,6 +17,9 @@ export const ledgerErrorHandler = (error: Error) => {
if (!error.message) {
return LEDGER_ERROR_CODES.UNKNOWN;
}
if (error.message.includes('0x6b00') || error.message.includes('0x6e00')) {
return LEDGER_ERROR_CODES.FIRMWARE_OR_APP_UPDATE_REQUIRED;
}
if (error.message.includes('0x650f')) {
return LEDGER_ERROR_CODES.LOCKED_OR_NO_ETH_APP;
}
Expand Down
22 changes: 22 additions & 0 deletions apps/mobile/src/utils/bluetoothPermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,28 @@ export const showBluetoothPermissionsAlert = async () => {
);
};

export const UpdateFirmwareAlert = async () => {
Alert.alert(
i18n.t('bluetooth.update_firmware_alert.title'),
i18n.t('bluetooth.update_firmware_alert.message'),
[
{
onPress: () => {
Linking.openURL(
'https://support.ledger.com/hc/articles/360003117594-Ledger-device-firmware-update-FAQ',
);
},
text: i18n.t('bluetooth.update_firmware_alert.update'),
},
{
onPress: () => null,
style: 'cancel',
text: i18n.t('bluetooth.update_firmware_alert.cancel'),
},
],
);
};

/**
* Checks and requests bluetooth permissions for Android
*/
Expand Down
6 changes: 1 addition & 5 deletions packages/eth-keyring-ledger/src/LedgerKeyring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,7 @@ class LedgerKeyring {
this.transport = await this.getTransport(this.deviceId!);
this.app = new LedgerEth(this.transport);
} catch (e: any) {
if (
e.name === 'BleError' ||
e.message?.includes('isConnected') ||
e.message?.includes('DisconnectedDevice')
) {
if (this.transportType === 'ble') {
throw e;
} else if (!e.message?.includes('The device is already open')) {
console.error(e);
Expand Down

0 comments on commit cf8f912

Please sign in to comment.