- L-1: Remove internal error details from SIWE verify response
- L-2: Stop forwarding raw Safe API error bodies to clients (log server-side)
- L-3: Evict stale keys from nonce rate limiter to prevent memory leak
- L-4: Add input length/type guards on wallet-link verify body fields
- L-5: Sanitize and cap limit query param on Safe transfers route (max 200)
- L-6: Server recomputes addressHash from SIWE address instead of trusting
client-supplied value for dedup
- L-7: Reset LinkedWalletStore singleton on logout to clear cached keys
- I-1: Add X-Content-Type-Options, X-Frame-Options, Referrer-Policy headers
- I-9: Build EIP712Domain type array dynamically from domain fields in
ExternalSigner.signTypedData (was hardcoded to empty, dropping fields)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Users can now connect browser wallets (MetaMask, Rainbow, etc.) to their
EncryptID identity via SIWE ownership proof, and view linked wallet
balances in the unified rWallet viewer.
New files:
- eip6963.ts: EIP-6963 multi-provider discovery
- external-signer.ts: EIP-1193 provider wrapper for tx signing
- linked-wallets.ts: encrypted client-side store (same AES-256-GCM pattern)
Server: wallet-link nonce/verify/list/delete routes, linked_wallets table,
Safe add-owner-proposal endpoint, new session permissions.
UI: "My Wallets" section with provider picker, SIWE linking flow,
wallet type badges, and click-to-view for linked wallets.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>