new tasks, devnet topup, cli, new model support
This commit is contained in:
65
docs/issues/41-account-wallet-keypair.md
Normal file
65
docs/issues/41-account-wallet-keypair.md
Normal file
@@ -0,0 +1,65 @@
|
||||
# US-041 — Account wallet: browser-extension signing, in-browser generation, export-only
|
||||
|
||||
Status: planned
|
||||
Priority: Medium (not needed for devnet friends test; needed before mainnet)
|
||||
Stage: Designed
|
||||
|
||||
## Context
|
||||
|
||||
Registration accepts an optional `wallet` field (a pubkey string) and the
|
||||
dashboard never shows it. Users need a visible wallet address on the account
|
||||
panel and a path to real Solana later, without the tracker ever holding user
|
||||
private keys.
|
||||
|
||||
Today wallets matter in two places: client deposit attribution
|
||||
(`bind_wallet` → deposit watcher) and node payout identity (Pending Balance
|
||||
keyed by wallet). Accounts themselves hold no keypair — and will stay that way.
|
||||
|
||||
## Decision (2026-07-06)
|
||||
|
||||
**Non-custodial.** The tracker stores public keys only; private keys never
|
||||
leave the browser.
|
||||
|
||||
1. **External wallets via browser extension.** The dashboard integrates the
|
||||
standard Solana wallet-adapter flow (Phantom, Solflare, …): connect the
|
||||
extension, prove ownership by signing a nonce, and the verified pubkey is
|
||||
stored as the account wallet. All future transaction authorization
|
||||
(deposits; later, anything requiring a user signature) happens in the
|
||||
extension — the tracker only ever sees signatures and pubkeys.
|
||||
2. **New wallets generated in-browser.** For users without an extension the
|
||||
dashboard generates a keypair client-side (dashboard JS, `Ed25519` via
|
||||
WebCrypto or bundled tweetnacl — CSP-safe, no CDN). The pubkey is uploaded;
|
||||
the private key is shown once for export (base58, plaintext acceptable for
|
||||
devnet) with a "save this now" warning, and optionally kept in
|
||||
localStorage for convenience on devnet.
|
||||
3. **No private-key import.** Users cannot paste an existing private key into
|
||||
the dashboard — accepting foreign private keys is a liability the project
|
||||
refuses. Users with existing wallets use the extension path (which imports
|
||||
nothing; it signs in place).
|
||||
|
||||
## Scope
|
||||
|
||||
- Account panel shows the account wallet address (copy button) or the two
|
||||
attach flows (connect extension / generate in browser)
|
||||
- `POST /v1/account/wallet` — session-authenticated; body carries pubkey and,
|
||||
for the extension flow, the signed-nonce ownership proof (reuse
|
||||
`wallet_proof.py` if it fits); binds the wallet to the account's keys for
|
||||
deposit attribution (existing `bind_wallet` path)
|
||||
- Wallet is per-account; the tracker fans the binding out to the account's
|
||||
API keys internally
|
||||
- Mainnet cutover remains config-only (same boundary as Mock USDT, ADR-0015)
|
||||
|
||||
Out of scope: password-wrapped keystore export, hardware wallets, changing
|
||||
the node/miner wallet flow.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- Connect-extension flow stores a verified pubkey (rejects unsigned/mismatched
|
||||
nonce proofs)
|
||||
- Generate flow: pubkey lands on the account; private key is never sent to the
|
||||
tracker (assert no such field in the request), export works
|
||||
- No endpoint or UI accepts a private key
|
||||
- Deposits to the shown address credit the account's keys via the existing
|
||||
watcher
|
||||
- Address visible on the account panel after either flow
|
||||
- `python -m pytest` passes from repo root
|
||||
Reference in New Issue
Block a user