Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: native dApp support [LIVE-9527] #6328

Merged
merged 46 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
b3d28c9
feat: native dapp integration wip
Justkant Feb 28, 2024
c911b68
fix: LLD add jsonrpc field when sending message to dapp
Justkant Feb 29, 2024
fa8711d
feat: add account selector for dapp on webview
Justkant Feb 29, 2024
3f37b9e
refactor: move logic to LLC and fix mobile injected code
Justkant Mar 1, 2024
d4f0e0f
store selected account in store
Wozacosta Mar 1, 2024
cccdb4d
comment about limited usefulness of manifestToCurrentAccountMap
Wozacosta Mar 1, 2024
f1b432d
pass currentAccountId to dapp browser as url param
Wozacosta Mar 4, 2024
a170054
hide topbar search account item if not dapp
Wozacosta Mar 4, 2024
736475d
derive currentnetwork from currentaccount, remove passing accountid a…
Wozacosta Mar 5, 2024
7bb3b55
feat: add mobile webview select account button
Justkant Mar 5, 2024
6d483d6
refactor: remove unneeded code
Justkant Mar 5, 2024
66c9cc9
fix: correct account and parentAccount usage
Justkant Mar 5, 2024
a24822a
refactor: move dapp injected code to another file
Justkant Mar 5, 2024
e6a0914
fix(LLM): only inject provider if dapp in the manifest
Justkant Mar 5, 2024
2a91101
accountsChanged bug fix
Wozacosta Mar 5, 2024
b623825
refactor: remove unused code
Justkant Mar 5, 2024
2a4211b
chore: remove unneeded comment
Justkant Mar 5, 2024
8d58709
separate preloader for dapp
Wozacosta Mar 6, 2024
49ec98f
fix logic of current account if set manually
Wozacosta Mar 6, 2024
494e9a5
save currentaccounthistatom in storage
Wozacosta Mar 6, 2024
0100275
clearer name of local storage key
Wozacosta Mar 6, 2024
06d3fa8
refactor: move dapp logic to separate file
Justkant Mar 7, 2024
1dbf3fc
refactor: share currency hook for LLD and LLM
Justkant Mar 8, 2024
dec449e
store current account with usedb
Wozacosta Mar 6, 2024
fb8211e
refactor: share LLEthereumProvider between LLD and LLM with a bundle
Justkant Mar 8, 2024
09ccfff
feat: add ws support
Justkant Mar 8, 2024
02a7689
lld no accounts handling
Wozacosta Mar 11, 2024
6f476d5
optional access to histdb
Wozacosta Mar 11, 2024
e748d1b
handle no accounts screen mobile
Wozacosta Mar 11, 2024
589d175
missing noaccountscreen file for mobile
Wozacosta Mar 12, 2024
cd525a0
use data uri with png logo
Wozacosta Mar 12, 2024
6828c3c
missing noaccounts returned from usedapp
Wozacosta Mar 12, 2024
39471dd
remove useless currentaccount in web3appwebview context
Wozacosta Mar 12, 2024
7019d20
fix types
Wozacosta Mar 12, 2024
6d7b5a2
fix account names not displayed on mobile
Wozacosta Mar 12, 2024
40b5e88
feat: enable navigation if in dapp manifest
Justkant Mar 15, 2024
9c92de7
fix: android
Justkant Mar 15, 2024
30dc387
feat: add provider field in dapp manifest type
Justkant Mar 15, 2024
be8d0f4
chore: fix lint and unimported issues
Justkant Mar 26, 2024
9b54d0d
chore: add changeset
Justkant Mar 26, 2024
b868777
chore: update the changeset description and title
Justkant Mar 26, 2024
c3d27f4
refactor: move functions to helper file
Justkant Mar 29, 2024
24a9278
refactor: rename generic type name
Justkant Mar 29, 2024
e0799ce
refactor: following review comments
Justkant Apr 2, 2024
4ba28a3
chore: remove the accounts from the useEffect deps
Justkant Apr 2, 2024
2b93b13
test: add basic dapp test
Justkant Apr 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/swift-apricots-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@actions/build-checks": minor
"ledger-live-desktop": minor
"live-mobile": minor
"@ledgerhq/live-common": minor
"@ledgerhq/ethereum-provider": minor
---

feat: native dapp support [LIVE-9527]

