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

♻️ (core) [DSDK-558]: Extract transports from core package #454

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 12 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,18 @@ This project uses [turbo monorepo](https://turbo.build/repo/docs) to build and r

A brief description of this project packages:

| Name | Path | Description |
| --------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| @ledgerhq/device-sdk-sample | apps/sample | React Next web app used to test & demonstrate the Web Device Management Kit |
| @ledgerhq/eslint-config-dsdk | packages/config/eslint | internal package which contains eslint shared config. Used by `extends: ["@ledgerhq/dsdk"]` in `.eslintrc`. |
| @ledgerhq/jest-config-dsdk | packages/config/jest | internal package which contains jest shared config. Used by `preset: "@ledgerhq/jest-config-dsdk"` in `jest.config.ts` |
| @ledgerhq/tsconfig-dsdk | packages/config/typescript | internal package which contains typescript shared config. Used by `"extends": "@ledgerhq/tsconfig-dsdk/tsconfig.sdk"` in `tsconfig.json` |
| @ledgerhq/device-management-kit | packages/core | external package that contains the core of the Web SDK |
| @ledgerhq/device-sdk-signer | packages/signer | external package that contains device coin application dedicated handlers |
| @ledgerhq/device-sdk-trusted-apps | packages/trusted-apps | external package that contains device trusted application dedicated handlers |
| @ledgerhq/device-sdk-ui | packages/ui | external package |
| Name | Path | Description |
| -------------------------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| @ledgerhq/device-sdk-sample | apps/sample | React Next web app used to test & demonstrate the Web Device Management Kit |
| @ledgerhq/eslint-config-dsdk | packages/config/eslint | internal package which contains eslint shared config. Used by `extends: ["@ledgerhq/dsdk"]` in `.eslintrc`. |
| @ledgerhq/jest-config-dsdk | packages/config/jest | internal package which contains jest shared config. Used by `preset: "@ledgerhq/jest-config-dsdk"` in `jest.config.ts` |
| @ledgerhq/tsconfig-dsdk | packages/config/typescript | internal package which contains typescript shared config. Used by `"extends": "@ledgerhq/tsconfig-dsdk/tsconfig.sdk"` in `tsconfig.json` |
| @ledgerhq/device-management-kit | packages/core | external package that contains the core of the Web SDK |
| @ledgerhq/device-sdk-signer | packages/signer | external package that contains device coin application dedicated handlers |
| @ledgerhq/device-sdk-trusted-apps | packages/trusted-apps | external package that contains device trusted application dedicated handlers |
| @ledgerhq/device-sdk-ui | packages/ui | external package |
| @ledgerhq/device-transport-kit-web-hid | packages/transport/web-hid | external package that contains the Web Hid transport implementation |
| @ledgerhq/device-transport-kit-web-ble | packages/transport/web-ble | external package that contains the Web Ble transport implementation |

# Getting started

Expand Down
2 changes: 2 additions & 0 deletions apps/sample/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
"@ledgerhq/device-signer-kit-ethereum": "workspace:*",
"@ledgerhq/device-signer-kit-solana": "workspace:*",
"@ledgerhq/device-sdk-transport-mock": "workspace:*",
"@ledgerhq/device-transport-kit-web-ble": "workspace:*",
"@ledgerhq/device-transport-kit-web-hid": "workspace:*",
"@ledgerhq/react-ui": "^0.16.2",
"@sentry/nextjs": "^8.32.0",
"@playwright/test": "^1.47.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
BuiltinTransports,
type SdkError,
} from "@ledgerhq/device-management-kit";
import { webBleIdentifier } from "@ledgerhq/device-transport-kit-web-ble";
import { webHidIdentifier } from "@ledgerhq/device-transport-kit-web-hid";
import { Button, Flex } from "@ledgerhq/react-ui";
import styled from "styled-components";

