4.8 KiB
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:443andwss://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 withretry: 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
# 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)
# 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 (dappandwalletmodes)
Build
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.