Check if ledger was successfully able to establish transport on confirm screen mount (#12535)

* Check if ledger was successfully able to establish transport on mount of confirm screens

* Update ledger message/action if transport creation was blocked by existing connection

* TEMP: point eth-ledger-bridge-keyring to commite, REMOVE BEFORE MERGE

* Update eth-ledger-bridge-keyring to v0.10.0
feature/default_network_editable
Dan J Miller 3 years ago committed by ryanml
parent 3f3ee7e51f
commit 10bec23ee9
  1. 3
      app/_locales/en/messages.json
  2. 9
      app/scripts/metamask-controller.js
  3. 2
      package.json
  4. 7
      shared/constants/hardware-wallets.js
  5. 61
      ui/components/app/ledger-instruction-field/ledger-instruction-field.js
  6. 20
      ui/ducks/app/app.js
  7. 13
      ui/selectors/selectors.js
  8. 1
      ui/store/actionConstants.js
  9. 4
      ui/store/actions.js
  10. 8
      yarn.lock

@ -1255,6 +1255,9 @@
"ledgerAccountRestriction": {
"message": "You need to make use your last account before you can add a new one."
},
"ledgerConnectionInstructionCloseOtherApps": {
"message": "Close any other software connected to your device and then click here to refresh."
},
"ledgerConnectionInstructionHeader": {
"message": "Prior to clicking confirm:"
},

@ -845,6 +845,10 @@ export default class MetamaskController extends EventEmitter {
this.setLedgerTransportPreference,
this,
),
attemptLedgerTransportCreation: nodeify(
this.attemptLedgerTransportCreation,
this,
),
// mobile
fetchInfoToSync: nodeify(this.fetchInfoToSync, this),
@ -1556,6 +1560,11 @@ export default class MetamaskController extends EventEmitter {
return keyring;
}
async attemptLedgerTransportCreation() {
const keyring = await this.getKeyringForDevice('ledger');
return await keyring.attemptMakeApp();
}
/**
* Fetch account list from a trezor device.
*

@ -105,7 +105,7 @@
"@material-ui/core": "^4.11.0",
"@metamask/contract-metadata": "^1.28.0",
"@metamask/controllers": "^17.0.0",
"@metamask/eth-ledger-bridge-keyring": "^0.9.0",
"@metamask/eth-ledger-bridge-keyring": "^0.10.0",
"@metamask/eth-token-tracker": "^3.0.1",
"@metamask/etherscan-link": "^2.1.0",
"@metamask/jazzicon": "^2.0.0",

@ -24,3 +24,10 @@ export const WEBHID_CONNECTED_STATUSES = {
NOT_CONNECTED: 'notConnected',
UNKNOWN: 'unknown',
};
export const TRANSPORT_STATES = {
NONE: 'NONE',
VERIFIED: 'VERIFIED',
DEVICE_OPEN_FAILURE: 'DEVICE_OPEN_FAILURE',
UNKNOWN_FAILURE: 'UNKNOWN_FAILURE',
};

@ -5,6 +5,7 @@ import {
LEDGER_TRANSPORT_TYPES,
LEDGER_USB_VENDOR_ID,
WEBHID_CONNECTED_STATUSES,
TRANSPORT_STATES,
} from '../../../../shared/constants/hardware-wallets';
import {
PLATFORM_FIREFOX,
@ -14,6 +15,8 @@ import {
import {
setLedgerWebHidConnectedStatus,
getLedgerWebHidConnectedStatus,
setLedgerTransportStatus,
getLedgerTransportStatus,
} from '../../../ducks/app/app';
import Typography from '../../ui/typography/typography';
@ -30,6 +33,7 @@ import {
getEnvironmentType,
} from '../../../../app/scripts/lib/util';
import { getLedgerTransportType } from '../../../ducks/metamask/metamask';
import { attemptLedgerTransportCreation } from '../../../store/actions';
const renderInstructionStep = (text, show = true, color = COLORS.PRIMARY3) => {
return (
@ -52,6 +56,7 @@ export default function LedgerInstructionField({ showDataInstruction }) {
const webHidConnectedStatus = useSelector(getLedgerWebHidConnectedStatus);
const ledgerTransportType = useSelector(getLedgerTransportType);
const transportStatus = useSelector(getLedgerTransportStatus);
const environmentType = getEnvironmentType();
const environmentTypeIsFullScreen =
environmentType === ENVIRONMENT_TYPE_FULLSCREEN;
@ -75,8 +80,45 @@ export default function LedgerInstructionField({ showDataInstruction }) {
);
}
};
const determineTransportStatus = async () => {
if (
ledgerTransportType === LEDGER_TRANSPORT_TYPES.WEBHID &&
webHidConnectedStatus === WEBHID_CONNECTED_STATUSES.CONNECTED &&
transportStatus === TRANSPORT_STATES.NONE
) {
try {
const transportedCreated = await attemptLedgerTransportCreation();
dispatch(
setLedgerTransportStatus(
transportedCreated
? TRANSPORT_STATES.VERIFIED
: TRANSPORT_STATES.UNKNOWN_FAILURE,
),
);
} catch (e) {
if (e.message.match('Failed to open the device')) {
dispatch(
setLedgerTransportStatus(TRANSPORT_STATES.DEVICE_OPEN_FAILURE),
);
} else if (e.message.match('the device is already open')) {
dispatch(setLedgerTransportStatus(TRANSPORT_STATES.VERIFIED));
} else {
dispatch(
setLedgerTransportStatus(TRANSPORT_STATES.UNKNOWN_FAILURE),
);
}
}
}
};
determineTransportStatus();
initialConnectedDeviceCheck();
}, [dispatch, ledgerTransportType, webHidConnectedStatus]);
}, [dispatch, ledgerTransportType, webHidConnectedStatus, transportStatus]);
useEffect(() => {
return () => {
dispatch(setLedgerTransportStatus(TRANSPORT_STATES.NONE));
};
}, [dispatch]);
const usingLedgerLive = ledgerTransportType === LEDGER_TRANSPORT_TYPES.LIVE;
const usingWebHID = ledgerTransportType === LEDGER_TRANSPORT_TYPES.WEBHID;
@ -104,6 +146,23 @@ export default function LedgerInstructionField({ showDataInstruction }) {
`- ${t('ledgerConnectionInstructionStepFour')}`,
showDataInstruction,
)}
{renderInstructionStep(
<span>
<Button
type="link"
onClick={async () => {
if (environmentTypeIsFullScreen) {
window.location.reload();
} else {
global.platform.openExtensionInBrowser(null, null, true);
}
}}
>
{t('ledgerConnectionInstructionCloseOtherApps')}
</Button>
</span>,
transportStatus === TRANSPORT_STATES.DEVICE_OPEN_FAILURE,
)}
{renderInstructionStep(
<span>
<Button

@ -1,4 +1,7 @@
import { WEBHID_CONNECTED_STATUSES } from '../../../shared/constants/hardware-wallets';
import {
WEBHID_CONNECTED_STATUSES,
TRANSPORT_STATES,
} from '../../../shared/constants/hardware-wallets';
import * as actionConstants from '../../store/actionConstants';
// actionConstants
@ -50,6 +53,7 @@ export default function reduceApp(state = {}, action) {
},
gasLoadingAnimationIsShowing: false,
ledgerWebHidConnectedStatus: WEBHID_CONNECTED_STATUSES.UNKNOWN,
ledgerTransportStatus: TRANSPORT_STATES.NONE,
...state,
};
@ -348,6 +352,12 @@ export default function reduceApp(state = {}, action) {
ledgerWebHidConnectedStatus: action.value,
};
case actionConstants.SET_LEDGER_TRANSPORT_STATUS:
return {
...appState,
ledgerTransportStatus: action.value,
};
default:
return appState;
}
@ -375,6 +385,10 @@ export function setLedgerWebHidConnectedStatus(value) {
return { type: actionConstants.SET_WEBHID_CONNECTED_STATUS, value };
}
export function setLedgerTransportStatus(value) {
return { type: actionConstants.SET_LEDGER_TRANSPORT_STATUS, value };
}
// Selectors
export function getQrCodeData(state) {
return state.appState.qrCodeData;
@ -387,3 +401,7 @@ export function getGasLoadingAnimationIsShowing(state) {
export function getLedgerWebHidConnectedStatus(state) {
return state.appState.ledgerWebHidConnectedStatus;
}
export function getLedgerTransportStatus(state) {
return state.appState.ledgerTransportStatus;
}

@ -10,6 +10,7 @@ import {
KEYRING_TYPES,
WEBHID_CONNECTED_STATUSES,
LEDGER_TRANSPORT_TYPES,
TRANSPORT_STATES,
} from '../../shared/constants/hardware-wallets';
import {
@ -42,7 +43,10 @@ import {
isAddressLedger,
findKeyringForAddress,
} from '../ducks/metamask/metamask';
import { getLedgerWebHidConnectedStatus } from '../ducks/app/app';
import {
getLedgerWebHidConnectedStatus,
getLedgerTransportStatus,
} from '../ducks/app/app';
/**
* One of the only remaining valid uses of selecting the network subkey of the
@ -657,8 +661,13 @@ export function doesAddressRequireLedgerHidConnection(state, address) {
const webHidIsNotConnected =
getLedgerWebHidConnectedStatus(state) !==
WEBHID_CONNECTED_STATUSES.CONNECTED;
const ledgerTransportStatus = getLedgerTransportStatus(state);
const transportIsNotSuccessfullyCreated =
ledgerTransportStatus !== TRANSPORT_STATES.VERIFIED;
return (
addressIsLedger && transportTypePreferenceIsWebHID && webHidIsNotConnected
addressIsLedger &&
transportTypePreferenceIsWebHID &&
(webHidIsNotConnected || transportIsNotSuccessfullyCreated)
);
}

@ -80,6 +80,7 @@ export const SET_MOUSE_USER_STATE = 'SET_MOUSE_USER_STATE';
// Ledger
export const SET_WEBHID_CONNECTED_STATUS = 'SET_WEBHID_CONNECTED_STATUS';
export const SET_LEDGER_TRANSPORT_STATUS = 'SET_LEDGER_TRANSPORT_STATUS';
// Network
export const SET_PENDING_TOKENS = 'SET_PENDING_TOKENS';

@ -2770,6 +2770,10 @@ export function setLedgerLivePreference(value) {
};
}
export async function attemptLedgerTransportCreation() {
return await promisifiedBackground.attemptLedgerTransportCreation();
}
export function captureSingleException(error) {
return async (dispatch, getState) => {
const { singleExceptions } = getState().appState;

@ -2821,10 +2821,10 @@
resolved "https://registry.yarnpkg.com/@metamask/eslint-config/-/eslint-config-6.0.0.tgz#ec53e8ab278073e882411ed89705bc7d06b78c81"
integrity sha512-LyakGYGwM8UQOGhwWa+5erAI1hXuiTgf/y7USzOomX6H9KiuY09IAUYnPh7ToPG2sedD2F48UF1bUm8yvCoZOw==
"@metamask/eth-ledger-bridge-keyring@^0.9.0":
version "0.9.0"
resolved "https://registry.yarnpkg.com/@metamask/eth-ledger-bridge-keyring/-/eth-ledger-bridge-keyring-0.9.0.tgz#42e98e7dfeaaa08e7c9ceff261facddd7320df80"
integrity sha512-EuNKvodbdJxQPzr+zAE5TE1iKUzuIRWKeVaYoYwpi18RjjtSQMKmZcb3VXY8hmQu+Fj4Ld/ujj22qSYjYAjtPg==
"@metamask/eth-ledger-bridge-keyring@^0.10.0":
version "0.10.0"
resolved "https://registry.yarnpkg.com/@metamask/eth-ledger-bridge-keyring/-/eth-ledger-bridge-keyring-0.10.0.tgz#9d5103be22221f4ef71393a2e11f24b788e343a5"
integrity sha512-ewcnEFmIL2lkUta811yQeJVWhTjll9U62GdbuauvxdQ0c6VBGZnf02GU3gcxyMOcEvZBnlU+d5LWpURQA8iNZQ==
dependencies:
"@ethereumjs/tx" "^3.2.0"
eth-sig-util "^2.0.0"

Loading…
Cancel
Save