docs: reconcile AGENTS.md with actual code (EIP-712 chainId, loadWallets verification, Aave endpoint)

This commit is contained in:
Dione
2026-06-15 16:40:58 +00:00
parent d27efd4b90
commit b7eb8ece97

View File

@ -55,7 +55,7 @@ The codebase is split into three vanilla ESM modules plus the single-page dashbo
- `walletCosts` / `walletBuys` — cost basis per wallet
- **API endpoints** (proxied through nginx):
- `GET /api/v1/prices/{symbol}/history?range=N` — price history
- `GET /api/v1/portfolio/{address}/base/aave` — Aave portfolio snapshots
- `GET /api/v1/portfolio/{address}/{chain}/aave` — Aave portfolio snapshots (chain-parameterized)
- **BTC price** fetched directly from Kraken: `https://api.kraken.com/0/public/OHLC?pair=XBTUSD&interval=1440`
- **Polling:** `setInterval` every 30s with a 60s throttle on the Aave endpoint
- **Tracked wallet:** `0x0c1a4a060e119f981412e323104d1c134d413dba` ("penguin", Base)
@ -82,7 +82,7 @@ stream.connect();
| Method | Description |
|---|---|
| `loadWallets()` | Reads from localStorage, sanitizes (always `isVerified: false`) |
| `loadWallets()` | Reads from localStorage, sanitizes — preserves `isVerified` only when `messageData` is present; btc/bitcoin/solana always kept; unverified EVM wallets discarded |
| `addWallet(address, chain, nickname)` | Validates format, appends, persists |
| `removeWallet(address, chain)` | Drops from state, persists |
| `verifyWallet(address, chain, signature, messageData)` | Sets `isVerified: true` |
@ -98,7 +98,7 @@ stream.connect();
| `triggerWalletVerification(chain, nickname)` | Full flow: eth_requestAccounts → EIP-712 sign → add + verify |
| `connect()` | Quick connect check (no signature) |
EIP-712 domain: `{ name: "Anonymous Wallet Tracker", version: "1", chainId: 1 }`
EIP-712 domain: `{ name: "Anonymous Wallet Tracker", version: "1", chainId }` where `chainId` is per-chain (ethereum=1, base=8453, arbitrum=42161, optimism=10, polygon=137, avalanche=43114, bsc=56, fantom=250, hyperevm=999; fallback 1).
### WalletStreamManager
@ -117,13 +117,13 @@ Cross-tab leader election uses `BroadcastChannel("dione_shared_stream")` with a
- `apiBase = window.location.origin` — the dashboard relies on nginx proxy to reach the backend at `192.168.1.102:8000`. Running without Docker/proxy means the Aave table and price charts fail silently.
- No linting, no type-checking, no CI. Validate changes by opening the HTML in a browser.
- Adding chart data? Update the embedded arrays (`walletCumulData`, etc.) — they are plain JS arrays of `[timestampMs, value]` pairs.
- `wallets.js` always forces `isVerified: false` on `loadWallets()` — persisted signatures are discarded. Verification must go through `WalletVerifier`.
- `wallets.js` preserves `isVerified` on `loadWallets()` only when `messageData` is present — unverified EVM wallets are discarded on reload. btc/bitcoin/solana wallets are always kept. Verification must go through `WalletVerifier`.
## Transaction Ledger Table — Data Flow
How the table gets its rows and values:
1. **Fetch:** `fetchAllWalletData()``fetchWalletAaveData(address)` hits `/api/v1/portfolio/{address}/base/aave`, returns array of snapshot events.
1. **Fetch:** `fetchWalletAaveData(address, chain)` hits `/api/v1/portfolio/{address}/{chain}/aave` (chain-parameterized, defaults `base`), returns array of snapshot events.
2. **Deduplicate:** `snapshotsToDaily(events)` collapses events to one per day (keeps latest `block_timestamp` per day). **Result is sorted newest-first.**
3. **Store:** Deduplicated snapshots land in `addressSnapshots[address]`.
4. **Prices:** `fetchPrices(symbols, oldestDateMs)` fetches `/api/v1/prices/{symbol}/history?range=N` where N = days between now and oldest snapshot. **Critical:** you must scan all snapshots for the *lowest* `block_timestamp` to compute the correct range. `snapshots[0]` is the *newest* — never assume the array is oldest-first. The `aavePriceMap` is keyed `[priceSymbol][dateStr] = closePrice`.