Skip to content

Commit e1619e1

Browse files
committed
Merge branch 'identity-upgrade'
2 parents 505281a + ed80ebe commit e1619e1

284 files changed

Lines changed: 41995 additions & 4367 deletions

File tree

Some content is hidden

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

.github/workflows/tests.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: Tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
matrix:
15+
node-version: [20, 22]
16+
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Use Node.js ${{ matrix.node-version }}
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: ${{ matrix.node-version }}
24+
25+
- name: Run crypto tests
26+
run: node --test tests/crypto/*.test.js
27+
28+
- name: Run module tests (vault, permissions, accounts)
29+
run: node --import ./tests/helpers/register-mocks.js --test tests/vault.test.js tests/permissions.test.js tests/accounts.test.js

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,41 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [0.2.0] - 2025-02-24
6+
7+
### Added
8+
- **NIP-07 Identity Provider** — full `window.nostr` signer (getPublicKey, signEvent, getRelays, nip04, nip44)
9+
- **Encrypted Key Vault** — AES-256-GCM with PBKDF2 (210,000 iterations), auto-lock timer
10+
- **Multi-account support** — generated (BIP-39/NIP-06), imported nsec, watch-only npub, NIP-46 bunker, external signer
11+
- **Per-account IndexedDB** — each identity gets its own `nostr-wot-{accountId}` database
12+
- **Onboarding wizard** — first-run setup flow for account creation and import
13+
- **Signing prompt system** — popup window for approving/denying NIP-07 requests with remember option
14+
- **Permission system** — per-domain, per-method, per-event-kind permission storage and cascade
15+
- **NIP-46 Nostr Connect** — remote signing via bunker:// URLs
16+
- **WoT trust badges** — visual hop-distance badges injected into Nostr web clients (Primal, Snort, Nostrudel, Coracle, Iris, generic fallback)
17+
- **Activity logging** — tracks signing operations per domain (capped at 200 entries)
18+
- **Pure JS crypto library** — secp256k1, Schnorr (BIP-340), NIP-01, NIP-04, NIP-44, BIP-32, BIP-39, bech32
19+
- **Internationalization** — i18n support with English and Spanish locales
20+
- **Test suite** — node:test based tests for crypto, vault, signer, permissions, accounts
21+
- **CI pipeline** — GitHub Actions workflow for automated testing
22+
- **CONTRIBUTING.md** — contributor guide with project structure and guidelines
23+
- **docs/architecture.md** — full technical architecture reference
24+
- **docs/add_badge.md** — guide for adding badge support to new Nostr clients
25+
- **SECURITY.md** — security model documentation
26+
27+
### Changed
28+
- **API: `isConfigured()``getStatus()`** — returns `{ configured, mode, hasLocalGraph }` instead of a boolean
29+
- **API: removed `getDistanceBetween()`** — third-party distance queries removed for privacy (surveillance vector)
30+
- Precomputed BFS cache with O(1) lookups via typed arrays (Uint8Array hops, Uint32Array paths)
31+
- Delta-encoded follow storage format (sorted Uint32Array deltas)
32+
- Background rate limiter: 10 req/sec per method (sliding window)
33+
- Privileged method gating via sender ID verification
34+
- Version bump to 0.2.0
35+
36+
### Fixed
37+
- Sync crash when triggered without a valid pubkey
38+
- Graph syncing reliability improvements
39+
540
## [0.1.1] - 2025-02-17
641

742
### Added

CLAUDE.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Self-Review Checklist
2+
3+
Every code change must pass through these gates. No exceptions, no shortcuts.
4+
5+
## Before Commiting Code
6+
Read existing code and documentation before commiting anything.
7+
8+
1. **Run the build**`npm run build` must succeed with no errors.
9+
2. **Run full suite**`./tests/run.sh` (module tests may hang after completion due to open handles in mock — this is known, not a failure).
10+
3. **Do not coauthor or cosign commits**.
11+
12+
## Before Writing Code
13+
14+
Read existing code and documentation before modifying anything.
15+
16+
**Always read:**
17+
- The file you're about to modify
18+
- Its existing tests (search `tests/` for matching filenames)
19+
20+
**Read based on what you're changing:**
21+
22+
| Changing | Read first |
23+
|----------|-----------|
24+
| `lib/`, `background.ts`, `content.ts`, `inject.ts` | `docs/architecture.md`, `docs/message-flow.md` |
25+
| `lib/crypto/`, `lib/vault.ts`, `lib/signer.ts` | `docs/security.md` |
26+
| Message handling, new RPC methods | `docs/message-flow.md` |
27+
| `src/components/`, `src/popup/` | `docs/component-standards.md` |
28+
| Test files or test infrastructure | `docs/testing.md` |
29+
| Badge engine (`badges/engine.ts`) | `tests/badges/engine.test.ts` |
30+
31+
## After Writing Code
32+
33+
Complete every step before claiming work is done.
34+
35+
1. **Run targeted tests** — run the specific test file(s) for the area you changed.
36+
2. **Run the build**`npm run build` must succeed with no errors.
37+
3. **Verify test coverage** — every new or changed function must have a test. If none exists, write one. Work is not done until the test exists.
38+
4. **Update documentation** — if your change alters behavior described in any `docs/` file, update that doc in the same changeset. A code change without its corresponding doc update is incomplete work. Do not defer this.
39+
40+
**Hard rule:** Never claim "done" or "all tests pass" without actually running the commands and reading the output. No assumptions. No "should work." Show the TAP summary or build output.
41+
42+
## Anti-Rationalization
43+
44+
These thoughts mean stop and verify:
45+
46+
| If you think... | Do this instead |
47+
|-----------------|-----------------|
48+
| "This is a small change, it won't break anything" | Run the tests. |
49+
| "I know what this function does" | Read it. Read its tests. Then modify. |
50+
| "The docs probably don't cover this" | Check. They probably do. |
51+
| "I'll update the docs later" | Update them now, in this changeset. |
52+
| "Tests pass for the file I changed" | Run the full suite. Cross-module regressions are real. |
53+
| "This new function is simple enough it doesn't need a test" | It does. Write one. |
54+
| "The build will be fine" | Run it. Verify the output. |
55+
56+
## Key Commands
57+
58+
```bash
59+
# Targeted test (example: crypto)
60+
node --import tsx --test tests/crypto/*.test.ts
61+
62+
# Targeted test (example: badge engine)
63+
node --import tsx --test tests/badges/engine.test.ts
64+
65+
# Module tests (need browser mock)
66+
node --import tsx --import ./tests/helpers/register-mocks.ts --test tests/vault.test.ts tests/permissions.test.ts tests/accounts.test.ts tests/signer.test.ts tests/security-hardening.test.ts tests/communication.test.ts
67+
68+
# Full suite
69+
./tests/run.sh
70+
71+
# Build
72+
npm run build
73+
```

CONTRIBUTING.md

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# Contributing to Nostr WoT Extension
2+
3+
Thank you for your interest in contributing! This extension provides NIP-07 signing, Web of Trust distance checking, and trust score badge injection for Nostr web clients.
4+
5+
## Getting Started
6+
7+
### Prerequisites
8+
9+
- Node.js 18+ (for running tests)
10+
- Chrome or Firefox browser
11+
- Basic familiarity with browser extension development (MV3)
12+
13+
### Setup
14+
15+
```bash
16+
git clone https://github.com/user/nostr-wot-extension.git
17+
cd nostr-wot-extension
18+
```
19+
20+
No build step required — the extension uses plain ES modules with no bundler.
21+
22+
### Loading the Extension
23+
24+
**Chrome:**
25+
1. Open `chrome://extensions`
26+
2. Enable "Developer mode"
27+
3. Click "Load unpacked" and select the project directory
28+
29+
**Firefox:**
30+
1. Open `about:debugging#/runtime/this-firefox`
31+
2. Click "Load Temporary Add-on"
32+
3. Select any file in the project directory (e.g., `manifest.json`)
33+
34+
### Running Tests
35+
36+
```bash
37+
node --test tests/
38+
```
39+
40+
Tests use Node.js native `node:test` module with browser API mocks in `tests/helpers/`.
41+
42+
## Project Structure
43+
44+
```
45+
├── background.js # Service worker — all business logic
46+
├── content.js # Content script (ISOLATED world) — message bridge
47+
├── inject.js # Page script (MAIN world) — window.nostr API
48+
├── badges/
49+
│ ├── engine.js # Badge injection engine (MAIN world)
50+
│ ├── badges.css # Badge visual styles
51+
│ └── adapters/ # Per-site badge adapters
52+
│ ├── primal.js
53+
│ ├── snort.js
54+
│ ├── nostrudel.js
55+
│ ├── coracle.js
56+
│ ├── iris.js
57+
│ └── generic.js # Fallback for any site with npub links
58+
├── lib/
59+
│ ├── crypto/ # Pure JS crypto (secp256k1, schnorr, NIPs)
60+
│ ├── storage.js # IndexedDB per-account graph storage
61+
│ ├── sync.js # BFS graph sync from relays
62+
│ ├── graph.js # Precomputed BFS with typed array cache
63+
│ ├── scoring.js # Trust score calculation
64+
│ ├── vault.js # AES-256-GCM encrypted key vault
65+
│ ├── signer.js # NIP-07 signing coordinator
66+
│ ├── permissions.js # Per-site permission storage
67+
│ ├── accounts.js # Account creation/import
68+
│ ├── nip46.js # NIP-46 Nostr Connect client
69+
│ └── browser.js # Cross-browser compatibility shim
70+
├── popup/ # Extension popup (tab-based UI)
71+
├── onboarding/ # First-run setup wizard
72+
├── prompt/ # Signing request approval popup
73+
├── docs/
74+
│ ├── architecture.md # Technical architecture reference
75+
│ └── add_badge.md # Guide for adding badge support
76+
└── tests/ # Node.js test suite
77+
```
78+
79+
## Types of Contributions
80+
81+
### Adding Badge Support for a New Nostr Client
82+
83+
This is the easiest way to contribute. See [docs/add_badge.md](docs/add_badge.md) for the full guide.
84+
85+
**Quick version:**
86+
1. Inspect the target site's DOM structure
87+
2. Add a site adapter to `wot-badges.js`
88+
3. Test on the actual site
89+
4. Submit a PR with screenshots
90+
91+
### Bug Fixes
92+
93+
1. Check existing issues first
94+
2. Create a failing test case if possible
95+
3. Fix the bug
96+
4. Verify existing tests still pass: `node --test tests/`
97+
98+
### New Features
99+
100+
1. Open an issue to discuss the feature first
101+
2. Reference the relevant NIP if applicable
102+
3. Follow existing patterns in the codebase
103+
4. Add tests for new backend logic
104+
105+
## Pull Request Process
106+
107+
### 1. Fork and Branch
108+
109+
```bash
110+
git checkout -b feature/my-change
111+
```
112+
113+
Use these branch name prefixes:
114+
- `feature/` — new functionality
115+
- `fix/` — bug fixes
116+
- `badge/` — new site badge support
117+
- `docs/` — documentation
118+
119+
### 2. Make Changes
120+
121+
- Follow existing code style (no linter configured — match surrounding code)
122+
- Use plain ES modules, no build tools
123+
- Use optional chaining (`?.`) for DOM access
124+
- Zero private keys after use (`privkey.fill(0)` in `try/finally`)
125+
- Gate privileged message handlers via `PRIVILEGED_METHODS` Set
126+
- No external dependencies — the extension is self-contained
127+
128+
### 3. Test
129+
130+
```bash
131+
node --test tests/
132+
```
133+
134+
For UI changes, manually test in Chrome and Firefox:
135+
- Open the popup and verify all tabs work
136+
- Test dark mode (system preference)
137+
- Test with 0 accounts, 1 account, and multiple accounts
138+
- Test with both signing accounts and read-only accounts
139+
140+
### 4. Submit
141+
142+
- Write a clear PR title (e.g., "badge: add support for habla.news")
143+
- Describe what changed and why
144+
- Include screenshots for UI changes
145+
- Reference any related issues
146+
147+
## Architecture Notes
148+
149+
Read [docs/architecture.md](docs/architecture.md) for the full technical reference. Key points:
150+
151+
- **No build system** — files are loaded directly by the browser
152+
- **Message passing** — inject.js → content.js → background.js via `postMessage` and `runtime.sendMessage`
153+
- **Privileged methods** — vault, permission, and management operations are gated to internal extension pages via sender ID verification
154+
- **Per-account databases** — each account gets its own IndexedDB named `nostr-wot-{accountId}`
155+
- **Precomputed graph** — distances are cached in typed arrays for O(1) lookup after first query
156+
157+
## Security Guidelines
158+
159+
- Never log or expose private keys
160+
- Always zero `Uint8Array` private keys after use
161+
- Validate all inputs from web pages (content script allowlists)
162+
- Use `sender.id` checks for privileged operations
163+
- Rate-limit external-facing API methods
164+
- Verify event signatures before trusting relay data
165+
166+
## Code of Conduct
167+
168+
Be respectful, constructive, and focused on building great software. Technical disagreements are welcome; personal attacks are not.

0 commit comments

Comments
 (0)