{"id":"1c9f51d218ed9778c0ed52623b574a70c8d0ef3551b4facc84c142486ccdde02","pubkey":"2b39b4ffe62933df970e19366c22c1e092f953f83fcfed754e0f04d5a3b459f9","created_at":1781353189,"kind":30817,"tags":[["d","nip-28"],["title","NIP-28: Public Chat"],["summary","Kinds 40 to 44, public chat channels with moderation left to the client."],["s","unrecommended"],["t","nostr"],["t","nip"],["k","40","Channel Creation"],["k","41","Channel Metadata"],["k","42","Channel Message"],["k","43","Channel Hide Message"],["k","44","Channel Mute User"],["alt","A specification: NIP-28: Public Chat"],["client","openspecs-import"],["published_at","1662830888"],["proxy","https://github.com/nostr-protocol/nips/blob/656cecc7c0a815b6a2b218d3b5d6f078b3f4dbab/28.md","web"],["x","47ea16f7bf11de03f25c0288e8d5670b2d1fcfee668849d0341637488a9df826"]],"content":"> __Warning__  `unrecommended`: try [NIP-29](nostr:naddr1qvzqqqrcvypzq2eeknl7v2fnm7tsuxfkds3vrcyjl9fls070a465urcy6k3mgk0eqqrxu6ts95erjranuqq) instead\n\nNIP-28\n======\n\nPublic Chat\n-----------\n\n`draft` `unrecommended` `optional`\n\nThis NIP defines new event kinds for public chat channels, channel messages, and basic client-side moderation.\n\nIt reserves five event kinds (40-44) for immediate use:\n\n- `40 - channel create`\n- `41 - channel metadata`\n- `42 - channel message`\n- `43 - hide message`\n- `44 - mute user`\n\nClient-centric moderation gives client developers discretion over what types of content they want included in their apps, while imposing no additional requirements on relays.\n\n## Kind 40: Create channel\n\nCreate a public chat channel.\n\nIn the channel creation `content` field, Client SHOULD include basic channel metadata (`name`, `about`, `picture` and `relays` as specified in kind 41).\n\n```yaml\n{\n  \"content\": \"{\\\"name\\\": \\\"Demo Channel\\\", \\\"about\\\": \\\"A test channel.\\\", \\\"picture\\\": \\\"https://placekitten.com/200/200\\\", \\\"relays\\\": [\\\"wss://nos.lol\\\", \\\"wss://nostr.mom\\\"]}\",\n // other fields...\n}\n```\n\n\n## Kind 41: Set channel metadata\n\nUpdate a channel's public metadata.\n\nKind 41 is used to update the metadata without modifying the event id for the channel. Only the most recent kind 41 per `e` tag value MAY be available.\n\nClients SHOULD ignore kind 41s from pubkeys other than the kind 40 pubkey.\n\nClients SHOULD support basic metadata fields:\n\n- `name` - string - Channel name\n- `about` - string - Channel description\n- `picture` - string - URL of channel picture\n- `relays` - array - List of relays to download and broadcast events to\n\nClients MAY add additional metadata fields.\n\nClients SHOULD use [NIP-10](nostr:naddr1qvzqqqrcvypzq2eeknl7v2fnm7tsuxfkds3vrcyjl9fls070a465urcy6k3mgk0eqqrxu6ts95cnqpw4wta) marked \"e\" tags to recommend a relay.\n\nIt is also possible to set the category name using the \"t\" tag. This category name can be searched and filtered.\n\n```yaml\n{\n  \"content\": \"{\\\"name\\\": \\\"Updated Demo Channel\\\", \\\"about\\\": \\\"Updating a test channel.\\\", \\\"picture\\\": \\\"https://placekitten.com/201/201\\\", \\\"relays\\\": [\\\"wss://nos.lol\\\", \\\"wss://nostr.mom\\\"]}\",\n  \"tags\": [\n    [\"e\", <channel_create_event_id>, <relay-url>, \"root\"],\n    [\"t\", <category_name-1>],\n    [\"t\", <category_name-2>],\n    [\"t\", <category_name-3>],\n  ],\n  // other fields...\n}\n```\n\n\n## Kind 42: Create channel message\n\nSend a text message to a channel.\n\nClients SHOULD use [NIP-10](nostr:naddr1qvzqqqrcvypzq2eeknl7v2fnm7tsuxfkds3vrcyjl9fls070a465urcy6k3mgk0eqqrxu6ts95cnqpw4wta) marked \"e\" tags to recommend a relay and specify whether it is a reply or root message.\n\nClients SHOULD append [NIP-10](nostr:naddr1qvzqqqrcvypzq2eeknl7v2fnm7tsuxfkds3vrcyjl9fls070a465urcy6k3mgk0eqqrxu6ts95cnqpw4wta) \"p\" tags to replies.\n\nRoot message:\n\n```yaml\n{\n  \"content\": <string>,\n  \"tags\": [[\"e\", <kind_40_event_id>, <relay-url>, \"root\"]],\n  // other fields...\n}\n```\n\nReply to another message:\n\n```yaml\n{\n  \"content\": <string>,\n  \"tags\": [\n      [\"e\", <kind_40_event_id>, <relay-url>, \"root\"],\n      [\"e\", <kind_42_event_id>, <relay-url>, \"reply\"],\n      [\"p\", <pubkey>, <relay-url>],\n      // rest of tags...\n  ],\n  // other fields...\n}\n```\n\n\n## Kind 43: Hide message\n\nUser no longer wants to see a certain message.\n\nThe `content` may optionally include metadata such as a `reason`.\n\nClients SHOULD hide event 42s shown to a given user, if there is an event 43 from that user matching the event 42 `id`.\n\nClients MAY hide event 42s for other users other than the user who sent the event 43.\n\n(For example, if three users 'hide' an event giving a reason that includes the word 'pornography', a Nostr client that is an iOS app may choose to hide that message for all iOS clients.)\n\n```yaml\n{\n  \"content\": \"{\\\"reason\\\": \\\"Dick pic\\\"}\",\n  \"tags\": [[\"e\", <kind_42_event_id>]],\n  // other fields...\n}\n```\n\n## Kind 44: Mute user\n\nUser no longer wants to see messages from another user.\n\nThe `content` may optionally include metadata such as a `reason`.\n\nClients SHOULD hide event 42s shown to a given user, if there is an event 44 from that user matching the event 42 `pubkey`.\n\nClients MAY hide event 42s for users other than the user who sent the event 44.\n\n```yaml\n{\n  \"content\": \"{\\\"reason\\\": \\\"Posting dick pics\\\"}\",\n  \"tags\": [[\"p\", <pubkey>]],\n  // other fields...\n}\n```\n\n## Relay recommendations\n\nClients SHOULD use the relay URLs of the metadata events. \n\nClients MAY use any relay URL. For example, if a relay hosting the original kind 40 event for a channel goes offline, clients could instead fetch channel data from a backup relay, or a relay that clients trust more than the original relay.\n\nMotivation\n----------\nIf we're solving censorship-resistant communication for social media, we may as well solve it also for Telegram-style messaging.\n\nWe can bring the global conversation out from walled gardens into a true public square open to all.\n\n\nAdditional info\n---------------\n\n- [Chat demo PR with fiatjaf+jb55 comments](https://github.com/ArcadeCity/arcade/pull/28)\n- [Conversation about NIP16](https://t.me/nostr_protocol/29566)\n","sig":"c9d8825bfe014e063942637188c21564a536d1b5ccc0c221b5a84582d3671fc671609ac36ef0b443590a5de270063b44af787e2d368d49f0c55ba622e4b04774"}