Commit Graph
6 Commits
Author SHA1 Message Date
selimaj-devandclaude 7f8270a048 Replace threshold placeholder link with a real settings panel
Adds a "Loss thresholds" panel to the popup backed by the backend's
new GET/PATCH /me/settings endpoints, converting between the wire's
fractional percentages and whole-number form inputs only at that
boundary.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RTorFQXMR9ZQtCKcMTXLHp
2026-09-08 02:38:46 +02:00
selimaj-devandclaude 8d104ef3cf Fix duplicate signing; make account switching an explicit action
Root cause of "requires a lot of signs, not just a single one":
inject.ts wired Phantom's own accountChanged provider event to
auto-trigger re-auth, but calling connect() ourselves also fires that
same event -- so a normal silent reconnect raced its own
event-triggered handler, producing two competing "wallet connected"
reports that each independently asked Phantom to sign a fresh nonce.

Removed that event wiring entirely (onWalletEvent, EVENT_CHANNEL) --
inject.ts now only responds to our own explicit calls, never reacts
to unsolicited provider events. Per feedback, account switching isn't
something that should be inferred from a Phantom event anyway; it's
now its own explicit feature: a "Switch account" button in the popup
(nexa:switch-account) that tells the content script to disconnect and
immediately reconnect, so Phantom's connect UI reflects whichever
account is currently active there.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YXiHuScXrjxBh7yFGAPq3B
2026-09-07 14:02:11 +02:00
selimaj-devandclaude b93a9c6f10 Support Phantom account switching and add sign-out
Wires Phantom's own accountChanged/disconnect provider events
(inject.ts) so switching accounts or disconnecting directly in
Phantom's UI is detected, not just our own connect/sign calls --
relayed as unsolicited postMessage events (relay.ts's onWalletEvent)
since they aren't a response to any request we made.

Adds a "Sign out" button in the popup (nexa:sign-out) that clears the
stored session, force-closes the WS connection via a new
ws-client.ts disconnect() (distinct from reconnectNow() -- it also
suppresses auto-reconnect until a new wallet connects), and asks the
content script to call provider.disconnect(), which revokes
Phantom's trust for the origin so the next silent connect correctly
fails until the user reconnects.

Fixes a real bug this surfaced: the existing "skip re-auth if a
session token exists" check in background.ts only checked for *any*
token, so switching Phantom accounts would have silently kept
authenticating as the old wallet. Session storage now tracks which
wallet it belongs to (backend-client.ts's storeSession(token,
walletAddress)) so the handler can tell "already signed in" apart
from "signed in as a different wallet than the one that just
connected."

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YXiHuScXrjxBh7yFGAPq3B
2026-09-07 13:48:05 +02:00
selimaj-devandclaude 56a2ff9930 Replace stub wallet keypair with real Phantom sign-in
Auth now goes through an actual connected Solana wallet instead of a
locally-generated ed25519 keypair. Phantom's window.solana provider
is only reachable from a page's own JS world, not an isolated-world
content script, so this adds a second world:'MAIN' content script
(wallet-bridge.content.ts + wallet-bridge/inject.ts) that talks to
window.solana directly and relays to the isolated world via window
CustomEvents (wallet-bridge/relay.ts), matched by request id.

wallet-connect.ts orchestrates: try a silent onlyIfTrusted connect on
load; if that fails, show an on-page banner (wallet-bridge/banner.ts)
whose click handler is what actually calls connect() -- Phantom
requires a real user gesture for the approval popup on a first-ever
connect, which a click relayed from the extension popup wouldn't
count as by the time it reaches the wallet.

background/wallet-auth.ts runs the REST auth flow (nonce -> ask the
tab's content script to sign it -> verify -> store session token)
once a wallet reports connected. ws-client.ts no longer force-retries
with a known-bad token on auth failure; it calls onAuthExpired
instead (which clears the token and prompts a silent wallet
reconnect) and exposes reconnectNow() so background.ts can
short-circuit the backoff wait once a fresh token exists.

identity.ts and its tweetnacl dependency are gone -- no more stub
signer.

Untested against real Phantom (no browser automation available this
session) -- flagged in CLAUDE.md as needing manual verification,
along with a note that world:'MAIN' needs Firefox 128+.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YXiHuScXrjxBh7yFGAPq3B
2026-09-07 12:20:17 +02:00
selimaj-devandclaude 3b6054f2f0 Connect to the real Nexa backend, replacing the mock lock toggle
Adds the wire-protocol WebSocket client (ws-client.ts) and the REST
auth flow (backend-client.ts) against the now-live backend, using a
locally-generated ed25519 keypair (identity.ts) as a stand-in wallet
signer until real wallet-extension integration is built.

lock-state.ts's setLockState is now applyLockState, called only by
the WS client on an incoming lock_state message -- the backend is
the sole source of truth for lock state, so there's no other writer
anymore. The popup's dev mock controls are replaced with a live
connection-status + lock-state display.

Verified end-to-end against the real backend (nonce -> verify -> /me
-> ws lock_state) using the same tweetnacl/bs58 libs shipped in the
extension.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01YXiHuScXrjxBh7yFGAPq3B
2026-09-07 09:10:18 +02:00
selimaj-dev 9362c9ac80 Lesss gooo claude 2026-09-06 11:44:59 +02:00