= Communikeys
Defines a standard for creating, managing and publishing to communities by leveraging existing key pairs and relays.
This approach uniquely allows:
- any existing npub to become a community (identity + manager).
- any existing publication to be targeted at any community.
- communities to have their own selected content types.
== Motivation
Current community management solutions on Nostr often require complex relay-specific implementations, lack proper decentralization and don’t allow publications to be targeted at more than one community.
This proposal aims to simplify community management by utilizing existing Nostr primitives (key pairs and relays) while adding minimal new event kinds.
== Community Creation Event (kind:10222)
A community is created when a key pair publishes a kind:10222 event. The pubkey of this key pair becomes the unique identifier for that community. One key pair can only represent one community.
The community’s name, picture, and description are derived from the pubkey’s kind:0 metadata event.
[source,json] –– { “id”: “<event-id>”, “pubkey”: “<community-pubkey>”, “created_at”: 1675642635, “kind”: 10222, “tags”: [ // at least one relay for the community [“r”, “<relay-url>”],
// one or more blossom servers [“blossom”, “<blossom-url>”],
// one or more ecash mints [“mint”, “<mint-url>”, “cashu”],
// one or more content sections: [“content”, “<name>”] [“content”, “Chat”], [“k”, “9”],
[“content”, “Post”], [“k”, “1”], [“k”, “11”], [“fee”, “10”, “sat”], [“exclusive”, “true”], // true if this event kind can ONLY be targeted to this community, not others
[“content”, “Article”], [“k”, “30023”], [“k”, “30040”], [“a”, “<badge-definition>”] // only npubs with this badge awarded to them can publish Articles
// Optional terms of service, points to another event [“tos”, “<event-id-or-address>”, “<relay-url>”],
// Optional location [“location”, “<location>”], [“g”, “<geo-hash>”],
// Optional description [“description”, “A description text that overwrites the profile’s description, if needed”] ], “content”: ““, “sig”: “<signature>” } ––
.Tag definitions [horizontal] r:: URLs of relays where community content should be published. First one is considered main relay. blossom:: URLs of blossom servers for additional community features (optional). mint:: URL of community mint for token/payment features (optional). content:: Name of Content Type section that the Communikey works with k:: Event kind, within a content type section. retention:: Retention policy in format [kind, value, type] where type is either “time” (seconds) or “count” (number of events). fee:: Admission fee in format [kind, amount, unit] where unit is typically “msats”. exclusive:: boolean that specifies if this content type can be targeted to other communities too. a:: Publishing permission that uses awarded Badges (Admin, Team, Top supporter, etc… ) tos:: URL to the community’s posting policy. location:: Location of the community. g:: Geo hash of the community. description:: Description of the community.
The pubkey of the key pair that creates this event serves as the unique identifier for the community. This means:
- Each key pair can only represent one community
-
Communities can be easily discovered by querying for the most recent
kind:10222event for a given pubkey -
Community managers can update their settings by publishing a new
kind:10222event
== Community Identifier Format
Communities can be referenced using an “ncommunity” format:
ncommunity://<pubkey>?relay=<url-encoded-relay-1>&relay=<url-encoded-relay-2> ––
This format follows the same principles as nprofile, but specifically for community identification. While the ncommunity format is recommended for complete relay information, the standard pubkey format can also be used when relay discovery is not needed.
== Targeted Publication Event (kind:30222)
To target an existing publication at specific communities, users create a kind:30222 event:
[source,json] –– { “id”: “<event-id>”, “pubkey”: “<pubkey>”, “created_at”: 1675642635, “kind”: 30222, “tags”: [ [“d”, “<random-id>”], // or maybe equate to “e” tag, but then we run into trouble for the “a” tags [“e”, “<event-id-of-original-publication>”], // Or [“a”, “<event-id-of-original-publication>”] [“k”, “<kind-of-original-publication>”], [“p”, “<community1-pubkey>”], [“r”, “<main-relay1-url>”], [“p”, “<community2-pubkey>”], [“r”, “<main-relay2-url>”] ], “content”: ““, “sig”: “<signature>” } ––
The targeted publication event can reference the original publication in two ways:
-
Using an
etag with the event ID, relay hint, and pubkey hint -
Using an
atag with the event address and relay hint
The k tag specifies the kind of the original publication, and the p tags list the communities that this publication is targeting.
Currently, we work with a maximum of 12 communities that can be tagged for one publication.
IMPORTANT: For publishing new events clients SHOULD create a targeted Publication event ID first reference that same ID with an h tag in the main event.
== Community-Exclusive Publications
Some content types should be exclusive to the Community by default:
- Chat
- Forum Posts
- Labels
For these we don’t need a Targeted Publication event and can just use an h-tag instead.
For chat messages within a community, for example, users should use kind:9 events with a community tag:
[source,json] –– { “id”: “<event-id>”, “pubkey”: “<pubkey>”, “created_at”: 1675642635, “kind”: 9, “tags”: [ [“h”, “<community-pubkey>”] ], “content”: “<message>”, “sig”: “<signature>” } ––
== Badge Integration
Communities can use Badges for access control and publishing permissions.
=== Badge-Based Publishing Permissions
Communities can require specific badges for publishing certain content types by including an a tag in the content section:
["content", "Article"],
["k", "30023"],
["a", "30009:community-pubkey:admin"] // only admin badge holders can publish articles
=== Badge Validation
When a community specifies a badge requirement:
- Relays SHOULD verify the user has the required badge before allowing publication
- Clients SHOULD check badge requirements before attempting to publish
- Badge Status can be confirmed or pending (see Badge spec for details)
=== Invite-Tree Access Control
Communities can implement invite-tree access control using badges with award_policy: "badgeholders":
["a", "30009:community-pubkey:member"] // member badge with invite-tree policy
This allows: - Confirmed badgeholders can invite others (creates pending profile label) - All badgeholders (confirmed or pending) can publish content - Community must confirm invites to grant invite authority
=== Example Badge Integration
[source,json] –– { “id”: “<event-id>”, “pubkey”: “<community-pubkey>”, “created_at”: 1675642635, “kind”: 10222, “tags”: [ [“r”, “wss://community-relay.example.com”], [“content”, “General”], [“k”, “1”], [“content”, “Articles”], [“k”, “30023”], [“a”, “30009:community-pubkey:writer”], // writer badge required [“content”, “Admin”], [“k”, “30023”], [“a”, “30009:community-pubkey:admin”] // admin badge required ], “content”: ““, “sig”: “<signature>” } ––
== Implementation Notes
-
Clients SHOULD verify that targeted publications (
kind:30222) are present on the community’s main relays. The main relay specified in the community creation event SHOULD be considered authoritative for community-related events. Clients MAY, however, fall back on a backup relay (as the authority) when the main relay is offline. - Clients MAY cache community metadata events to reduce relay queries.
- Relay operators MAY implement/automate additional filtering or moderation based on community specifications.
- Badge Validation: Relays SHOULD verify badge requirements before accepting publications.
- Invite Management: Communities SHOULD provide tools for managing badge invites and confirmations.
== Benefits
- Any existing npub can become a community + we can piggy-back on any feature/ability Profiles have
- Any existing publication can be targeted at Communities (i.e. backwards compatibility with all current Nostr content)
- Communities are not permanently tied to specific relays
- Communities can work with whatever content-types they want + set whatever publishing conditions they want
- Has cross-community interaction and discovery (via Targeted Publications)
- The ability to target publications to more than one community and the access to any desired content type eliminates the need for #channels or rooms
- Flexible Access Control: Badge-based permissions provide granular access control
Comments
Public conversation about this article.
No comments yet.
Article metadata
About this entry
Event Id
Raw event
Other authors
No one else has published this topic yet.
