Skip to content
Back to skills

Kindle Lpagent Dashboard

ASecurity

Install, configure, update and troubleshoot the LP Agent e-ink dashboard on a jailbroken Kindle (standalone - a busybox shell daemon pulls the LP Agent Open API and a local WAF web app draws it, no server). Use when someone wants to turn a Kindle into an LP Agent dashboard, copy or deploy it over USB or Wi-Fi, change its config or layout, or fix it (no data, stale data, screensaver, unexpected restarts, app not opening, can't reach the dev shell).

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added November 7, 2026
ai-agentsgoshellsqlawsgitapi

Works with

  • api

Security analysis

A100/100

Scanned November 7, 2026

npx -y skills add toanbku/kindle-lpagent-dashboard --skill kindle-lpagent-dashboard --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Kindle Lpagent Dashboard?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Kindle Lpagent Dashboard
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/toanbku-kindle-lpagent-dashboard/badge)](https://www.skillsdirectory.com/skills/toanbku-kindle-lpagent-dashboard)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: kindle-lpagent-dashboard
description: Install, configure, update and troubleshoot the LP Agent e-ink dashboard on a jailbroken Kindle (standalone - a busybox shell daemon pulls the LP Agent Open API and a local WAF web app draws it, no server). Use when someone wants to turn a Kindle into an LP Agent dashboard, copy or deploy it over USB or Wi-Fi, change its config or layout, or fix it (no data, stale data, screensaver, unexpected restarts, app not opening, can't reach the dev shell).
---

# Kindle LP Agent dashboard

The project lives at https://github.com/toanbku/kindle-lpagent-dashboard. The README there is the user-facing manual. This
file is the operator's checklist plus the gotchas that cost time.

**Find the files first.**
- If this skill was installed with the plugin, the repo root is two levels above this skill's base directory
  (`<base>/../..`), and `kindle/lpdash/lpdashd.sh` must exist there.
- Otherwise, clone the repo into a working folder.

**Map of the repo:**
- `kindle/` is a mirror of the Kindle's user storage `/mnt/us`. On macOS it is mounted at `/Volumes/Kindle`.
- `tools/` holds the scripts that run on the computer: `ksh.py`, `kshot.py` and `render-test.sh`.

## Ground rules

- **The API key is a secret.**
  - Never print it, echo it, paste it into chat or put it in a commit.
  - When showing `config.sh`, redact `LPA_KEY`, e.g. `sed -E 's/(LPA_KEY=).*/\1<redacted>/'`.
  - `config.sh` is gitignored. Keep it that way.
- **Jailbreaking is the user's call.** It can brick the device.
  - Explain the risk, link the [Kindle Modding guide](https://kindlemodding.org) (WinterBreak) and let the user do the steps on the device.
  - Until the device is jailbroken, it must stay in airplane mode, because an automatic update can close the exploit.
- **Don't edit a shell script while it runs.** For the daemon, the order is: stop it, copy the file, start it.
- **The dev shell is passwordless root over telnet.**
  - Only allow the user's own computer IP (`DEV_SHELL_ALLOW_IP`).
  - Remind the user to turn it off when finished.
- **Rebooting the device, deleting files on it, or editing `/var/local/appreg.db` changes the user's Kindle.** Say what you
  are about to do before you do it.

## 1. Check the device

- **USB.**
  - Mac: `ls /Volumes/Kindle`.
  - If nothing mounts, check `ioreg -p IOUSB -l -w0 | grep '"idVendor" = 6473'` (Amazon is 0x1949).
  - A charge-only cable or a bad port is the usual cause, so swap the cable.
  - After an eject, the Kindle stays in charge-only mode until it is replugged.
- **Firmware:** `/Volumes/Kindle/system/version.txt`. WinterBreak supports firmware up to 5.18.0.
- **Jailbroken?** Ask the user. On a jailbroken Kindle, `.sh` files in `documents/` with a `# Name:` header show up as
  books (scriptlets).

## 2. Install

1. Copy the payload:
   ```sh
   cp -RX kindle/apps kindle/lpdash kindle/documents kindle/emergency.sh /Volumes/Kindle/
   find /Volumes/Kindle -maxdepth 3 -name '._*' -delete
   ```
   If `/Volumes/Kindle/emergency.sh` already exists and is not ours, merge it instead of overwriting.
2. Create `lpdash/config.sh` from `config.example.sh`.
   - Ask the user for the API key, the wallet, the chain (`ROBINHOOD` or `SOL`), their UTC offset, and optionally their computer's LAN IP for the dev shell.
   - Write the file without echoing the key, then run `chmod 600` on it.
3. Eject with `diskutil eject /Volumes/Kindle`. If the local `kindle/lpdash/` holds a preview `data/` or `log.txt`, it
   was copied too. That is harmless, but you can delete them on the device.
4. The user turns Wi-Fi on and taps **LP Agent Dashboard**. That registers the WAF app, starts the daemon and opens the app about 4 s later.
5. Verify that `lpdash/log.txt` shows `fetch 4/4`.

## 3. Update or debug over Wi-Fi

1. The user taps **LP Agent - Dev shell (on/off)**. It prints `Dev shell ON: <ip>:2323`.
2. If you don't know the IP, find it:
   - A reboot can give the Kindle a new IP (DHCP), and a reboot also turns the dev shell off.
   - Ping-sweep the LAN, then run `arp -an`. Amazon devices have MAC prefixes such as `1c:4d:66`.
3. Run commands with `KINDLE_IP=<ip>`:
   ```sh
   tools/ksh.py 'tail -20 /mnt/us/lpdash/log.txt'
   tools/ksh.py --put <local> <remote>          # prints the remote md5, compare it with `md5 -q <local>`
   tools/kshot.py shot.png                      # framebuffer screenshot (dark images may come out inverted)
   ```
4. Restart the daemon:
   ```sh
   kill $(cat /mnt/us/lpdash/lpdashd.pid)
   nohup sh /mnt/us/lpdash/lpdashd.sh >/dev/null 2>&1 &
   ```
   - Only one daemon may run. Check with `/proc/<pid>/cmdline`, not `ps | grep`, because a forked child still carries the script name.
5. Open the app with `lipc-set-prop com.lab126.appmgrd start app://com.lpagent.dashboard`.
6. Finish by having the user tap the Dev shell item again to turn it off.

## 4. Change the layout (`kindle/apps/xyz.lpagent.dashboard/index.html`)

- **Old WebKit rules:**
  - Write ES5 only: no flexbox/grid, no Promise, no arrow functions.
  - Use tables and absolute positioning.
  - CSS `zoom` works.
- **Data:** it arrives through `<script>` tags that set `window.LPRAW.<name>`, because there is no XHR on `file://`.
  The path is `../../lpdash/data/`, or `demo/` with `?demo=1`.
- **Fonts:** the bundled Inter subset lacks ● ○ ≈. Draw dots with CSS.
- **Screen height:** `innerHeight` reports 1448 first and about 1232 roughly 2 s later, once the system bar is drawn.
  `layout()` re-runs at 1.5, 3.5 and 7 s: it drops "Recently closed" rows, then zooms.
- **System bar:** the top bar cannot be hidden (`kindle.chrome.hide()` and appreg `default-chrome-style` do nothing).
  Set its title with `kindle.messaging.sendMessage('com.lab126.chromebar','configureChrome',...)`.
- **Net worth** = wallet `balanceInUsd` + each position's `currentValue` + `unCollectedFee`. This matches the LP Agent app.
- **Preview:** run `tools/render-test.sh demo`, and `tools/render-test.sh` for real data. Look at both pages for
  overflow before you deploy.

## 5. Troubleshooting

| Symptom | Cause / fix |
|---|---|
| "No data yet" | The daemon is not running or `config.sh` is missing. Check `lpdash/log.txt`. |
| STALE DATA banner | Wi-Fi is off or the API is failing. `log.txt` has the HTTP codes. `429` = rate limit, so keep the 6 s gaps and raise `INTERVAL`. `000` is a network/TLS blip that usually recovers on the next try. |
| Screensaver appears | Something reset `preventScreenSaver` to 0. The daemon's `keepalive` sets it every minute, and when `state` is `screenSaver` it sends `wakeUp 1` (that property only works while the screensaver shows) and `lipc-set-prop com.lab126.blanket unload ad_screensaver` to clear the Special Offers lock screen. |
| Kindle restarted by itself | Run `dmesg \| grep -i "reboot reason"`. `PWRON_LONGPRESS` = the power button was held for about 9 s, not a crash. |
| Dashboard did not come back after a reboot | Check `log.txt` for `autostart:` lines and look for `lpdash/autostart.off` (the boot-loop guard creates it after 3 boots within 15 min). `/etc/upstart/kmc.conf` must exist. |
| App opens then closes, or the Store opens instead | Don't launch through the Store or Mesquito: online, the Store loads Amazon's page. Use the registered WAF app (`register_waf.sql`). The scriptlet re-registers it if it is missing. |
| Two daemons, doubled API calls | Check the pidfile against `/proc/<pid>/cmdline`, kill the extra one. |

**Useful device commands:**
- `lipc-get-prop com.lab126.powerd state`, which returns `active`, `screenSaver` and so on.
- `lipc-probe com.lab126.powerd`
- `lipc-set-prop com.lab126.powerd flIntensity 0` (frontlight off)
- `/mnt/us/libkh/bin/fbink -s -f` (full flashing refresh)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.