2021-10-21 21:17:03 +02:00
|
|
|
import React, { useEffect } from 'react';
|
|
|
|
import { useDispatch, useSelector } from 'react-redux';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import {
|
2023-01-20 16:14:40 +01:00
|
|
|
LedgerTransportTypes,
|
|
|
|
WebHIDConnectedStatuses,
|
|
|
|
HardwareTransportStates,
|
2021-10-21 21:17:03 +02:00
|
|
|
LEDGER_USB_VENDOR_ID,
|
|
|
|
} from '../../../../shared/constants/hardware-wallets';
|
|
|
|
import {
|
|
|
|
PLATFORM_FIREFOX,
|
|
|
|
ENVIRONMENT_TYPE_FULLSCREEN,
|
|
|
|
} from '../../../../shared/constants/app';
|
|
|
|
|
|
|
|
import {
|
|
|
|
setLedgerWebHidConnectedStatus,
|
|
|
|
getLedgerWebHidConnectedStatus,
|
2021-11-04 19:19:53 +01:00
|
|
|
setLedgerTransportStatus,
|
|
|
|
getLedgerTransportStatus,
|
2021-10-21 21:17:03 +02:00
|
|
|
} from '../../../ducks/app/app';
|
|
|
|
|
|
|
|
import Typography from '../../ui/typography/typography';
|
|
|
|
import Button from '../../ui/button';
|
|
|
|
import { useI18nContext } from '../../../hooks/useI18nContext';
|
|
|
|
import {
|
|
|
|
COLORS,
|
|
|
|
FONT_WEIGHT,
|
|
|
|
TYPOGRAPHY,
|
|
|
|
} from '../../../helpers/constants/design-system';
|
|
|
|
import Dialog from '../../ui/dialog';
|
|
|
|
import {
|
|
|
|
getPlatform,
|
|
|
|
getEnvironmentType,
|
|
|
|
} from '../../../../app/scripts/lib/util';
|
|
|
|
import { getLedgerTransportType } from '../../../ducks/metamask/metamask';
|
2021-11-04 19:19:53 +01:00
|
|
|
import { attemptLedgerTransportCreation } from '../../../store/actions';
|
2021-10-21 21:17:03 +02:00
|
|
|
|
2022-03-23 19:54:01 +01:00
|
|
|
const renderInstructionStep = (
|
|
|
|
text,
|
|
|
|
show = true,
|
2022-05-10 19:28:30 +02:00
|
|
|
color = COLORS.TEXT_DEFAULT,
|
2022-03-23 19:54:01 +01:00
|
|
|
) => {
|
2021-10-21 21:17:03 +02:00
|
|
|
return (
|
|
|
|
show && (
|
|
|
|
<Typography
|
|
|
|
boxProps={{ margin: 0 }}
|
|
|
|
color={color}
|
|
|
|
fontWeight={FONT_WEIGHT.BOLD}
|
|
|
|
variant={TYPOGRAPHY.H7}
|
|
|
|
>
|
|
|
|
{text}
|
|
|
|
</Typography>
|
|
|
|
)
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default function LedgerInstructionField({ showDataInstruction }) {
|
|
|
|
const t = useI18nContext();
|
|
|
|
const dispatch = useDispatch();
|
|
|
|
|
|
|
|
const webHidConnectedStatus = useSelector(getLedgerWebHidConnectedStatus);
|
|
|
|
const ledgerTransportType = useSelector(getLedgerTransportType);
|
2021-11-04 19:19:53 +01:00
|
|
|
const transportStatus = useSelector(getLedgerTransportStatus);
|
2021-10-21 21:17:03 +02:00
|
|
|
const environmentType = getEnvironmentType();
|
|
|
|
const environmentTypeIsFullScreen =
|
|
|
|
environmentType === ENVIRONMENT_TYPE_FULLSCREEN;
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
const initialConnectedDeviceCheck = async () => {
|
|
|
|
if (
|
2023-01-20 16:14:40 +01:00
|
|
|
ledgerTransportType === LedgerTransportTypes.webhid &&
|
|
|
|
webHidConnectedStatus !== WebHIDConnectedStatuses.connected
|
2021-10-21 21:17:03 +02:00
|
|
|
) {
|
|
|
|
const devices = await window.navigator.hid.getDevices();
|
|
|
|
const webHidIsConnected = devices.some(
|
|
|
|
(device) => device.vendorId === Number(LEDGER_USB_VENDOR_ID),
|
|
|
|
);
|
|
|
|
dispatch(
|
|
|
|
setLedgerWebHidConnectedStatus(
|
|
|
|
webHidIsConnected
|
2023-01-20 16:14:40 +01:00
|
|
|
? WebHIDConnectedStatuses.connected
|
|
|
|
: WebHIDConnectedStatuses.notConnected,
|
2021-10-21 21:17:03 +02:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
2021-11-04 19:19:53 +01:00
|
|
|
const determineTransportStatus = async () => {
|
|
|
|
if (
|
2023-01-20 16:14:40 +01:00
|
|
|
ledgerTransportType === LedgerTransportTypes.webhid &&
|
|
|
|
webHidConnectedStatus === WebHIDConnectedStatuses.connected &&
|
|
|
|
transportStatus === HardwareTransportStates.none
|
2021-11-04 19:19:53 +01:00
|
|
|
) {
|
|
|
|
try {
|
|
|
|
const transportedCreated = await attemptLedgerTransportCreation();
|
|
|
|
dispatch(
|
|
|
|
setLedgerTransportStatus(
|
|
|
|
transportedCreated
|
2023-01-20 16:14:40 +01:00
|
|
|
? HardwareTransportStates.verified
|
|
|
|
: HardwareTransportStates.unknownFailure,
|
2021-11-04 19:19:53 +01:00
|
|
|
),
|
|
|
|
);
|
|
|
|
} catch (e) {
|
|
|
|
if (e.message.match('Failed to open the device')) {
|
|
|
|
dispatch(
|
2023-01-20 16:14:40 +01:00
|
|
|
setLedgerTransportStatus(
|
|
|
|
HardwareTransportStates.deviceOpenFailure,
|
|
|
|
),
|
2021-11-04 19:19:53 +01:00
|
|
|
);
|
|
|
|
} else if (e.message.match('the device is already open')) {
|
2023-01-20 16:14:40 +01:00
|
|
|
dispatch(
|
|
|
|
setLedgerTransportStatus(HardwareTransportStates.verified),
|
|
|
|
);
|
2021-11-04 19:19:53 +01:00
|
|
|
} else {
|
|
|
|
dispatch(
|
2023-01-20 16:14:40 +01:00
|
|
|
setLedgerTransportStatus(HardwareTransportStates.unknownFailure),
|
2021-11-04 19:19:53 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
determineTransportStatus();
|
2021-10-21 21:17:03 +02:00
|
|
|
initialConnectedDeviceCheck();
|
2021-11-04 19:19:53 +01:00
|
|
|
}, [dispatch, ledgerTransportType, webHidConnectedStatus, transportStatus]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
return () => {
|
2023-01-20 16:14:40 +01:00
|
|
|
dispatch(setLedgerTransportStatus(HardwareTransportStates.none));
|
2021-11-04 19:19:53 +01:00
|
|
|
};
|
|
|
|
}, [dispatch]);
|
2021-10-21 21:17:03 +02:00
|
|
|
|
2023-01-20 16:14:40 +01:00
|
|
|
const usingLedgerLive = ledgerTransportType === LedgerTransportTypes.live;
|
|
|
|
const usingWebHID = ledgerTransportType === LedgerTransportTypes.webhid;
|
2021-10-21 21:17:03 +02:00
|
|
|
|
|
|
|
const isFirefox = getPlatform() === PLATFORM_FIREFOX;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<div className="confirm-detail-row">
|
|
|
|
<Dialog type="message">
|
|
|
|
<div className="ledger-live-dialog">
|
|
|
|
{renderInstructionStep(t('ledgerConnectionInstructionHeader'))}
|
|
|
|
{renderInstructionStep(
|
|
|
|
`- ${t('ledgerConnectionInstructionStepOne')}`,
|
|
|
|
!isFirefox && usingLedgerLive,
|
|
|
|
)}
|
|
|
|
{renderInstructionStep(
|
|
|
|
`- ${t('ledgerConnectionInstructionStepTwo')}`,
|
|
|
|
!isFirefox && usingLedgerLive,
|
|
|
|
)}
|
|
|
|
{renderInstructionStep(
|
|
|
|
`- ${t('ledgerConnectionInstructionStepThree')}`,
|
|
|
|
)}
|
|
|
|
{renderInstructionStep(
|
|
|
|
`- ${t('ledgerConnectionInstructionStepFour')}`,
|
|
|
|
showDataInstruction,
|
|
|
|
)}
|
2021-11-04 19:19:53 +01:00
|
|
|
{renderInstructionStep(
|
|
|
|
<span>
|
|
|
|
<Button
|
|
|
|
type="link"
|
|
|
|
onClick={async () => {
|
|
|
|
if (environmentTypeIsFullScreen) {
|
|
|
|
window.location.reload();
|
|
|
|
} else {
|
|
|
|
global.platform.openExtensionInBrowser(null, null, true);
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{t('ledgerConnectionInstructionCloseOtherApps')}
|
|
|
|
</Button>
|
|
|
|
</span>,
|
2023-01-20 16:14:40 +01:00
|
|
|
transportStatus === HardwareTransportStates.deviceOpenFailure,
|
2021-11-04 19:19:53 +01:00
|
|
|
)}
|
2021-10-21 21:17:03 +02:00
|
|
|
{renderInstructionStep(
|
|
|
|
<span>
|
|
|
|
<Button
|
|
|
|
type="link"
|
|
|
|
onClick={async () => {
|
|
|
|
if (environmentTypeIsFullScreen) {
|
2022-07-31 20:26:40 +02:00
|
|
|
const connectedDevices =
|
|
|
|
await window.navigator.hid.requestDevice({
|
2021-10-21 21:17:03 +02:00
|
|
|
filters: [{ vendorId: LEDGER_USB_VENDOR_ID }],
|
2022-07-31 20:26:40 +02:00
|
|
|
});
|
2021-10-21 21:17:03 +02:00
|
|
|
const webHidIsConnected = connectedDevices.some(
|
|
|
|
(device) =>
|
|
|
|
device.vendorId === Number(LEDGER_USB_VENDOR_ID),
|
|
|
|
);
|
|
|
|
dispatch(
|
|
|
|
setLedgerWebHidConnectedStatus({
|
|
|
|
webHidConnectedStatus: webHidIsConnected
|
2023-01-20 16:14:40 +01:00
|
|
|
? WebHIDConnectedStatuses.connected
|
|
|
|
: WebHIDConnectedStatuses.notConnected,
|
2021-10-21 21:17:03 +02:00
|
|
|
}),
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
global.platform.openExtensionInBrowser(null, null, true);
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{environmentTypeIsFullScreen
|
|
|
|
? t('clickToConnectLedgerViaWebHID')
|
|
|
|
: t('openFullScreenForLedgerWebHid')}
|
|
|
|
</Button>
|
|
|
|
</span>,
|
|
|
|
usingWebHID &&
|
2023-01-20 16:14:40 +01:00
|
|
|
webHidConnectedStatus === WebHIDConnectedStatuses.notConnected,
|
2022-08-13 00:14:59 +02:00
|
|
|
COLORS.WARNING_DEFAULT,
|
2021-10-21 21:17:03 +02:00
|
|
|
)}
|
|
|
|
</div>
|
|
|
|
</Dialog>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
LedgerInstructionField.propTypes = {
|
|
|
|
showDataInstruction: PropTypes.bool,
|
|
|
|
};
|