# KB2040 Hidden Signer (HID + WebUSB)

This directory contains an Arduino firmware scaffold that implements the `kb2040_hidden_signer` plan on top of a TinyUSB composite device.

- Firmware: [`kb2040_hidden_signer.ino`](./kb2040_hidden_signer.ino)
- Host client: [`examples/kb2040_hidden_signer_client.py`](../../examples/kb2040_hidden_signer_client.py)

## What is implemented

1. Composite USB device with two active interfaces:
   - HID Consumer Control (media keys)
   - Vendor/WebUSB transport (framed JSON)
2. Default media mode:
   - Play/Pause, Next, Previous buttons emit HID consumer usages
   - Rotary encoder emits volume up/down
3. Hidden mode toggle:
   - Hold PLAY + NEXT for 3 seconds to toggle media/signer mode
4. WebUSB framed transport:
   - 4-byte big-endian length + JSON payload
5. Signer RPC scaffold methods:
   - `ping`
   - `get_status`
   - `set_mnemonic`
   - `set_auto_approve`
   - `get_public_key` (deterministic placeholder pubkey)
   - `sign_event` (approval gate + placeholder signature)

## What remains to reach production n_signer parity

1. Replace placeholder crypto with real `n_signer` core integration:
   - mnemonic -> seed -> key derivation
   - secp256k1 schnorr signing
   - full auth envelope verification
2. Replace naive JSON parsing with robust parsing (e.g. `ArduinoJson` or cJSON port).
3. Wire exact `keyboard_modules` pin mapping and display abstraction.
4. Add secure memory wiping and persistent policy storage if required.

## Arduino setup (IDE)

1. Install Adafruit board index in Arduino IDE.
2. Install **Adafruit RP2040** boards package.
3. Select board **Adafruit KB2040**.
4. Set **Tools -> USB Stack -> Adafruit TinyUSB**.
5. Install library **Adafruit TinyUSB Library**.
6. Open and flash [`kb2040_hidden_signer.ino`](./kb2040_hidden_signer.ino).

## Arduino CLI flashing (recommended repeatable command)

Use this exact command when flashing from CLI:

```bash
arduino-cli compile --upload -p /dev/ttyACM0 \
  --fqbn rp2040:rp2040:adafruit_kb2040:usbstack=tinyusb \
  firmware/kb2040_hidden_signer
```

Notes:
- `usbstack=tinyusb` is **required** for this firmware (TinyUSB composite device).
- If you omit that option, build fails with `TinyUSB is not selected`.
- If `/dev/ttyACM0` changes, find the current port with:

```bash
arduino-cli board list
```

## Host validation

Install dependency:

```bash
pip install pyusb
```

Basic dual-interface verification:

```bash
python3 tests/test_kb2040_dual.py
```

Signer RPC flow (WebUSB/vendor interface):

```bash
python3 examples/kb2040_hidden_signer_client.py status
python3 examples/kb2040_hidden_signer_client.py set-mnemonic --mnemonic "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
python3 examples/kb2040_hidden_signer_client.py get-public-key
python3 examples/kb2040_hidden_signer_client.py sign-event --event '{"kind":1,"content":"hello"}'
```

## Pin mapping

Current defaults in [`kb2040_hidden_signer.ino`](./kb2040_hidden_signer.ino):

- `PIN_BTN_PLAY = 2`
- `PIN_BTN_NEXT = 3`
- `PIN_BTN_PREV = 4`
- `PIN_ENC_A = 5`
- `PIN_ENC_B = 6`
- `PIN_ENC_SW = 7`

Update these constants to match your physical `keyboard_modules` build.
