This is a project which uses nostr keys as the root identity of an online community.
These keys MUST be generated using a distributed key generation (DKG) process based on Secure Multi-Party Computation (MPC) so that no single member sees the full key at any time. These keys must then be stored as key shares, each of which is custodied by a member of the group. Admins may be rotated out by reconstructing the key using MPC and re-creating shares for the new admins.
The community key has certain responsibilities:
- Issuing and revoking capabilities
- Selecting relays for storing capabilities
- Selecting relays for storing gated community content
- Selecting relays for storing publicly visible community content
Capabilities are a way of assigning the following abilities to other nostr pubkeys:
read- the pubkey can read group contentwrite- the pubkey can write group contentpublish- the pubkey can publish content on behalf of the communitydelete- the pubkey can delete group contentdelegate- the pubkey can create chained capabilities
Each capability can be qualified with additional parameters, such as what event kinds are in scope, or whether events need to have (or not have certain) tags.
To participate in a community, members must publish content to the relays selected by the root key. Content not served by those relays must not be considered part of the group.
Members may publish content on behalf of the group by publishing to the group's public content relays. Members must have the publish capability for the event in question.
This is a typescript/pnpm monorepo. Packages:
@nkg/signer- utilities related to MPC/DKG key generation and signing@nkg/cap- utilities related to capability issuance and validation@nkg/relay- a relay implementation that supports nip 29 and capability authorization@nkg/chat- a proof of concept chat app with nip 29 support
Technologies used:
- pnpm/typescript
- Graphical user interfaces are written using mithriljs
- Nostr code uses nostr-tools
- FROST implementation uses @cmdcode/frost
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Run tests
pnpm test
# Start the chat app (development)
cd packages/chat && pnpm dev
# Start the relay
cd packages/relay && pnpm start- Initialize pnpm workspace with
pnpm-workspace.yaml - Create root
package.jsonwith workspace configuration - Create root
tsconfig.jsonwith project references - Set up shared TypeScript configuration (
tsconfig.base.json) - Create the 4 package directories under
packages/
- Set up package structure with
package.jsonandtsconfig.json - Implement DKG session types and interfaces (participant IDs, round states)
- Implement DKG Round 1: Generate and broadcast commitments via nostr events
- Implement DKG Round 2: Process received commitments and generate shares
- Implement DKG Round 3: Finalize key shares and derive group public key
- Implement key share serialization/deserialization for secure storage
- Implement threshold signing Round 1: Generate and broadcast nonces
- Implement threshold signing Round 2: Generate signature shares
- Implement signature aggregation and verification
- Implement key share refresh (admin rotation without changing pubkey)
- Define nostr event kinds for DKG/signing protocol messages
- Write tests for full DKG flow with configurable t-of-n threshold
- Write tests for threshold signing flow
- Set up package structure with
package.jsonandtsconfig.json - Define capability event schema (kind, tags for permissions, expiry, etc.)
- Implement capability types:
read,write,publish,delete,delegate - Implement capability qualifiers (event kinds, tag filters)
- Implement capability issuance (create and sign via signer package)
- Implement capability revocation (nostr event referencing original)
- Implement chained capabilities (delegation chains with proof of authority)
- Implement capability validation (signature verification, expiry, chain validation)
- Implement capability query utilities (filter by pubkey, permission type)
- Write tests for issuance, validation, and revocation
- Set up package structure with
package.jsonandtsconfig.json - Implement WebSocket server for nostr relay protocol
- Implement NIP-29 event kinds (9, 10, 11, 12 for chat/notes)
- Implement NIP-29 group metadata events (39000, 39001, 39002)
- Implement NIP-29 moderation events (9000-9020)
- Implement NIP-29 join/leave requests (9021, 9022)
- Implement
htag validation for group membership - Implement
previoustag validation for timeline references - Implement late publication prevention
- Integrate capability validation for all write operations
- Implement relay-signed group metadata generation
- Implement event storage (in-memory or SQLite for PoC)
- Implement REQ/EVENT/CLOSE protocol handlers with AUTH
- Write tests for NIP-29 compliance
- Write tests for capability-gated access
- Set up package structure with
package.jsonandtsconfig.json - Set up mithriljs with TypeScript and build tooling (esbuild/vite)
- Implement relay connection management (using nostr-tools)
- Implement login/key management UI (import key share or participate in DKG)
- Implement group list view (show joined groups from kind 10009)
- Implement group creation UI (initiate DKG with other admins)
- Implement chat view with kind 9 messages
- Implement threaded replies with kind 10
- Implement join/leave group functionality
- Implement capability display (show what the user can do)
- Implement moderation UI for admins (if user has delete capability)
- Basic styling and UX polish
- Integration tests across all packages
- Update README.md with setup instructions
- Document the capability event schema
- Document the DKG nostr event protocol
| Decision | Choice |
|---|---|
| DKG Communication | Nostr events (ephemeral or stored) |
| Capability Format | Nostr events signed by group key |
| Threshold Config | Configurable t-of-n |
| Relay Type | Standalone with full NIP-29 support |
| FROST Library | @cmdcode/frost |
| Nostr Library | nostr-tools |
| UI Framework | mithriljs |