Skip to content

fix(keepkey-webusb): clearHalt the IN pipe on a stalled read, not OUT#45

Merged
BitHighlander merged 2 commits into
masterfrom
fix/webusb-clearhalt-endpoint
Jun 7, 2026
Merged

fix(keepkey-webusb): clearHalt the IN pipe on a stalled read, not OUT#45
BitHighlander merged 2 commits into
masterfrom
fix/webusb-clearhalt-endpoint

Conversation

@BitHighlander

Copy link
Copy Markdown
Collaborator

What

readChunk() reads the IN endpoint (transferIn), but on a "stall" it called clearHalt("out", …) — the wrong endpoint and direction. On WinUSB a halted IN pipe is only resumed by resetting that same pipe, so the IN pipe stayed halted and subsequent reads re-stalled. The browser transport additionally fell through and returned the stalled (empty/short) buffer, which the framing parser then rejected as "message not valid".

Fix

clearHalt("in", …) on the pipe that actually stalled, and throw a retryable "bad read" instead of surfacing a non-packet. Applied to both:

  • hdwallet-keepkey-nodewebusb (Node/libusb — used by the desktop Vault)
  • hdwallet-keepkey-webusb (browser)

Scope

This is split out of #44 as the isolated, low-risk correctness fix. The transfer-timeout work from #44 is intentionally not included here (it touches the shared transport more invasively and wants its own validation). #44 is being closed in favor of this.

Note on impact: on the node transport the old clearHalt("out") branch was effectively dead code (a node stall returns no data, so the old && result.data !== undefined guard never fired and it already threw). The actively-buggy path was the browser transport. Either way this is the correct behavior.

CI

The repo's build check is currently red on pre-existing prettier/eslint errors in packages/hdwallet-keepkey/src/zcash.ts + zcash.test.ts (the target of #41) — unrelated to this PR. The two files changed here pass prettier --check and eslint cleanly.

Testing

  • mac/Linux: pair + sign a tx to confirm the happy path is unaffected (stall is rare/not naturally triggered).
  • Optional: a unit test feeding a stall status asserting clearHalt("in", …) + throw.

readChunk() reads the IN endpoint (transferIn) but on a "stall" it cleared
clearHalt("out", ...) -- the wrong endpoint and direction. A halted IN pipe is
only resumed by resetting that same pipe, so it stayed halted. The browser
transport also fell through and returned the stalled (empty/short) buffer, which
the framing parser then rejected as "message not valid".

Reset the IN pipe and throw a retryable "bad read" instead of surfacing a
non-packet. Applied to both hdwallet-keepkey-nodewebusb (Node/libusb) and
hdwallet-keepkey-webusb (browser).

Split out from #44 (which also added transfer timeouts); this is the isolated,
low-risk correctness fix.
@vercel

vercel Bot commented Jun 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hdwallet-sandbox Ready Ready Preview, Comment Jun 7, 2026 9:27pm

Request Review

@BitHighlander BitHighlander merged commit c5a4d79 into master Jun 7, 2026
5 checks passed
@BitHighlander BitHighlander deleted the fix/webusb-clearhalt-endpoint branch June 7, 2026 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant