Skip to content

Commit

Permalink
✨ (core) [DSDK-180]: Add new USB discovery module (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
aussedatlo authored Feb 21, 2024
2 parents 7e53bd8 + 5b4e22b commit da49397
Show file tree
Hide file tree
Showing 53 changed files with 1,809 additions and 81 deletions.
51 changes: 49 additions & 2 deletions apps/sample/src/components/MainView/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import React from "react";
import React, { useCallback, useEffect, useState } from "react";
import type { DiscoveredDevice } from "@ledgerhq/device-sdk-core";
import { Button, Flex, Icons, Text } from "@ledgerhq/react-ui";
import Image from "next/image";
import styled, { DefaultTheme } from "styled-components";

import { useSdk } from "@/providers/DeviceSdkProvider";

const Root = styled(Flex)`
flex-direction: column;
flex: 1;
Expand Down Expand Up @@ -41,6 +44,45 @@ const NanoLogo = styled(Image).attrs({ mb: 8 })`
`;

export const MainView: React.FC = () => {
const sdk = useSdk();
const [discoveredDevice, setDiscoveredDevice] =
useState<null | DiscoveredDevice>(null);

// Example starting the discovery on a user action
const onSelectDeviceClicked = useCallback(() => {
sdk.startDiscovering().subscribe({
next: (device) => {
console.log(`🦖 Discovered device: `, device);
setDiscoveredDevice(device);
},
error: (error) => {
console.error(error);
},
});
}, [sdk]);

useEffect(() => {
return () => {
// Example cleaning up the discovery
sdk.stopDiscovering();
};
}, [sdk]);

useEffect(() => {
if (discoveredDevice) {
sdk.connect({ deviceId: discoveredDevice.id }).subscribe({
next: (connectedDevice) => {
console.log(
`🦖 Response from connect: ${JSON.stringify(connectedDevice)} 🎉`,
);
},
error: (error) => {
console.error(`Error from connection or get-version`, error);
},
});
}
}, [sdk, discoveredDevice]);

return (
<Root>
<Header>
Expand Down Expand Up @@ -72,7 +114,12 @@ export const MainView: React.FC = () => {
Use this application to test Ledger hardware device features.
</Description>

<Button variant="main" backgroundColor="main" size="large">
<Button
onClick={onSelectDeviceClicked}
variant="main"
backgroundColor="main"
size="large"
>
Select a device
</Button>
</Container>
Expand Down
37 changes: 0 additions & 37 deletions packages/config/eslint/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,42 +81,5 @@ module.exports = {
],
},
},
{
files: ["**/*.mjs"],
env: {
es6: true,
node: true,
},
globals: {
log: true,
$: true,
argv: true,
cd: true,
chalk: true,
echo: true,
expBackoff: true,
fs: true,
glob: true,
globby: true,
nothrow: true,
os: true,
path: true,
question: true,
quiet: true,
quote: true,
quotePowerShell: true,
retry: true,
sleep: true,
spinner: true,
ssh: true,
stdin: true,
which: true,
within: true,
},
parserOptions: {
ecmaVersion: 2018,
sourceType: "module",
},
},
],
};
1 change: 0 additions & 1 deletion packages/config/typescript/sdk.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"compilerOptions": {
"target": "esnext",
"lib": ["esnext", "dom"],
"types": ["reflect-metadata", "jest", "node"],
"sourceMap": true,
"declaration": true,
"declarationMap": true,
Expand Down
37 changes: 37 additions & 0 deletions packages/core/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,42 @@ module.exports = {
"@typescript-eslint/unbound-method": 0,
},
},
{
files: ["**/*.mjs"],
env: {
es6: true,
node: true,
},
globals: {
log: true,
$: true,
argv: true,
cd: true,
chalk: true,
echo: true,
expBackoff: true,
fs: true,
glob: true,
globby: true,
nothrow: true,
os: true,
path: true,
question: true,
quiet: true,
quote: true,
quotePowerShell: true,
retry: true,
sleep: true,
spinner: true,
ssh: true,
stdin: true,
which: true,
within: true,
},
parserOptions: {
ecmaVersion: 2018,
sourceType: "module",
},
},
],
};
10 changes: 8 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"lint:fix": "eslint --cache --fix --ext .ts \"src\"",
"prettier": "prettier . --check",
"prettier:fix": "prettier . --write",
"test": "jest src",
"test": "jest",
"test:watch": "pnpm test -- --watch",
"test:coverage": "pnpm test -- --coverage",
"typecheck": "tsc --noEmit",
Expand All @@ -24,9 +24,15 @@
"inversify": "^6.0.2",
"inversify-logger-middleware": "^3.1.0",
"purify-ts": "^2.0.3",
"reflect-metadata": "^0.2.1"
"reflect-metadata": "^0.2.1",
"rxjs": "^7.8.1",
"semver": "^7.5.4",
"uuid": "^9.0.1"
},
"devDependencies": {
"@types/semver": "^7.5.6",
"@types/uuid": "^9.0.8",
"@types/w3c-web-hid": "^1.0.6",
"@ledgerhq/eslint-config-dsdk": "workspace:*",
"@ledgerhq/jest-config-dsdk": "workspace:*",
"@ledgerhq/tsconfig-dsdk": "workspace:*",
Expand Down
12 changes: 6 additions & 6 deletions packages/core/scripts/add-module.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@ import { basename } from "node:path";
const modules = argv._;

if (!modules.length) {
console.error(`Usage: ${basename(__filename)} <feature1> [<feature2> ...]`);
console.error(`Usage: ${basename(__filename)} <module1> [<module2> ...]`);
process.exit(1);
}

within(async () => {
cd("src/internal");
for (const mod of modules) {
const rootFolderName = `${mod}`;
const featureUppercased = mod.charAt(0).toUpperCase() + mod.slice(1);
const moduleUppercased = mod.charAt(0).toUpperCase() + mod.slice(1);
await $`mkdir ${rootFolderName}`;
within(async () => {
cd(rootFolderName);
await $`mkdir data di model service usecase`;
const files = [
`data/${featureUppercased}DataSource.ts`,
`data/${moduleUppercased}DataSource.ts`,
`di/${mod}Module.test.ts`,
`di/${mod}Module.ts`,
`di/${mod}Types.ts`,
`model/.gitkeep`,
`service/${featureUppercased}Service.ts`,
`service/Default${featureUppercased}Service.test.ts`,
`service/Default${featureUppercased}Service.ts`,
`service/${moduleUppercased}Service.ts`,
`service/Default${moduleUppercased}Service.test.ts`,
`service/Default${moduleUppercased}Service.ts`,
`usecase/.gitkeep`,
];
for (const file of files) {
Expand Down
27 changes: 27 additions & 0 deletions packages/core/src/api/DeviceSdk.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import { Container } from "inversify";
import { Observable } from "rxjs";

import { types as ConfigTypes } from "@internal/config/di/configTypes";
import { GetSdkVersionUseCase } from "@internal/config/usecase/GetSdkVersionUseCase";
import { discoveryDiTypes } from "@internal/discovery/di/discoveryDiTypes";
import {
ConnectUseCase,
ConnectUseCaseArgs,
} from "@internal/discovery/use-case/ConnectUseCase";
import type { StartDiscoveringUseCase } from "@internal/discovery/use-case/StartDiscoveringUseCase";
import type { StopDiscoveringUseCase } from "@internal/discovery/use-case/StopDiscoveringUseCase";
import { DiscoveredDevice } from "@internal/usb/model/DiscoveredDevice";
import { makeContainer, MakeContainerProps } from "@root/src/di";

export class DeviceSdk {
Expand All @@ -27,4 +36,22 @@ export class DeviceSdk {
.get<GetSdkVersionUseCase>(ConfigTypes.GetSdkVersionUseCase)
.getSdkVersion();
}

startDiscovering(): Observable<DiscoveredDevice> {
return this.container
.get<StartDiscoveringUseCase>(discoveryDiTypes.StartDiscoveringUseCase)
.execute();
}

stopDiscovering() {
return this.container
.get<StopDiscoveringUseCase>(discoveryDiTypes.StopDiscoveringUseCase)
.execute();
}

connect(args: ConnectUseCaseArgs) {
return this.container
.get<ConnectUseCase>(discoveryDiTypes.ConnectUseCase)
.execute(args);
}
}
3 changes: 3 additions & 0 deletions packages/core/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ export type {
export { ConsoleLogger, Log } from "./ConsoleLogger";
export { DeviceSdk } from "./DeviceSdk";
export { LedgerDeviceSdkBuilder as DeviceSdkBuilder } from "./DeviceSdkBuilder";

// [SHOULD] be exported from another file
export type { DiscoveredDevice } from "@internal/usb/model/DiscoveredDevice";
6 changes: 6 additions & 0 deletions packages/core/src/di.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ import { Container } from "inversify";
// Uncomment this line to enable the logger middleware
// import { makeLoggerMiddleware } from "inversify-logger-middleware";
import { configModuleFactory } from "@internal/config/di/configModule";
import { deviceModelModuleFactory } from "@internal/device-model/di/deviceModelModule";
import { discoveryModuleFactory } from "@internal/discovery/di/discoveryModule";
import { loggerModuleFactory } from "@internal/logger/di/loggerModule";
import { LoggerSubscriber } from "@internal/logger/service/Log";
import { usbModuleFactory } from "@internal/usb/di/usbModule";

// Uncomment this line to enable the logger middleware
// const logger = makeLoggerMiddleware();
Expand All @@ -25,6 +28,9 @@ export const makeContainer = ({

container.load(
configModuleFactory({ stub }),
deviceModelModuleFactory({ stub }),
usbModuleFactory({ stub }),
discoveryModuleFactory({ stub }),
loggerModuleFactory({ subscribers: loggers }),
// modules go here
);
Expand Down
1 change: 0 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import "reflect-metadata";

export * from "./api";
export * from "./transport";
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import {
DeviceModel,
DeviceModelId,
} from "@internal/device-model/model/DeviceModel";

/**
* Source of truth for the device models
*/
export interface DeviceModelDataSource {
getAllDeviceModels(): DeviceModel[];

getDeviceModel(params: { id: DeviceModelId }): DeviceModel;

filterDeviceModels(params: Partial<DeviceModel>): DeviceModel[];
}
Loading

0 comments on commit da49397

Please sign in to comment.