-
Notifications
You must be signed in to change notification settings - Fork 16
WIP: node-hid transport #821
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
base: develop
Are you sure you want to change the base?
Conversation
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
1 Skipped Deployment
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements a new node-hid transport for interacting with Ledger devices via Web HID, including configuration updates, connection handling, and documentation. Key changes include:
- A complete implementation of NodeHidDeviceConnection with APDU sending, reconnection handling, and error propagation.
- Test and lint configuration files along with updated stubs, models, and documentation to support the new transport.
- Changelog entries documenting version updates and improvements.
Reviewed Changes
Copilot reviewed 12 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/transport/node-hid/vitest.config.mjs | Added Vitest config with custom test, coverage, and alias settings. |
| packages/transport/node-hid/src/index.ts | Simplified export aggregation from the API directory. |
| packages/transport/node-hid/src/api/transport/NodeHidDeviceConnection.ts | Introduced connection handling, APDU processing, and reconnection logic. |
| packages/transport/node-hid/src/api/model/HIDDevice.stub.ts | Created a stub builder for HID device testing. |
| packages/transport/node-hid/src/api/model/Errors.ts | Defined custom errors for Web HID transport failures. |
| packages/transport/node-hid/src/api/index.ts | Exported errors and transport APIs. |
| packages/transport/node-hid/src/api/data/WebHidConfig.ts | Added configuration constants. |
| packages/transport/node-hid/eslint.config.mjs | Provided ESLint configuration with project settings and ignores. |
| packages/transport/node-hid/README.md | Updated documentation for installation and usage of the new transport. |
| packages/transport/node-hid/CHANGELOG.md | Recorded version updates and change details. |
| packages/transport/node-hid/.prettierrc.js | Configured Prettier settings based on the LedgerHQ DS SDK config. |
Files not reviewed (5)
- packages/transport/node-hid/.prettierignore: Language not supported
- packages/transport/node-hid/package.json: Language not supported
- packages/transport/node-hid/tsconfig.json: Language not supported
- packages/transport/node-hid/tsconfig.prod.json: Language not supported
- pnpm-lock.yaml: Language not supported
| async sendApdu( | ||
| apdu: Uint8Array, | ||
| triggersDisconnection?: boolean, | ||
| ): Promise<Either<DmkError, ApduResponse>> { | ||
| this._sendApduSubject = new Subject(); | ||
| this._pendingApdu = Maybe.of(apdu); | ||
| this._logger.debug("Sending APDU", { | ||
| data: { apdu }, | ||
| tag: "apdu-sender", | ||
| }); | ||
|
|
||
| const resultPromise = new Promise<Either<DmkError, ApduResponse>>( | ||
| (resolve) => { | ||
| this._sendApduSubject.subscribe({ |
Copilot
AI
Apr 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reinitializing _sendApduSubject on each call to sendApdu may lead to race conditions if the method is invoked concurrently. Consider ensuring that multiple APDU transactions are serialized or using a dedicated subject for each call.
| async sendApdu( | |
| apdu: Uint8Array, | |
| triggersDisconnection?: boolean, | |
| ): Promise<Either<DmkError, ApduResponse>> { | |
| this._sendApduSubject = new Subject(); | |
| this._pendingApdu = Maybe.of(apdu); | |
| this._logger.debug("Sending APDU", { | |
| data: { apdu }, | |
| tag: "apdu-sender", | |
| }); | |
| const resultPromise = new Promise<Either<DmkError, ApduResponse>>( | |
| (resolve) => { | |
| this._sendApduSubject.subscribe({ | |
| private _apduQueue: Promise<void> = Promise.resolve(); | |
| async sendApdu( | |
| apdu: Uint8Array, | |
| triggersDisconnection?: boolean, | |
| ): Promise<Either<DmkError, ApduResponse>> { | |
| return this._apduQueue = this._apduQueue.then(async () => { | |
| const sendApduSubject = new Subject<Either<DmkError, ApduResponse>>(); | |
| this._pendingApdu = Maybe.of(apdu); | |
| this._logger.debug("Sending APDU", { | |
| data: { apdu }, | |
| tag: "apdu-sender", | |
| }); | |
| const resultPromise = new Promise<Either<DmkError, ApduResponse>>( | |
| (resolve) => { | |
| sendApduSubject.subscribe({ |
| this._device = device; | ||
| this.watchData(); | ||
|
|
Copilot
AI
Apr 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Attaching a new data listener in reconnectHidDevice via watchData may result in accumulated listeners if the previous ones are not properly detached. Consider explicitly removing old listeners before reattaching to avoid potential memory leaks.
| this._device = device; | |
| this.watchData(); | |
| this._device = device; | |
| if (this._dataListener) { | |
| this._device.removeListener("data", this._dataListener); | |
| } | |
| this.watchData(); | |
| } | |
| private watchData() { | |
| this._dataListener = (data: Buffer) => { | |
| // Handle incoming data | |
| this._logger.info(`Received data: ${data.toString("hex")}`); | |
| }; | |
| this._device.on("data", this._dataListener); |
📝 Description
Replace this text by a clear and concise description of what this pull request is about and why it is needed. Be sure to explain the problem you're addressing and the solution you're proposing.
For libraries, you can add a code sample of how to use it.
For bugfixes, you can explain the previous behavior and how it was fixed.
In case of visual features, please attach screenshots or video recordings to demonstrate the changes.
❓ Context
✅ Checklist
Pull Requests must pass CI checks and undergo code review. Set the PR as Draft if it is not yet ready for review.
🧐 Checklist for the PR Reviewers