From b7eb8ece9742885f4af3c8d3bc550ea6b66356db Mon Sep 17 00:00:00 2001 From: Dione Date: Mon, 15 Jun 2026 16:40:58 +0000 Subject: [PATCH] docs: reconcile AGENTS.md with actual code (EIP-712 chainId, loadWallets verification, Aave endpoint) --- AGENTS.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 91707e6..fd7c912 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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`.