Skip to content

fix: surface typed trezor pin failures #105

Description

@ovitrif

Context

The Bitkit App needs a reliable app-facing error state when a user enters the wrong Trezor PIN. This came up while tracking the hardware-wallet polishing follow-up in synonymdev/bitkit-android#1030, and iOS will need the same typed signal when it reaches the same Trezor flows. Without a typed signal, the app can only treat the operation as a generic device failure/loading state, which makes retry UX unclear and can interact badly with reconnect/backoff logic.

Trezor protocol already exposes this as Failure_PinInvalid after PinMatrixAck. python-trezor handles the same flow by checking for PinInvalid, PinCancelled, and PinExpected immediately after sending the PIN and raising a PIN-specific exception.

trezor-connect-rs also defines DeviceError::InvalidPin, and bitkit-core already has TrezorError::InvalidPin; however, current trezor-connect-rs 0.3.2 appears to return some protocol Failure responses as generic DeviceError { code, message } / Failure { code, message }, so the typed error can be lost before it reaches mobile bindings.

This can also be handled in trezor-connect-rs, but it appears easier and sufficient to normalize it in bitkit-core because bitkit-core is the mobile-facing adapter that owns the stable TrezorError contract for the Bitkit App on Android and iOS.

Scope

Preserve Trezor PIN failure semantics in bitkit-core's public FFI error surface.

  • Map Trezor protobuf FailureType codes from upstream generic device failures to typed TrezorError variants where possible:
    • Failure_PinInvalid (7) -> TrezorError::InvalidPin
    • Failure_PinCancelled (6) -> TrezorError::PinCancelled
    • Failure_PinExpected (5) -> TrezorError::PinRequired
    • optionally Failure_ActionCancelled (4) -> TrezorError::UserCancelled
  • Apply the mapping for both upstream DeviceError::Failure { code, message } and DeviceError::DeviceError { code, message } if both can carry those protocol codes.
  • Keep unknown failure codes as generic TrezorError::DeviceError so existing behavior is preserved.
  • Add tests proving numeric/protobuf PIN failure codes surface as typed bitkit-core errors through the existing conversion path.
  • Regenerate mobile bindings and publish a release so the Bitkit App can consume the typed errors on Android and iOS.

Bitkit App usage after release

The Bitkit App should use the typed InvalidPin signal to:

  • clear the submitted/spinner state on PIN entry;
  • show explicit copy such as "Incorrect PIN. Try again.";
  • let the user retry deliberately;
  • avoid reconnecting, refreshing features, or opening a new transport while the device is still mid-flow.

Acceptance criteria

  • Wrong Trezor PIN failures are exposed to the Bitkit App as TrezorError.InvalidPin, not only as generic device errors.
  • PIN cancelled/expected protocol failures are mapped to the existing typed PIN errors where available.
  • Existing generic device failures remain generic unless their protocol code is one of the known PIN/action codes.
  • Mobile bindings expose the updated behavior in a released bitkit-core artifact.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions