WizardConnect/CLAUDE.md

103 lines
4.8 KiB
Markdown

# wizardconnect
Relay-based protocol library for connecting dapps to HD wallets over WebSocket (Nostr NIP-17 gift-wrapped messages).
## Testing philosophy
Tests are more important than the code itself. A correct implementation that lacks tests is worse than a slightly imperfect implementation that is well-tested, because untested code will silently break and the breakage will only surface in production — often as subtle protocol bugs that are hard to reproduce.
This codebase communicates over a live relay with timing-sensitive handshakes and stateful reconnection logic. These bugs cannot be caught by reading the code. They only appear in integration tests that exercise the real relay.
**Always write tests before or alongside any non-trivial change.** If you add a feature, add a test. If you fix a bug, add a regression test that would have caught it.
### Test types
**Unit tests** (`npm test` in a package):
- Fast, no network, run on every change
- Test individual functions and classes in isolation
- Use vitest, mock external deps
- Should cover all edge cases in pure logic (state managers, message builders, URI encoding, etc.)
**Integration tests** (`npm run test:integration` in a package):
- Hit the real relays at `wss://relay.riften.net:443` and `wss://relay.cauldron.quest:443`
- Test the full protocol handshake end-to-end
- Located in `src/integration/*.test.ts` (wallet is the only package with them today)
- Run with generous timeouts (60s per test) via `vitest.integration.config.ts`, serially
(`singleFork`) to avoid relay contention, and with `retry: 2` — these hit third-party
relays, so a dropped connection is an environment failure rather than a regression
- A failure that reproduces locally is real; one that does not is usually the relay.
Check whether the same test passed on an earlier pipeline before assuming a regression
- Must pass before any release
### Running tests
```bash
# All packages, unit tests only (fast):
npm run test
# Wallet package integration tests (requires network):
cd packages/wallet && npm run test:integration
# Custom relay:
TEST_RELAY_URL=wss://your-relay:443 npm run test:integration
```
### Test CLI (manual/exploratory testing)
```bash
# Start a dapp session and watch the protocol:
npm run dapp
# Connect a test wallet to a dapp URI:
npm run wallet -- --uri wiz://...
# Test the approval flow:
npm run dapp -- --sign
```
The test CLI (`packages/test-cli/`) is not a substitute for automated tests — it is a debugging tool.
## Documentation
Protocol and architecture documentation lives in `docs/`. Keep it up to date when making changes:
| File | Update when… |
|------|-------------|
| `docs/protocol.md` | Protocol messages, handshake logic, or `PathName`/`PathXpub`/`NextIndex` types change |
| `docs/extensions.md` | Extension system, `WalletAdapter` extension hooks, known extensions, or custom message conventions change |
| `docs/connection-uri.md` | URI format, key exchange flow, or credential structure changes |
| `docs/transport.md` | `RelayClient`, `initiateRelay`, reconnect logic, or encryption scheme changes |
| `docs/wallet.md` | `WalletAdapter`, `WalletConnectionManager`, or connection lifecycle changes |
| `docs/dapp.md` | `DappConnectionManager` API or session lifecycle changes |
| `docs/react.md` | React components, hooks, or QR dialog API changes |
| `docs/pubkey-derivation.md` | xpub delivery, `DappPubkeyStateManager`, or gap-fill logic changes |
| `docs/xpub-sharing.md` | xpub sharing rationale, security model, or comparison with other protocols changes |
| `docs/serialization.md` | Relay JSON encoding (`sourceOutputToRelay`, `toBigInt`, `toUint8Array`, etc.) changes |
| `docs/index.md` | New top-level docs files are added |
## Packages
- `@wizardconnect/core` — transport + protocol primitives (relay client, key exchange, hdwalletv1 message types)
- `@wizardconnect/dapp` — dapp-side helpers (`DappConnectionManager`, `DappPubkeyStateManager`)
- `@wizardconnect/wallet` — wallet-side helpers (`WalletConnectionManager`, `WalletAdapter`, `PubkeyStateManager`)
- `@wizardconnect/react` — React components and hooks (`WizardConnectQRDialog`, `AlphanumericQRCode`, `useWizardConnect`)
- `@wizardconnect/test-cli` — manual test CLI (`dapp` and `wallet` modes)
## Build
```bash
npm install
npm run build # builds all packages in dependency order
```
Packages must be built before integration tests run (tests import from `dist/`).
## Releases
The `publish` CI job runs on `master` only, via `contrib/auto-publish.js`.
**The `version` in each `package.json` is a floor, not the shipped version** — all declare
`0.2.0` while npm carries higher patches. Use `npm view @wizardconnect/<pkg> version`.
The lockfile is not published, so clearing a dependency advisory means bumping the declared
range in `package.json`, not just `package-lock.json`.