Migration from [ETH dApp Browser Live App](https://github.com/LedgerHQ/eth-dapp-browser) and [iframe-provider](https://github.com/LedgerHQ/iframe-provider) to support inside LL directly injecting an EIP 6963 compatible provider in the WebView, using params from the manifest.
1 change: 1 addition & 0 deletions apps/ledger-live-desktop/.unimportedrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"src/renderer/index.ts",
"src/preloader/index.ts",
"src/renderer/webworkers/workers/*.ts",
"src/webviewPreloader/dappPreloader.ts",
"src/webviewPreloader/index.ts"
],
"extensions": [".ts", ".js", ".jsx", ".tsx"],
Expand Down
1 change: 1 addition & 0 deletions apps/ledger-live-desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
"@ledgerhq/devices": "workspace:^",
"@ledgerhq/domain-service": "workspace:^",
"@ledgerhq/errors": "workspace:^",
"@ledgerhq/ethereum-provider": "workspace:^",
"@ledgerhq/hw-transport": "workspace:^",
"@ledgerhq/hw-transport-http": "workspace:^",
"@ledgerhq/hw-transport-node-hid-singleton": "workspace:^",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class OperationsList extends PureComponent<Props, State> {
setDrawer(OperationDetails, {
operationId: operation.id,
accountId: account.id,
parentId: parentAccount?.id as string | undefined | null,
parentId: parentAccount?.id,
});

// TODO: convert of async/await if fetching with the api
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import { getCurrentDevice } from "~/renderer/reducers/devices";
import Success from "./Success";
import Searching from "./Searching";
import { useOnboardingStatePolling } from "@ledgerhq/live-common/onboarding/hooks/useOnboardingStatePolling";
import LockedDeviceDrawer, {
Props as LockedDeviceDrawerProps,
} from "~/renderer/components/SyncOnboarding/Manual/LockedDeviceDrawer";
import LockedDeviceDrawer from "~/renderer/components/SyncOnboarding/Manual/LockedDeviceDrawer";
import { setDrawer } from "~/renderer/drawers/Provider";

export type SyncOnboardingDeviceConnectionProps = {
Expand Down Expand Up @@ -48,13 +46,16 @@ const SyncOnboardingDeviceConnection = ({

useEffect(() => {
if (lockedDevice && currentDevice) {
const props: LockedDeviceDrawerProps = {
deviceModelId,
};
setDrawer(LockedDeviceDrawer, props, {
forceDisableFocusTrap: true,
preventBackdropClick: true,
});
setDrawer(
LockedDeviceDrawer,
{
deviceModelId,
},
{
forceDisableFocusTrap: true,
preventBackdropClick: true,
},
);
} else {
setDrawer();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,17 @@ import manager from "@ledgerhq/live-common/manager/index";
import { useGenuineCheck } from "@ledgerhq/live-common/hw/hooks/useGenuineCheck";
import { useGetLatestAvailableFirmware } from "@ledgerhq/live-common/deviceSDK/hooks/useGetLatestAvailableFirmware";
import Body from "./Body";
import TroubleshootingDrawer, {
Props as TroubleshootingDrawerProps,
} from "../TroubleshootingDrawer";
import SoftwareCheckAllowSecureChannelDrawer, {
Props as SoftwareCheckAllowSecureChannelDrawerProps,
} from "./SoftwareCheckAllowSecureChannelDrawer";
import TroubleshootingDrawer from "../TroubleshootingDrawer";
import SoftwareCheckAllowSecureChannelDrawer from "./SoftwareCheckAllowSecureChannelDrawer";
import { Status as SoftwareCheckStatus } from "../types";
import { getDeviceModel, DeviceModelId } from "@ledgerhq/devices";
import { openURL } from "~/renderer/linking";
import { setDrawer } from "~/renderer/drawers/Provider";
import UpdateFirmwareModal, {
Props as UpdateFirmwareModalProps,
} from "~/renderer/modals/UpdateFirmwareModal";
import UpdateFirmwareModal from "~/renderer/modals/UpdateFirmwareModal";
import { Device } from "@ledgerhq/live-common/hw/actions/types";
import { initialStepId } from "~/renderer/screens/manager/FirmwareUpdate";
import ErrorDrawer, { Props as ErrorDrawerProps } from "./ErrorDrawer";
import DeviceNotGenuineDrawer, {
Props as DeviceNotGenuineDrawerProps,
} from "./DeviceNotGenuineDrawer";
import ErrorDrawer from "./ErrorDrawer";
import DeviceNotGenuineDrawer from "./DeviceNotGenuineDrawer";
import { useTranslation } from "react-i18next";
import TrackPage from "~/renderer/analytics/TrackPage";
import { track } from "~/renderer/analytics/segment";
Expand Down Expand Up @@ -136,49 +128,52 @@ const EarlySecurityChecks = ({
if (!deviceInfo || !latestFirmware) return;
const modal = deviceInfo.isOSU ? "install" : "disclaimer";
const stepId = initialStepId({ device, deviceInfo });
const updateFirmwareModalProps: UpdateFirmwareModalProps = {
withAppsToReinstall: false,
withResetStep: manager.firmwareUpdateNeedsLegacyBlueResetInstructions(

setDrawer(
UpdateFirmwareModal,
{
withAppsToReinstall: false,
withResetStep: manager.firmwareUpdateNeedsLegacyBlueResetInstructions(
deviceInfo,
device.modelId,
),
onDrawerClose: () => {
closeFwUpdateDrawer();
setFwUpdateInterrupted(latestFirmware?.final);
restartChecksAfterUpdate();
},
onRequestClose: () => {
closeFwUpdateDrawer();
setFwUpdateInterrupted(latestFirmware?.final);
restartChecksAfterUpdate();
},
status: modal,
stepId,
firmware: latestFirmware,
deviceInfo,
device.modelId,
),
onDrawerClose: () => {
closeFwUpdateDrawer();
setFwUpdateInterrupted(latestFirmware?.final);
restartChecksAfterUpdate();
},
onRequestClose: () => {
closeFwUpdateDrawer();
setFwUpdateInterrupted(latestFirmware?.final);
restartChecksAfterUpdate();
},
status: modal,
stepId,
firmware: latestFirmware,
deviceInfo,
device,
deviceModelId: deviceModelId,
setFirmwareUpdateCompleted: () => null,
device,
deviceModelId: deviceModelId,
setFirmwareUpdateCompleted: () => null,

finalStepSuccessDescription: t(
"syncOnboarding.manual.softwareCheckContent.firmwareUpdate.finalStepSuccessDescription",
),
finalStepSuccessButtonLabel: t(
"syncOnboarding.manual.softwareCheckContent.firmwareUpdate.finalStepSuccessButtonLabel",
),
finalStepSuccessButtonOnClick: () => {
closeFwUpdateDrawer();
restartChecksAfterUpdate();
finalStepSuccessDescription: t(
"syncOnboarding.manual.softwareCheckContent.firmwareUpdate.finalStepSuccessDescription",
),
finalStepSuccessButtonLabel: t(
"syncOnboarding.manual.softwareCheckContent.firmwareUpdate.finalStepSuccessButtonLabel",
),
finalStepSuccessButtonOnClick: () => {
closeFwUpdateDrawer();
restartChecksAfterUpdate();
},
deviceHasPin: deviceModelId !== DeviceModelId.stax, // early security checks are triggered only if the device is in one of the steps prior to setting a PIN code
},
deviceHasPin: deviceModelId !== DeviceModelId.stax, // early security checks are triggered only if the device is in one of the steps prior to setting a PIN code
};

setDrawer(UpdateFirmwareModal, updateFirmwareModalProps, {
preventBackdropClick: true,
forceDisableFocusTrap: true,
withPaddingTop: false,
onRequestClose: undefined,
});
{
preventBackdropClick: true,
forceDisableFocusTrap: true,
withPaddingTop: false,
onRequestClose: undefined,
},
);
}, [
closeFwUpdateDrawer,
device,
Expand Down Expand Up @@ -254,47 +249,62 @@ const EarlySecurityChecks = ({
/** Opening and closing of drawers */
useEffect(() => {
if (disconnectedDeviceModalIsOpen) {
const props: TroubleshootingDrawerProps = {
lastKnownDeviceId: deviceModelId,
onClose: () => {
resetGenuineCheckState();
history.push("/onboarding/select-device");
setDrawer(
TroubleshootingDrawer,
{
lastKnownDeviceId: deviceModelId,
onClose: () => {
resetGenuineCheckState();
history.push("/onboarding/select-device");
},
},
};
setDrawer(TroubleshootingDrawer, props, commonDrawerProps);
commonDrawerProps,
);
} else if (allowSecureChannelIsOpen) {
const props: SoftwareCheckAllowSecureChannelDrawerProps = {
deviceModelId,
};
// FIXME: drawer is non closeable so we have to handle device disconnection
setDrawer(SoftwareCheckAllowSecureChannelDrawer, props, commonDrawerProps);
setDrawer(
SoftwareCheckAllowSecureChannelDrawer,
{
deviceModelId,
},
commonDrawerProps,
);
} else if (notGenuineIsOpen) {
const props: DeviceNotGenuineDrawerProps = {
productName,
};
setDrawer(DeviceNotGenuineDrawer, props, commonDrawerProps);
setDrawer(
DeviceNotGenuineDrawer,
{
productName,
},
commonDrawerProps,
);
} else if (genuineCheckError) {
setGenuineCheckStatus(SoftwareCheckStatus.failed);
const props: ErrorDrawerProps = {
onClickRetry: () => {
resetGenuineCheckState();
setGenuineCheckStatus(SoftwareCheckStatus.active);
setDrawer(
ErrorDrawer,
{
onClickRetry: () => {
resetGenuineCheckState();
setGenuineCheckStatus(SoftwareCheckStatus.active);
},
error: genuineCheckError,
},
error: genuineCheckError,
};
setDrawer(ErrorDrawer, props, commonDrawerProps);
commonDrawerProps,
);
} else if (
networkStatus === NetworkStatus.OFFLINE &&
genuineCheckStatus !== SoftwareCheckStatus.inactive
) {
const props: ErrorDrawerProps = {
onClickRetry: () => {
resetGenuineCheckState();
setGenuineCheckStatus(SoftwareCheckStatus.active);
setDrawer(
ErrorDrawer,
{
onClickRetry: () => {
resetGenuineCheckState();
setGenuineCheckStatus(SoftwareCheckStatus.active);
},
error: new NetworkDown(),
},
error: new NetworkDown(),
};
setDrawer(ErrorDrawer, props, commonDrawerProps);
commonDrawerProps,
);
} else if (
getLatestAvailableFirmwareError &&
!(
Expand All @@ -309,14 +319,17 @@ const EarlySecurityChecks = ({
getLatestAvailableFirmwareError.name,
);
setFirmwareUpdateStatus(SoftwareCheckStatus.failed);
const props: ErrorDrawerProps = {
onClickRetry: () => {
setFirmwareUpdateStatus(SoftwareCheckStatus.active);
setDrawer(
ErrorDrawer,
{
onClickRetry: () => {
setFirmwareUpdateStatus(SoftwareCheckStatus.active);
},
error: { message: "Unknown error", ...getLatestAvailableFirmwareError },
closeable: true,
},
error: { message: "Unknown error", ...getLatestAvailableFirmwareError },
closeable: true,
};
setDrawer(ErrorDrawer, props, { forceDisableFocusTrap: true });
{ forceDisableFocusTrap: true },
);
}
return () => setDrawer();
}, [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import TrackPage from "~/renderer/analytics/TrackPage";
import { trackPage } from "~/renderer/analytics/segment";
import { Device } from "@ledgerhq/live-common/hw/actions/types";
import { setDrawer } from "~/renderer/drawers/Provider";
import LockedDeviceDrawer, { Props as LockedDeviceDrawerProps } from "./LockedDeviceDrawer";
import LockedDeviceDrawer from "./LockedDeviceDrawer";
import { LockedDeviceError } from "@ledgerhq/errors";
import { saveSettings } from "~/renderer/actions/settings";

Expand Down Expand Up @@ -318,13 +318,16 @@ const SyncOnboardingCompanion: React.FC<SyncOnboardingCompanionProps> = ({

useEffect(() => {
if (lockedDevice) {
const props: LockedDeviceDrawerProps = {
deviceModelId: device.modelId,
};
setDrawer(LockedDeviceDrawer, props, {
forceDisableFocusTrap: true,
preventBackdropClick: true,
});
setDrawer(
LockedDeviceDrawer,
{
deviceModelId: device.modelId,
},
{
forceDisableFocusTrap: true,
preventBackdropClick: true,
},
);
}
return () => setDrawer();
}, [device.modelId, history, lockedDevice]);
Expand Down
Loading
Loading