File size: 8,130 Bytes
e344944 83006bc e344944 3f9464a e344944 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | ---
license: apache-2.0
pretty_name: Sentinel-Witness
tags:
- trading
- dashboard
- ledger
- crypto
---
# Ledger Trading Dashboard
Phone-first PWA: Ledger hardware wallet + Coinbase/Kraken/Crypto.com, staged
dashboard β manual-approval β automated execution, driven by walk-forward-
validated grid/bracket strategy parameters (see the companion `strategy/`
Python project) with a real-time adaptive layer on top.
## What's actually tested vs. what needs your device
This was built in a sandboxed environment with no access to Coinbase/
Kraken/Crypto.com's APIs, no WebHID, no real Ledger. That shaped what
"tested" can honestly mean here:
| Module | Tested | How |
|---|---|---|
| `secureStorage.js` | Yes | Full encrypt/decrypt round trip, wrong-passphrase-fails-closed, fresh salt/IV per save β real IndexedDB via `fake-indexeddb`, not mocked |
| `gridMath.js` | Yes | Lookahead safety, capital-safety invariant, parity against the Python engine's validated $12 dead-weight case, throttle-never-hits-zero |
| `exchanges/kraken.js`, `cryptocom.js` signing | Yes | Determinism, structural correctness (output length/format), key-order invariance |
| `exchanges/coinbase.js` JWT | Partially | ES256 JWT structure and signature cryptographically verified against a generated key pair β confirms the *mechanism* is right. Does **not** confirm a real Coinbase CDP key imports cleanly; that needs your actual key |
| `tradeGate.js` tier enforcement | Yes | Every limit-rejection path, tier-gating path, and the "no unlimited option" guarantee, via a mock exchange |
| `ledger.js` | No β cannot be | Needs a real browser (WebHID) and a real device |
| Live exchange calls (balances, order placement) | No β cannot be | This sandbox's network can't reach any of the three exchanges |
| UI (`Dashboard.jsx`, `App.jsx`) | No β cannot be | Needs a real browser |
Run `npm test` to re-run everything that *can* run outside a browser.
## Setup
```
npm install
npm run dev # local dev server
npm run build # production build, output in dist/
```
### Exchange credentials
- **Kraken**: create an API key with Query Funds + Create/Cancel orders
permissions (not Withdraw). Enter the key + secret in the app; they're
encrypted with your passphrase and stored only in this browser's
IndexedDB.
- **Crypto.com**: same shape (API key + secret), trading permissions only.
- **Coinbase**: create a CDP API key (Advanced Trade). The downloaded
private key must be PKCS8 PEM (`-----BEGIN PRIVATE KEY-----`). If yours
says `-----BEGIN EC PRIVATE KEY-----`, convert it first:
`openssl pkcs8 -topk8 -nocrypt -in your-key.pem -out converted.pem`
None of these should ever have withdrawal permission. This app only ever
needs to read balances and place/cancel limit orders.
## Security model
- **Ledger**: signing happens on-device with a physical confirmation.
This code never sees a seed phrase or private key β see `ledger.js`'s
docstring. WebHID (required for the Ledger connection) works in Chrome/
Edge on desktop and Android; it does **not** work in any iOS browser,
including Safari-based ones on iPhone. On iOS, this needs a native app
with Ledger's Bluetooth SDK instead β flagged, not built here.
- **Exchange credentials**: AES-GCM encrypted with a key derived from
your passphrase (PBKDF2, 210k iterations), stored in this browser's
IndexedDB. This is real protection against someone reading files off
disk. It is **not** equivalent to a native app's OS Keychain/Keystore β
a PWA can't reach either. See `secureStorage.js` and the in-app
`SecurityNotice` component.
- **Trade execution guardrails**: all enforced in `tradeGate.js`, not
just documented β automated tier refuses to start without finite,
positive `maxPerTradeUsd` and `maxDailyTradesCount` (no unlimited
option), both re-checked on every signal, not just at setup. Every
execution path requires the Ledger confirmation step; there is no
code path that skips it.
## What's genuinely not built yet
- **XRP unsigned-transaction-blob assembly.** `tradeGate.executeApprovedSignal()`
gets all the way to calling the Ledger and reading the address, then
throws an explicit `not_implemented` error rather than faking a
completed trade. Turning a `{pair, price, quantity}` signal into the
actual bytes `signXrpTransaction()` needs to sign (proper XRP Ledger
transaction encoding, sequence numbers, fees, submission to a node)
is real protocol work not done in this pass β flagged loudly rather
than stubbed quietly, per this whole project's standing rule about
silent failures being the dangerous kind.
- PWA icons (`icon-192.png`, `icon-512.png` referenced in `vite.config.js`)
aren't generated.
- Only XRP is wired through the UI/gate end-to-end; the strategy guide
covers DOGE too (see `src/lib/strategyGuide.js`) but the app only
asks for one asset right now.
## Automated-tier setup
`AutomatedSetupModal.jsx` replaced the earlier `prompt()`/`alert()`
placeholder. Real form, real inline validation (mirrors
`tradeGate.js`'s own `enableAutomated()` check exactly β see
`src/lib/automatedLimits.js` β so the UI never blocks something the gate
would allow or vice versa), and a live "worst-case daily deployment"
figure (`maxPerTradeUsd Γ maxDailyTradesCount`, related to current USD
balance when known) so the two numbers you're locking in mean something
concrete before you confirm, not just two blank fields. Covered by
`src/lib/__tests__/automatedLimits.test.js`.
While wiring this in, found and fixed a second bug: the "Dashboard" tier
button rendered clickable while at manual/automated tier (stepping down
is deliberately always open, from any tier β see `tierNavigation.js`),
but `handleTierChange` had no branch for it, so tapping it silently did
nothing. Confirmed empirically before fixing (not assumed), and now
covered by `src/lib/__tests__/tierNavigation.test.js`, which asserts the
dashboard-tier case directly rather than just the fields it happened to
break in.
## Re-generating the strategy guide
`src/lib/strategyGuide.js` embeds a snapshot from
`recursive_strategy_optimizer.py` (the Python walk-forward optimizer, in
the companion `strategy/` project β re-run that periodically, it's
designed for it). Either replace the `BAKED_IN_GUIDE` constant with fresh
output, or host the JSON somewhere and call `refreshGuide(url)` so the
app picks up updates without a rebuild.
---
## Part of one system β each piece usable on its own
These repositories are independent instruments that also compose into a single apparatus for **building and honestly auditing trustworthy multi-intelligence systems**. Any one can be used standalone; together they form the stack:
- **Governed core** β [covenant](https://huggingface.co/Lawless1987/covenant): a self-governing multi-agent system with an ethics gate inside the transaction path.
- **Observability & provenance** β [threefold](https://huggingface.co/Lawless1987/threefold) (the L-lens layer over Jacobian Lens) and [threefold-memory](https://huggingface.co/Lawless1987/threefold-memory) (its persistent, provenance-tracked memory): every action measured and recorded under one task identity.
- **Measurement instruments** β [contradiction-probe](https://huggingface.co/Lawless1987/contradiction-probe) and [flinch-observability](https://huggingface.co/Lawless1987/flinch-observability), with the session records [flinch-record](https://huggingface.co/Lawless1987/flinch-record) and [grokflinch](https://huggingface.co/Lawless1987/grokflinch): preregistered, blind-scored tests of AI behaviour that embody the covenant's rule β *investigate a signal, never convict on one*.
- **Neuromorphic research** β [spiking-experiments](https://huggingface.co/Lawless1987/spiking-experiments): from-scratch spiking-network experiments with the pass/fail bar declared before each run.
- **Ledger surface** β [Sentinel-Witness](https://huggingface.co/Lawless1987/Sentinel-Witness): the trading / ledger dashboard.
**This repository's place in it:** the ledger / trading-dashboard surface.
|