Add README

This commit is contained in:
Dagur Valberg Johannsson 2026-03-17 14:55:18 +01:00
parent bc002551fb
commit 9b4f21676c
No known key found for this signature in database
GPG key ID: FD701804AEE88107
2 changed files with 193 additions and 0 deletions

View file

@ -65,6 +65,7 @@ Protocol and architecture documentation lives in `docs/`. Keep it up to date whe
| `docs/wallet.md` | `WalletAdapter`, `WalletConnectionManager`, or connection lifecycle changes | | `docs/wallet.md` | `WalletAdapter`, `WalletConnectionManager`, or connection lifecycle changes |
| `docs/dapp.md` | `DappConnectionManager` API or session lifecycle changes | | `docs/dapp.md` | `DappConnectionManager` API or session lifecycle changes |
| `docs/pubkey-derivation.md` | xpub delivery, `DappPubkeyStateManager`, or gap-fill logic 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/index.md` | New top-level docs files are added | | `docs/index.md` | New top-level docs files are added |
## Packages ## Packages

192
README.md Normal file
View file

@ -0,0 +1,192 @@
# WizardConnect
A dapp-to-wallet protocol built for Bitcoin Cash.
WizardConnect lets a dapp scan a wallet's QR code and immediately start
deriving addresses, constructing transactions, and requesting signatures —
no seed phrases, no trusted servers, no round trips.
## Why not WalletConnect?
WalletConnect was built for Ethereum, where a wallet is a single address. BCH
wallets are HD wallets with thousands of addresses for privacy. Forcing an
Ethereum protocol onto BCH means:
- **One address per session.** WalletConnect gives the dapp a single address.
That breaks the HD wallet model and destroys the privacy that multiple
addresses provide.
- **Unreliable on BCH.** BCH support in WalletConnect is a second-class
citizen — a bridge on top of an Ethereum-native protocol. Connections drop,
sessions fail to restore, and there's no community maintaining it for BCH.
WizardConnect replaces all of this with a protocol designed from the ground up
for UTXO chains and HD wallets.
## How it works
```
Wallet Relay Dapp
│ │ │
│ ◄───── QR code scan ────── │ ◄──── shows QR (wiz://...) │
│ │ │
│ wallet_ready ──────────────►│──────────────────────────────►│
│ (xpubs + key exchange) │ │
│ │ derive addresses │
│ │ locally from xpubs │
│ │ (no more round trips)│
│ │ │
│ ◄──────────────────────────│◄──── sign_transaction_request │
│ user approves on wallet │ │
│ sign_transaction_response──►│──────────────────────────────►│
│ │ broadcast │
```
1. The dapp generates a `wiz://` URI and displays it as a QR code.
2. The wallet scans the QR, connects to the relay, and sends its xpubs.
3. The dapp derives all addresses locally — no further contact with the wallet
needed for address generation.
4. When the dapp needs a signature, it sends a request. The user approves on
the wallet. The signed transaction comes back.
All communication is end-to-end encrypted via Nostr NIP-17 gift wrap. The
relay sees only ciphertext.
## Key features
**Full HD wallet support.** The wallet shares BIP32 xpubs for specific
derivation paths (receive, change, DeFi). The dapp derives unlimited
addresses locally. No more single-address sessions.
**Zero round trips for addresses.** After the initial handshake, the dapp
never needs to ask the wallet for a public key. It derives them on demand from
the xpubs, in microseconds.
**Decentralized transport.** Built on Nostr — an open protocol with hundreds
of public relays. No proprietary bridge server. Users can point to any relay
for additional privacy or self-host their own.
**Reconnection-proof.** Both sides can disconnect and reconnect independently
(app switch, browser refresh, network drop) and converge back to a live
session without user action.
**Extensible.** The protocol negotiates capabilities during the handshake.
`hdwalletv1` is the first protocol; future protocols (multisig, post-quantum,
token-aware) can be added without breaking existing connections.
**Open source (LGPL-3.0).** Free to use in commercial and non-commercial
applications. Modifications to the library itself must be shared back.
## Packages
```
npm install @wizardconnect/core # transport, protocol types, key exchange
npm install @wizardconnect/dapp # dapp-side session + address derivation
npm install @wizardconnect/wallet # wallet-side connection + signing
```
| Package | Description |
|---------|-------------|
| `@wizardconnect/core` | Relay client, NIP-17 encryption, URI encoding, protocol message types |
| `@wizardconnect/dapp` | `DappConnectionManager`, `DappPubkeyStateManager` — session management and on-demand pubkey derivation |
| `@wizardconnect/wallet` | `WalletConnectionManager`, `WalletAdapter` interface — multi-connection management and sign request dispatch |
## Quick start: dapp
```typescript
import { initiateDappRelay } from "@wizardconnect/core";
import { DappConnectionManager } from "@wizardconnect/dapp";
const dapp = new DappConnectionManager("My Dapp", "https://example.com/icon.png");
const relay = initiateDappRelay(
(payload) => dapp.updateConnection(payload.client, payload.status),
{ explicitRelayUrls: ["wss://relay.cauldron.quest:443"] },
);
// Display relay.uri as a QR code for the wallet to scan
dapp.on("walletready", () => {
// Connected! Derive addresses locally:
const receivePubkey = dapp.getPubkey(0, 0n); // receive path, index 0
const changePubkey = dapp.getPubkey(1, 0n); // change path, index 0
});
```
## Quick start: wallet
```typescript
import { WalletConnectionManager } from "@wizardconnect/wallet";
const manager = new WalletConnectionManager(myWalletAdapter);
// When the user scans a dapp's QR code:
const connectionId = manager.connect("wiz://?p=...&s=...");
// When a sign request arrives, show it to the user:
manager.on("pendingSignRequest", async ({ connectionId, request }) => {
const approved = await showApprovalUI(request);
if (approved) {
await manager.sendSignResponse(connectionId, request.sequence, signedTxHex);
} else {
await manager.sendSignError(connectionId, request.sequence, "User rejected");
}
});
```
See [wallet integration guide](docs/wallet.md) for `WalletAdapter` implementation details.
## Privacy model
WizardConnect shares xpubs at the **chain level**, not the account level.
A dapp receiving the receive xpub can derive receive addresses but cannot
derive change addresses or any other internal wallet activity. This is the
same level of key material used by watch-only wallets.
For wallets that want stronger isolation, the protocol supports per-session
xpub rotation — the dapp sees only the xpub node, never the derivation path.
See [xpub sharing: why it's safe](docs/xpub-sharing.md) for a full discussion.
## Security
- Private keys never leave the wallet. Signing happens on-device.
- All relay traffic is end-to-end encrypted (NIP-17 gift wrap). The relay
cannot read messages.
- Key exchange includes an 8-byte shared secret (embedded in the QR code) for
MITM prevention.
- No trusted intermediary. The relay is a dumb message broker — compromise it
and you get ciphertext.
## Documentation
| Topic | Link |
|-------|------|
| Protocol messages and handshake | [protocol.md](docs/protocol.md) |
| Connection URI and key exchange | [connection-uri.md](docs/connection-uri.md) |
| Relay transport and encryption | [transport.md](docs/transport.md) |
| Wallet integration guide | [wallet.md](docs/wallet.md) |
| Dapp integration guide | [dapp.md](docs/dapp.md) |
| xpub delivery and derivation | [pubkey-derivation.md](docs/pubkey-derivation.md) |
| xpub sharing: why it's safe | [xpub-sharing.md](docs/xpub-sharing.md) |
## Building
```bash
npm install
npm run build # builds all packages in dependency order
npm run test # unit tests (fast, no network)
```
Integration tests hit a live relay:
```bash
cd packages/wallet && npm run test:integration
```
## License
[LGPL-3.0-or-later](https://www.gnu.org/licenses/lgpl-3.0.html). Free for
commercial and non-commercial use. Modifications to the library must be
released under the same license.
Built by [Riften Labs](https://riftenlabs.com).