Skip to content

Commit

Permalink
feat(transport): add nodeusb transport
Browse files Browse the repository at this point in the history
  • Loading branch information
mroz22 committed Jun 12, 2023
1 parent 82fb7d6 commit f710f5c
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 16 deletions.
2 changes: 2 additions & 0 deletions packages/connect-iframe/webpack/prod.webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ const config: webpack.Configuration = {
events: require.resolve('events'),
http: false,
zlib: false,
path: false, // usb
os: false, // usb
},
},
performance: {
Expand Down
9 changes: 9 additions & 0 deletions packages/connect/src/device/DeviceList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { TypedEmitter } from '@trezor/utils/lib/typedEventEmitter';
import {
BridgeTransport,
WebUsbTransport,
NodeUsbTransport,
Transport,
TRANSPORT,
Descriptor,
Expand Down Expand Up @@ -87,6 +88,14 @@ export class DeviceList extends TypedEmitter<DeviceListEvents> {
}),
);
break;
case 'NodeUsbTransport':
this.transports.push(
new NodeUsbTransport({
messages: this.messages,
logger: transportLogger,
}),
);
break;
case 'BridgeTransport':
this.transports.push(
new BridgeTransport({
Expand Down
3 changes: 1 addition & 2 deletions packages/suite/src/views/settings/debug/Transport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ export const Transport = () => {
const transports: TransportMenuItem['name'][] = ['BridgeTransport'];

if (isDesktop()) {
// todo: enable when nodeusb added
// transports.push('NodeUsbTransport');
transports.push('NodeUsbTransport');
} else {
transports.push('WebUsbTransport');
}
Expand Down
5 changes: 4 additions & 1 deletion packages/transport/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
],
"main": "./lib/index.js",
"browser": {
"./lib/transports/nodeusb": "./lib/transports/nodeusb.browser",
"./lib/transports/webusb": "./lib/transports/webusb.browser",
"./src/transports/nodeusb": "./src/transports/nodeusb.browser",
"./src/transports/webusb": "./src/transports/webusb.browser"
},
"files": [
Expand Down Expand Up @@ -59,6 +61,7 @@
"json-stable-stringify": "^1.0.2",
"long": "^4.0.0",
"prettier": "2.8.8",
"protobufjs": "6.11.3"
"protobufjs": "6.11.3",
"usb": "^2.9.0"
}
}
4 changes: 2 additions & 2 deletions packages/transport/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ export { BridgeTransport } from './transports/bridge';
// browser (chrome-like) only
export { WebUsbTransport } from './transports/webusb';

export { SessionsBackground } from './sessions/background';
export { SessionsClient } from './sessions/client';
// node only
export { NodeUsbTransport } from './transports/nodeusb';
26 changes: 26 additions & 0 deletions packages/transport/src/transports/nodeusb.browser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { AbstractTransport } from './abstract';

import { WRONG_ENVIRONMENT } from '../errors';
import { empty, emptyAbortable, emptySync } from '../utils/resultEmpty';

// this class loads in browser environment only in case of accidental use of NodeUsbTransport

export class NodeUsbTransport extends AbstractTransport {
public name = 'NodeUsbTransport' as const;

constructor(params: ConstructorParameters<typeof AbstractTransport>[0]) {
super(params);
console.error(WRONG_ENVIRONMENT);
}

init = emptyAbortable;
acquire = emptyAbortable;
enumerate = emptyAbortable;
call = emptyAbortable;
receive = emptyAbortable;
send = emptyAbortable;
release = emptyAbortable;
stop = empty;
releaseDevice = empty;
listen = emptySync;
}
41 changes: 41 additions & 0 deletions packages/transport/src/transports/nodeusb.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { WebUSB } from 'usb';
import { AbstractTransport } from './abstract';
import { AbstractUsbTransport } from './abstractUsb';
import { SessionsClient } from '../sessions/client';
import { SessionsBackground } from '../sessions/background';
import { UsbInterface } from '../interfaces/usb';

// notes:
// to make it work on Linux I needed to run `sudo chmod -R 777 /dev/bus/usb/` which is obviously not
// the way to go.

export class NodeUsbTransport extends AbstractUsbTransport {
public name = 'NodeUsbTransport' as const;

constructor({ messages, logger }: ConstructorParameters<typeof AbstractTransport>[0]) {
const sessionsBackground = new SessionsBackground();

// in nodeusb there is no synchronization yet. this is a followup and needs to be decided
// so far, sessionsClient has direct access to sessionBackground
const sessionsClient = new SessionsClient({
requestFn: args => sessionsBackground.handleMessage(args),
registerBackgroundCallbacks: () => {},
});

sessionsBackground.on('descriptors', descriptors => {
sessionsClient.emit('descriptors', descriptors);
});

super({
messages,
usbInterface: new UsbInterface({
usbInterface: new WebUSB({
allowAllDevices: true, // return all devices, not only authorized
}),
logger,
}),

sessionsClient,
});
}
}
16 changes: 6 additions & 10 deletions packages/transport/src/transports/webusb.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import { AbstractTransport } from './abstract';

import { error } from '../utils/result';
import { WRONG_ENVIRONMENT } from '../errors';

const emptyAbortable = () => ({
promise: Promise.resolve(error({ error: WRONG_ENVIRONMENT })),
abort: () => {},
});

const empty = () => Promise.resolve(error({ error: WRONG_ENVIRONMENT }));

const emptySync = () => error({ error: WRONG_ENVIRONMENT });
import { empty, emptyAbortable, emptySync } from '../utils/resultEmpty';

// this class loads in node environment only in case of accidental use of WebusbTransport
export class WebUsbTransport extends AbstractTransport {
public name = 'WebUsbTransport' as const;

constructor(params: ConstructorParameters<typeof AbstractTransport>[0]) {
super(params);
console.error(WRONG_ENVIRONMENT);
}

init = emptyAbortable;
acquire = emptyAbortable;
enumerate = emptyAbortable;
Expand Down
11 changes: 11 additions & 0 deletions packages/transport/src/utils/resultEmpty.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { WRONG_ENVIRONMENT } from '../errors';
import { error } from './result';

export const emptyAbortable = () => ({
promise: Promise.resolve(error({ error: WRONG_ENVIRONMENT })),
abort: () => {},
});

export const empty = () => Promise.resolve(error({ error: WRONG_ENVIRONMENT }));

export const emptySync = () => error({ error: WRONG_ENVIRONMENT });
24 changes: 23 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8349,6 +8349,7 @@ __metadata:
ts-node: ^10.9.1
tsx: ^3.12.7
typescript: 4.9.5
usb: ^2.9.0
languageName: unknown
linkType: soft

Expand Down Expand Up @@ -25267,6 +25268,15 @@ __metadata:
languageName: node
linkType: hard

"node-addon-api@npm:^6.0.0":
version: 6.1.0
resolution: "node-addon-api@npm:6.1.0"
dependencies:
node-gyp: latest
checksum: 3a539510e677cfa3a833aca5397300e36141aca064cdc487554f2017110709a03a95da937e98c2a14ec3c626af7b2d1b6dabe629a481f9883143d0d5bff07bf2
languageName: node
linkType: hard

"node-dir@npm:^0.1.10, node-dir@npm:^0.1.17":
version: 0.1.17
resolution: "node-dir@npm:0.1.17"
Expand Down Expand Up @@ -25321,7 +25331,7 @@ __metadata:
languageName: node
linkType: hard

"node-gyp-build@npm:^4.2.0, node-gyp-build@npm:^4.2.2, node-gyp-build@npm:^4.3.0":
"node-gyp-build@npm:^4.2.0, node-gyp-build@npm:^4.2.2, node-gyp-build@npm:^4.3.0, node-gyp-build@npm:^4.5.0":
version: 4.6.0
resolution: "node-gyp-build@npm:4.6.0"
bin:
Expand Down Expand Up @@ -33333,6 +33343,18 @@ __metadata:
languageName: node
linkType: hard

"usb@npm:^2.9.0":
version: 2.9.0
resolution: "usb@npm:2.9.0"
dependencies:
"@types/w3c-web-usb": ^1.0.6
node-addon-api: ^6.0.0
node-gyp: latest
node-gyp-build: ^4.5.0
checksum: 59474e106bb0e261c0c107994c948e4493b0d390671a738f386054263f6fdeea8f990ae22256dcf28812717844ec757b58501a9950ad9ca18ccb4791505870b0
languageName: node
linkType: hard

"use-callback-ref@npm:^1.3.0":
version: 1.3.0
resolution: "use-callback-ref@npm:1.3.0"
Expand Down

0 comments on commit f710f5c

Please sign in to comment.