Skip to content

Commit dfadebf

Browse files
Copexitclaude
andcommitted
fix: comprehensive privacy engine and accessibility improvements
10-iteration automated review cycle covering bitcoin privacy auditor and UI/UX reviewer agents. Key changes: Privacy engine: - Add OFAC sanctions check to pre-send destination flow - Fix cluster analysis self-reuse bug (was following payment recipients as change) - Expand CoinJoin cross-heuristic suppression from 5 to 9 finding types - Recalibrate address reuse penalties and batch payment edge case - Remove overly generic wallet fingerprint signals (nLockTime=0, nVersion) - Add WabiSabi multi-tier denomination detection - Fix spending analysis counting CoinJoin outputs as counterparties - Wire AbortSignal through entire API layer (fetch retry, rate limiter, pagination) - Add cancellable sleep to fetchWithRetry, immediately re-throw AbortError - Case-insensitive OFAC bech32 matching, stricter address validation regex - Correct methodology page impact ranges for H6, H7, H8, H9, H12, H15 Accessibility: - Add skip-to-content link, aria-live phase announcements - Add focus trap in ApiSettings panel with focus restore - Remove all focus:outline-none overrides (12 instances) - Fix text contrast (eliminate muted/30, muted/40; upgrade muted/50 on content) - Add 44px touch targets on action bars, toggles, triggers, dismiss buttons - Add prefers-reduced-motion support (CSS + JS) - Fix 320px mobile overflow in PreSendResultPanel and TxSummary UI polish: - Make ConnectionBadge tappable with tooltip on mobile - Fix TipToast/InstallPrompt overlap (stack vertically) - Remove duplicate "100% client-side" from footer - Replace all em dashes with hyphens across codebase and docs - Remove onion.md from tracking, add to .gitignore Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 974b502 commit dfadebf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1160
-646
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,4 @@ ROADMAP.md
4444
claw_braindump.md
4545
screenshots/
4646
cex_braindump.md
47+
onion.md

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ In April 2024, [OXT.me](https://oxt.me) and [KYCP.org](https://kycp.org) went of
1414

1515
As of today, there is no publicly available tool that combines entropy estimation, wallet fingerprinting detection, CoinJoin pattern recognition, and dust attack warnings in a single interface. **am-i.exposed** fills that gap.
1616

17-
For the full technical deep-dive every heuristic, scoring weight, academic reference, threat model, and competitor analysis see [`privacy_engine.md`](./privacy_engine.md).
17+
For the full technical deep-dive - every heuristic, scoring weight, academic reference, threat model, and competitor analysis - see [`privacy_engine.md`](./privacy_engine.md).
1818

1919
## How it works
2020

@@ -28,7 +28,7 @@ For the full technical deep-dive — every heuristic, scoring weight, academic r
2828
**Your queries are not fully private.** Analysis runs client-side, but your browser makes API requests to [mempool.space](https://mempool.space) to fetch blockchain data. Their servers can see your IP address and which addresses/transactions you look up.
2929

3030
For stronger privacy:
31-
- Use **Tor Browser** the tool auto-detects Tor and routes API requests through the mempool.space `.onion` endpoint
31+
- Use **Tor Browser** - the tool auto-detects Tor and routes API requests through the mempool.space `.onion` endpoint
3232
- Use a **trusted, no-log VPN**
3333
- **Wait** before querying a recent transaction (timing correlation is a real risk)
3434

@@ -38,11 +38,11 @@ There is no am-i.exposed backend. No analytics. No cookies. No tracking. The sta
3838

3939
| Grade | Score | Meaning |
4040
|-------|-------|---------|
41-
| A+ | 90-100 | Excellent you know what you're doing |
42-
| B | 75-89 | Good minor issues |
43-
| C | 50-74 | Fair notable concerns |
44-
| D | 25-49 | Poor significant exposure |
45-
| F | 0-24 | Critical you might as well use Venmo |
41+
| A+ | 90-100 | Excellent - you know what you're doing |
42+
| B | 75-89 | Good - minor issues |
43+
| C | 50-74 | Fair - notable concerns |
44+
| D | 25-49 | Poor - significant exposure |
45+
| F | 0-24 | Critical - you might as well use Venmo |
4646

4747
Scoring starts at a base of 70. Each heuristic applies a positive or negative modifier. The sum is clamped to 0-100. Only CoinJoin participation, Taproot usage, and high entropy can raise the score. Everything else can only lower it.
4848

@@ -55,11 +55,11 @@ Scoring starts at a base of 70. Each heuristic applies a positive or negative mo
5555
| **Round amount detection** | Round BTC/sat outputs that reveal payment vs change |
5656
| **Change detection** | Address type mismatch, unnecessary inputs, round-amount change, output ordering |
5757
| **Common input ownership (CIOH)** | Multi-input txs that link all your addresses to the same entity |
58-
| **CoinJoin detection** | Whirlpool, Wasabi/WabiSabi, and JoinMarket patterns the only positive signal |
59-
| **Entropy estimation** | Simplified Boltzmann how many valid input-output mappings exist |
58+
| **CoinJoin detection** | Whirlpool, Wasabi/WabiSabi, and JoinMarket patterns - the only positive signal |
59+
| **Entropy estimation** | Simplified Boltzmann - how many valid input-output mappings exist |
6060
| **Fee analysis** | Round fee rates and RBF signaling that narrow wallet identification |
6161
| **OP_RETURN metadata** | Permanent embedded data (Omni, OpenTimestamps, Runes, ASCII text) |
62-
| **Wallet fingerprinting** | nLockTime, nVersion, nSequence, BIP69 ordering, low-R signatures identifies wallet software |
62+
| **Wallet fingerprinting** | nLockTime, nVersion, nSequence, BIP69 ordering, low-R signatures - identifies wallet software |
6363
| **Script type mix** | Mixed address types across inputs/outputs that distinguish sender from recipient |
6464
| **Anonymity set estimation** | How large the set of indistinguishable participants is |
6565
| **Timing analysis** | Transaction patterns that correlate with off-chain behavior |
@@ -68,7 +68,7 @@ Scoring starts at a base of 70. Each heuristic applies a positive or negative mo
6868

6969
| Heuristic | What it detects |
7070
|-----------|----------------|
71-
| **Address reuse** | The #1 privacy killer harshest penalty in the model |
71+
| **Address reuse** | The #1 privacy killer - harshest penalty in the model |
7272
| **UTXO set exposure** | Dust attack detection (<1000 sats), consolidation risk, UTXO count |
7373
| **Address type** | P2TR (Taproot) > P2WPKH (SegWit) > P2SH > P2PKH (Legacy) |
7474
| **Spending patterns** | How funds have moved through the address over time |
@@ -79,14 +79,14 @@ The engine doesn't run heuristics in isolation. CoinJoin detection suppresses CI
7979

8080
## Tech
8181

82-
- **Next.js 16** static export no server, hosted on GitHub Pages
83-
- **Client-side analysis** heuristics run in your browser, not on a server
82+
- **Next.js 16** static export - no server, hosted on GitHub Pages
83+
- **Client-side analysis** - heuristics run in your browser, not on a server
8484
- **mempool.space API** primary, **Blockstream Esplora** fallback (mainnet only)
85-
- **Tor-aware** auto-detects `.onion` and routes API requests through Tor
85+
- **Tor-aware** - auto-detects `.onion` and routes API requests through Tor
8686
- **TypeScript** throughout
87-
- **Tailwind CSS 4** dark theme
88-
- **PWA** installable, works offline (after first load)
89-
- **bitcoinjs-lib** raw transaction parsing for wallet fingerprinting
87+
- **Tailwind CSS 4** - dark theme
88+
- **PWA** - installable, works offline (after first load)
89+
- **bitcoinjs-lib** - raw transaction parsing for wallet fingerprinting
9090

9191
## Development
9292

TODO-custom-api.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Let advanced users point the tool at their own mempool.space instance (local or remote) instead of the public one. Privacy-conscious users run their own node + mempool and don't want to leak queries to mempool.space.
55

66
## UX
7-
- **NOT in your face** this is for power users only
7+
- **NOT in your face** - this is for power users only
88
- Small gear/settings icon in the footer or header, or a collapsible "Advanced" section below the input
99
- Clicking opens a minimal panel with a single text field: "Custom API endpoint"
1010
- Placeholder: `https://mempool.space/api` (the default)
@@ -16,18 +16,18 @@ Let advanced users point the tool at their own mempool.space instance (local or
1616
- Store in localStorage key: `ami-custom-api-url`
1717
- Validate: must be a URL, should respond to `/api/blocks/tip/height` (quick health check)
1818
- Pass through to the existing API client (`src/lib/api/client.ts` or `src/lib/api/mempool.ts`)
19-
- Fallback behavior: if custom endpoint fails, ask user don't silently fall back to public (that would defeat the privacy purpose)
19+
- Fallback behavior: if custom endpoint fails, ask user - don't silently fall back to public (that would defeat the privacy purpose)
2020
- Update CSP in layout.tsx to allow `connect-src` to any https origin when custom URL is set (or use a meta tag override)
2121

2222
## Examples of custom endpoints
23-
- `http://localhost:8999/api` local mempool instance
24-
- `http://umbrel.local:3006/api` Umbrel node
25-
- `https://mempool.mydomain.com/api` self-hosted remote
26-
- `http://mempoolhqx4isw62xs7abwphsq7ldvnlk5.onion/api` Tor
23+
- `http://localhost:8999/api` - local mempool instance
24+
- `http://umbrel.local:3006/api` - Umbrel node
25+
- `https://mempool.mydomain.com/api` - self-hosted remote
26+
- `http://mempoolhqx4isw62xs7abwphsq7ldvnlk5.onion/api` - Tor
2727

2828
## CSP consideration
2929
The current CSP only allows `connect-src` to mempool.space and blockstream.info. A custom URL needs to either:
30-
1. Relax CSP when custom URL is set (via JS, not meta tag meta tags are static)
30+
1. Relax CSP when custom URL is set (via JS, not meta tag - meta tags are static)
3131
2. Or remove the connect-src restriction entirely and rely on the user's judgment
3232

3333
Option 2 is simpler and fine for a privacy tool aimed at technical users.

onion.md

Lines changed: 0 additions & 219 deletions
This file was deleted.

0 commit comments

Comments
 (0)