Expand All @@ -26,7 +28,7 @@ export const ConnectDeviceActions = ({
const sdk = useSdk();

const onSelectDeviceClicked = useCallback(
(selectedTransport: BuiltinTransports) => {
(selectedTransport: string) => {
onError(null);
sdk.startDiscovering({ transport: selectedTransport }).subscribe({
next: (device) => {
Expand Down Expand Up @@ -78,15 +80,15 @@ export const ConnectDeviceActions = ({
) : (
<Flex>
<ConnectButton
onClick={() => onSelectDeviceClicked(BuiltinTransports.USB)}
onClick={() => onSelectDeviceClicked(webHidIdentifier)}
variant="main"
backgroundColor="main"
size="large"
>
Select a USB device
</ConnectButton>
<ConnectButton
onClick={() => onSelectDeviceClicked(BuiltinTransports.BLE)}
onClick={() => onSelectDeviceClicked(webBleIdentifier)}
variant="main"
backgroundColor="main"
size="large"
Expand Down
64 changes: 47 additions & 17 deletions apps/sample/src/providers/DeviceSdkProvider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
WebLogsExporterLogger,
} from "@ledgerhq/device-management-kit";
import { FlipperSdkLogger } from "@ledgerhq/device-management-kit-flipper-plugin-client";
import { WebBleTransport } from "@ledgerhq/device-transport-kit-web-ble";
import { WebHidTransport } from "@ledgerhq/device-transport-kit-web-hid";

import { useHasChanged } from "@/hooks/useHasChanged";
import { useSdkConfigContext } from "@/providers/SdkConfig";
Expand All @@ -17,23 +19,49 @@ const LogsExporterContext = createContext<WebLogsExporterLogger | null>(null);

function buildDefaultSdk(logsExporter: WebLogsExporterLogger) {
return new DeviceSdkBuilder()
.addTransport(BuiltinTransports.USB)
.addTransport(BuiltinTransports.BLE)
.addLogger(new ConsoleLogger())
.addTransport(
({
deviceModelDataSource,
loggerServiceFactory,
apduSenderServiceFactory,
apduReceiverServiceFactory,
}) =>
new WebHidTransport(
deviceModelDataSource,
loggerServiceFactory,
apduSenderServiceFactory,
apduReceiverServiceFactory,
),
)
.addTransport(
({
deviceModelDataSource,
loggerServiceFactory,
apduSenderServiceFactory,
apduReceiverServiceFactory,
}) =>
new WebBleTransport(
deviceModelDataSource,
loggerServiceFactory,
apduSenderServiceFactory,
apduReceiverServiceFactory,
),
Comment on lines +24 to +49
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[SHOULD] export those factories from each transport package, as a default transport factory

)
.addLogger(logsExporter)
.addLogger(new FlipperSdkLogger())
.build();
}

function buildMockSdk(url: string, logsExporter: WebLogsExporterLogger) {
return new DeviceSdkBuilder()
.addTransport(BuiltinTransports.MOCK_SERVER)
.addLogger(new ConsoleLogger())
.addLogger(logsExporter)
.addLogger(new FlipperSdkLogger())
.addConfig({ mockUrl: url })
.build();
}
// function buildMockSdk(url: string, logsExporter: WebLogsExporterLogger) {
// return new DeviceSdkBuilder()
// .addTransport(BuiltinTransports.MOCK_SERVER)
// .addLogger(new ConsoleLogger())
// .addLogger(logsExporter)
// .addLogger(new FlipperSdkLogger())
// .addConfig({ mockUrl: url })
// .build();
// }

export const SdkProvider: React.FC<PropsWithChildren> = ({ children }) => {
const {
Expand All @@ -43,9 +71,10 @@ export const SdkProvider: React.FC<PropsWithChildren> = ({ children }) => {
const mockServerEnabled = transport === BuiltinTransports.MOCK_SERVER;
const [state, setState] = useState(() => {
const logsExporter = new WebLogsExporterLogger();
const sdk = mockServerEnabled
? buildMockSdk(mockServerUrl, logsExporter)
: buildDefaultSdk(logsExporter);
// const sdk = mockServerEnabled
// ? buildMockSdk(mockServerUrl, logsExporter)
// : buildDefaultSdk(logsExporter);
const sdk = buildDefaultSdk(logsExporter);
return { sdk, logsExporter };
});

Expand All @@ -55,9 +84,10 @@ export const SdkProvider: React.FC<PropsWithChildren> = ({ children }) => {
if (mockServerEnabledChanged || mockServerUrlChanged) {
setState(({ logsExporter }) => {
return {
sdk: mockServerEnabled
? buildMockSdk(mockServerUrl, logsExporter)
: buildDefaultSdk(logsExporter),
// sdk: mockServerEnabled
// ? buildMockSdk(mockServerUrl, logsExporter)
// : buildDefaultSdk(logsExporter),
sdk: buildDefaultSdk(logsExporter),
logsExporter,
};
});
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"build": "turbo run build",
"build:libs": "turbo run build --filter=./packages/**",
"dev": "turbo run dev",
"dev": "turbo run dev --concurrency 20",
"lint": "turbo run lint",
"lint:fix": "turbo run lint:fix",
"prettier": "turbo run prettier",
Expand All @@ -23,6 +23,9 @@
"transport-mock": "pnpm --filter @ledgerhq/device-sdk-transport-mock",
"trusted-apps": "pnpm --filter @ledgerhq/device-sdk-trusted-apps",
"ui": "pnpm --filter @ledgerhq/device-sdk-ui",
"transports": "pnpm --filter @ledgerhq/device-transport-*",
"transport-web-hid": "pnpm --filter @ledgerhq/device-transport-kit-web-hid",
"transport-web-ble": "pnpm --filter @ledgerhq/device-transport-kit-web-ble",
"flipper": "pnpm --filter @ledgerhq/device-management-kit-flipper-plugin-client",
"sample": "pnpm --filter @ledgerhq/device-sdk-sample",
"bump": "changeset version",
Expand Down
2 changes: 1 addition & 1 deletion packages/core/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const internalPaths = pathsToModuleNameMapper(compilerOptions.paths, {
const config: JestConfigWithTsJest = {
preset: "@ledgerhq/jest-config-dsdk",
setupFiles: ["<rootDir>/jest.setup.ts"],
testPathIgnorePatterns: ["<rootDir>/lib/esm", "<rootDir>/lib/cjs"],
testPathIgnorePatterns: ["<rootDir>/lib/esm/", "<rootDir>/lib/cjs/"],
collectCoverageFrom: [
"src/**/*.ts",
"!src/**/*.stub.ts",
Expand Down
7 changes: 4 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@
"inversify-logger-middleware": "^3.1.0",
"purify-ts": "^2.1.0",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
"semver": "^7.6.3",
"uuid": "^10.0.0",
"xstate": "^5.18.2"
},
"peerDependencies": {
"rxjs": "^7.8.1"
},
"devDependencies": {
"@ledgerhq/esbuild-tools": "workspace:*",
"@ledgerhq/eslint-config-dsdk": "workspace:*",
Expand All @@ -57,8 +59,7 @@
"@ledgerhq/tsconfig-dsdk": "workspace:*",
"@types/semver": "^7.5.8",
"@types/uuid": "^10.0.0",
"@types/w3c-web-hid": "^1.0.6",
"@types/web-bluetooth": "^0.0.20",
"rxjs": "^7.8.1",
"ts-node": "^10.9.2"
}
}
2 changes: 0 additions & 2 deletions packages/core/src/api/DeviceSdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ export class DeviceSdk {
constructor({
stub,
transports,
customTransports,
loggers,
config,
}: Partial<MakeContainerProps> = {}) {
Expand All @@ -69,7 +68,6 @@ export class DeviceSdk {
this.container = makeContainer({
stub,
transports,
customTransports,
loggers,
config,
});
Expand Down
17 changes: 4 additions & 13 deletions packages/core/src/api/DeviceSdkBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import {
} from "@internal/manager-api/model/Const";

import { type LoggerSubscriberService } from "./logger-subscriber/service/LoggerSubscriberService";
import { type Transport } from "./transport/model/Transport";
import { type BuiltinTransports } from "./transport/model/TransportIdentifier";
import { type TransportFactory } from "./transport/model/Transport";
import { DeviceSdk } from "./DeviceSdk";
import { type SdkConfig } from "./SdkConfig";

Expand All @@ -16,17 +15,15 @@ import { type SdkConfig } from "./SdkConfig";
* ```
* const sdk = new LedgerDeviceSdkBuilder()
* .setStub(false)
* .addTransport(BuiltinTransports.USB)
* .addCustomTransport(new MyTransport())
* .addTransport(new MyTransport())
* .addLogger(myLogger)
* .build();
* ```
*/
export class LedgerDeviceSdkBuilder {
private stub = false;
private readonly loggers: LoggerSubscriberService[] = [];
private readonly transports: BuiltinTransports[] = [];
private readonly customTransports: Transport[] = [];
private readonly transports: TransportFactory[] = [];
private config: SdkConfig = {
managerApiUrl: DEFAULT_MANAGER_API_BASE_URL,
mockUrl: DEFAULT_MOCK_SERVER_BASE_URL,
Expand All @@ -36,7 +33,6 @@ export class LedgerDeviceSdkBuilder {
return new DeviceSdk({
stub: this.stub,
transports: this.transports,
customTransports: this.customTransports,
loggers: this.loggers,
config: this.config,
});
Expand All @@ -47,16 +43,11 @@ export class LedgerDeviceSdkBuilder {
return this;
}

addTransport(transport: BuiltinTransports): LedgerDeviceSdkBuilder {
addTransport(transport: TransportFactory): LedgerDeviceSdkBuilder {
this.transports.push(transport);
return this;
}

addCustomTransport(transport: Transport): LedgerDeviceSdkBuilder {
this.customTransports.push(transport);
return this;
}

/**
* Add a logger to the SDK that will receive its logs
*/
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/api/apdu/utils/ApduParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe("ApduParser", () => {
});

it("Test zero length", () => {
const response: ApduResponse = new ApduResponse({
response = new ApduResponse({
statusCode: STATUS_WORD_SUCCESS,
data: RESPONSE_LV_ZERO,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { Left } from "purify-ts";

import { type Command } from "@api/command/Command";
import { CommandResultStatus } from "@api/command/model/CommandResult";
import { type LoggerPublisherService } from "@api/logger-publisher/service/LoggerPublisherService";
import { deviceSessionStubBuilder } from "@internal/device-session/model/DeviceSession.stub";
import { DefaultDeviceSessionService } from "@internal/device-session/service/DefaultDeviceSessionService";
import { type DeviceSessionService } from "@internal/device-session/service/DeviceSessionService";
import { DefaultLoggerPublisherService } from "@internal/logger-publisher/service/DefaultLoggerPublisherService";
import { type LoggerPublisherService } from "@internal/logger-publisher/service/LoggerPublisherService";
import { AxiosManagerApiDataSource } from "@internal/manager-api/data/AxiosManagerApiDataSource";
import { type ManagerApiDataSource } from "@internal/manager-api/data/ManagerApiDataSource";
import { DefaultManagerApiService } from "@internal/manager-api/service/DefaultManagerApiService";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { inject, injectable } from "inversify";

import { Command } from "@api/command/Command";
import { CommandResult } from "@api/command/model/CommandResult";
import { LoggerPublisherService } from "@api/logger-publisher/service/LoggerPublisherService";
import { deviceSessionTypes } from "@internal/device-session/di/deviceSessionTypes";
import type { DeviceSessionService } from "@internal/device-session/service/DeviceSessionService";
import { loggerTypes } from "@internal/logger-publisher/di/loggerTypes";
import { LoggerPublisherService } from "@internal/logger-publisher/service/LoggerPublisherService";

export type SendCommandUseCaseArgs<Response, ErrorStatusCodes, Args = void> = {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import {
ExecuteDeviceActionReturnType,
} from "@api/device-action/DeviceAction";
import { SdkError } from "@api/Error";
import { LoggerPublisherService } from "@api/logger-publisher/service/LoggerPublisherService";
import { deviceSessionTypes } from "@internal/device-session/di/deviceSessionTypes";
import type { DeviceSessionService } from "@internal/device-session/service/DeviceSessionService";
import { loggerTypes } from "@internal/logger-publisher/di/loggerTypes";
import { LoggerPublisherService } from "@internal/logger-publisher/service/LoggerPublisherService";

export type ExecuteDeviceActionUseCaseArgs<
Output,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { type DeviceModelId } from "@api/device/DeviceModel";
import {
type BleDeviceInfos,
type TransportDeviceModel,
} from "@api/device-model/model/DeviceModel";

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

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

filterDeviceModels(
params: Partial<TransportDeviceModel>,
): TransportDeviceModel[];

getBluetoothServicesInfos(): Record<string, BleDeviceInfos>;

getBluetoothServices(): string[];
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DeviceModelId } from "@api/device/DeviceModel";
import { BleDeviceInfos } from "@internal/transport/ble/model/BleDeviceInfos";
import { BleDeviceInfos } from "@api/device-model/model/DeviceModel";

import { StaticDeviceModelDataSource } from "./StaticDeviceModelDataSource";

Expand Down
Loading
Loading