diff --git a/.ion-connect-protocol/ICIP-1000.md b/.ion-connect-protocol/ICIP-1000.md new file mode 100644 index 0000000..f855b15 --- /dev/null +++ b/.ion-connect-protocol/ICIP-1000.md @@ -0,0 +1,113 @@ +ICIP-1000 +======= + +Multiple Public Key Types and Signature Algorithms for Event Signing +----- + +`draft` `optional` + +This ICIP defines a way for clients and relays to allow other types of ECC Public Keys and Signature Algorithms to be used in Nostr in a seamless manner. + +### Motivation + +As mentioned in [NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md): + +> Each user has a keypair. Signatures, public key, and encodings are done according to the [Schnorr signatures standard for the curve `secp256k1`](https://bips.xyz/340). + +This is a limitation for Nostr adoption, as many Blockchains and other Cryptographic Networks have already identities in place using different ECC Public Key curves, and may use different Signature Algorithms. Even Bitcoin pre Taproot uses `ECDSA/secp256k1` and not `Schnorr/secp256k1`. + +In this case it is just the signatures that differ, and the public key derivation is based out of the same `secp256k1` curve, so the public keys remain valid, but for other networks that use `ed25519` signatures, for instance, not even the public keys would be valid, as the curve used is `Curve25519` instead. + +This means that Nostr identities would have to be different than the ones used in the other networks, making it impossible to consider a direct match between one network identity and the other, for instance, for having a smart contract as a Nostr identity (public key). + +### References + +This proposal came together with inputs from many other proposals and discussions, but these are the main ones: + +[NIP-01: Basic protocol flow description](https://github.com/nostr-protocol/nips/blob/master/01.md)
+[NIP-06: Basic key derivation from mnemonic seed phrase](https://github.com/nostr-protocol/nips/blob/master/06.md) + +### Public Key Types and Signature Algorithms + +A small list of networks and their ECC Key Derivation curves and Signature Algorithms: + +| Network | ECC Curve | Signature Algorithm | +|-------------------|------------|---------------------| +| Bitcoin (legacy) | secp256k1 | ECDSA | +| Bitcoin (taproot) | secp256k1 | Schnorr | +| Ethereum | secp256k1 | ECDSA | +| Litecoin | secp256k1 | ECDSA | +| Monero | curve25519 | EdDSA | +| Cardano | curve25519 | EdDSA | +| Ripple | secp256k1 | ECDSA | +| TON (Telegram) | curve25519 | EdDSA | +| Cardano | curve25519 | EdDSA | +| Stellar | curve25519 | EdDSA | +| Tezos | curve25519 | EdDSA | +| Zcash | curve25519 | EdDSA | +| Zcash (shielded) | secp256k1 | ECDSA | + +From this small list it is clear that more than half of the public keys from these selected networks wouldn't be compatible with Nostr, and only a Bitcoin taproot wallet would be able to generate compatible signatures for Nostr events. + +We want to eliminate this problem, and it is quite simple... + +### Signature Prefixes + +This ICIP introduces a prefix mechanism for the `.sig` field of Nostr events, that by default (without any prefix) falls back to `schnorr/secp256k1`, but when present defines the signature algorithm and public key derivation curve. + +#### Signature Algorithms + +| Prefix | Signature Algorithm | ECC Curve (default) | +|---------|---------------------|---------------------| +| schnorr | Schnorr | secp256k1 | +| ecdsa | ECDSA | secp256k1 | +| eddsa | EdDSA | curve25519 | + +#### Public Key Derivation Curves + +| Prefix | ECC Curve | +|------------|------------| +| secp256k1 | secp256k1 | +| secp256r1 | secp256r1 | +| curve25519 | Curve25519 | +| curve448 | Curve448 | + +#### Signature Algorithm Prefix + +To use a different Signature Algorithm, for instance ECDSA for legacy Bitcoin wallets, an event would look like this: + +```json +{ + "id": "567b41fc9060c758c4216fe5f8d3df7c57daad7ae757fa4606f0c39d4dd220ef", + "kind": "1", + "pubkey": "8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd", + "tags": [], + "content": "some note", + ... + "sig": "ecdsa:3046022100a0e03de740d3a1136d443b0c24a252e08ae1ae4dd73f0f7dacfdc440c69ce45102210083b5ba4e0f34261b605848ad85ddf585637c7579e58e73058ab3c934a7ca05c2" +} +``` + +#### Signature Algorithm Prefix with a Different ECC Curve + +To use another Signature Algorithm and another ECC Curve, an event would look like this: + +```json +{ + "id": "567b41fc9060c758c4216fe5f8d3df7c57daad7ae757fa4606f0c39d4dd220ef", + "kind": "1", + "pubkey": "8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd", + "tags": [], + "content": "some note", + ... + "sig": "ecdsa/secp256r1:3046022100c04f4139d4d52aa516873a8a9fba77c54810ade51e7e1720b45934d51a9a1216022100a645e11aa3877f111caf486fbd199781dca85373da504f6eb3690439f7a1a222" +} +``` + +### Clients and Relays + +Clients and Relays are free to choose what combinations of Signatures Algorithms and ECC Curves they support, the only mandatory one is `schnorr/secp256k1`, which is the default for Nostr, but highly encouraged to support more, at least `ecdsa` and `eddsa` with their default curves. This way Nostr network will be increasingly more compatible and possible to interoperate with other networks. + +### Integration into NIP-01 + +We propose that this ICIP, when discussed and approved, should be integrated into NIP-01, as it represents a global improvement for event signing. We decided to keep it separated in a different file to be more concise for discussion for now. \ No newline at end of file diff --git a/.ion-connect-protocol/ICIP-2000.md b/.ion-connect-protocol/ICIP-2000.md new file mode 100644 index 0000000..305e311 --- /dev/null +++ b/.ion-connect-protocol/ICIP-2000.md @@ -0,0 +1,273 @@ +ICIP-2000 +====== + +On-Behalf of - Simple Sub-Key Management +----- + +`draft` `optional` + +This ICIP defines a simple way for an Identity Sub-Key management system, including active, inactive and revoked public keys, for publishing On-Behalf of a master identity. + +### Motivation + +The state of the art now has two methods for enabling sub-key management: +- [NIP-26](https://github.com/nostr-protocol/nips/blob/master/26.md): Multiple key delegation and no revocation (just time bound) +- [NIP-41](https://github.com/nostr-protocol/nips/pull/1032): More complete single key delegation and revocation (complex) + +Each of these methods has their own pros and cons, but there's a very common use case that is not covered by any of these methods completely, which is having a master identity that is secure (possibly in cold storage), that can whitelist and blacklist multiple public keys (one for each device or app, for example), that can be used individually (less common but interesting for media management companies) and can publish on-behalf of one or several master identities. + +Using [NIP-26](https://github.com/nostr-protocol/nips/blob/master/26.md) for this purpose doesn't allow for blacklisting (revocation), or alternatively requires time bound delegation, with new delegation signing at every expiry. On the other hand [NIP-41](https://github.com/nostr-protocol/nips/pull/1032) is a more complete and complex identity management solution, but only allows for one active sub-key at any point in time, and that sub-key's only purpose is bound to the main identity. + +### References + +This proposal came together with inputs from many other proposals and discussions, but these are the main ones: + +[NIP-26: Delegated Event Signing](https://github.com/nostr-protocol/nips/blob/master/26.md)
+[NIP-41: Identity Management](https://github.com/nostr-protocol/nips/pull/1032)
+[NIP-06: Basic Key Derivation from Mnemonic Seed Phrase](https://github.com/nostr-protocol/nips/blob/master/06.md)
+[NIP-51: Lists](https://github.com/nostr-protocol/nips/blob/master/51.md) + +[Why I don’t like NIP-26 as a solution for key management](https://fiatjaf.com/4c79fd7b.html)
+[Thoughts on Nostr key management](https://fiatjaf.com/72f5d1e4.html) + +[Stateless key rotation using a series of hidden commitments](https://github.com/nostr-protocol/nips/issues/103)
+[Key distribution, rotation, and recovery](https://github.com/nostr-protocol/nostr/issues/45)
+[Key rotation verified through root key attestation](https://github.com/nostr-protocol/nips/issues/116)
+[Trusted public-key-bundle attestations for key rotation and group definition](https://github.com/nostr-protocol/nips/issues/123) + +### Identity types + +For clarity in this ICIP, we'll use the following identities to describe the actors that are involved in the examples and use cases: + +- **master**: the master account, the content owner or author +- **active**: an active sub account, device account, media manager or publisher account +- **inactive**: a sub account that has been inactivated (but not compromised) +- **revoked**: a sub account that has been revoked (it may have been compromised, and all events posted on-behalf of master need to be invalidated) + +### On-Behalf of Attestations List + +This ICIP introduces a replaceable event with `kind 10100`, which is used to keep a [NIP-51](https://github.com/nostr-protocol/nips/blob/master/51.md) list of `active`, `inactive` or `revoked` public keys, for publishing events on-behalf of a master account. The only valid tag in this list is the `p` tag as defined below. + +`.content` fields is unused and can be ignored if present. + +This list is owned by the master account, and can only be updated by an event signed by the master account itself, so never using a `b` on-behalf tag (see below), neither by [NIP-41](https://github.com/nostr-protocol/nips/pull/1032) `p` tag in `kind 0`, nor using a [NIP-26](https://github.com/nostr-protocol/nips/blob/master/26.md) `delegation` tag. + +This list is ever-growing, so each update has to include all previous attestations unchanged, and add one or more attestations to the list, otherwise they should be considered invalid and ignored by clients and relays. + +### Tag `b` (on-Behalf) for events + +This ICIP introduces a new tag: `b`, which is indexable by relays, and can be present in active account events, if attested at the on-behalf list above, formatted as follows: + +```json +[ "b", ] +``` + +To prevent spam, only one `b` tag can be present in an event. + +If present and valid, the `b` tag will represent that clients and relays should consider that event as published by the master account specified in the `b` tag, instead of the one in the event `.pubkey` field. + +If an invalid `b` tag is present, clients and relays should disregard the event, as if it had an invalid signature. + +### Tag `p` (with attestation string) for `kind 10100` list + +This ICIP also introduces a new attestation string for `p` tag. The `p` tag can be present multiple times in master account's `kind 10100` On-Behalf Of attestations list, formatted as follows: + +```json +[ + "p", ,
, +] +``` + +Field `main relay URL` can be omitted if not required or needed for accessing the sub account events, and in this case an empty string should be used in the second field of the `p` tag. + +#### Active Attestation String + +The **Active Attestation** should be a string in the following format: + +``` +"active::" +``` + +Last `:` is only required if an optional kinds list is present. Without a kinds list, the attestation is valid for all event kinds besides `kind 10100`. + +#### Inactive and Revoked Attestation String + +The **Inactive** or **Revoked Attestations** should be a string in the following formats: + +``` +"inactive:" +``` + +or + +``` +"revoked:" +``` + +To purposely limit the creative use cases, so that it doesn't become very demanding to compute the final state of an account, `inactive` and `revoked` attestations invalidate all previous `active` attestations, and subsequent `active` attestations are considered invalid as well. + +> This way the master account can decide, depending on the use case and criticality, if it makes sense to keep the published content valid, by adding an `inactive` attestation, or if it's preferable to invalidate all content published by that account, on its behalf, by adding a `revoked` attestation. + +##### Subsequent Attestations Resolution + +As the attestations are all timestamped, it is convention that a subsequent attestation overrides a prior one, but in the rare event of the same timestamp in attestations for the same public key, the latest in the tags array order should override the previous. + +### Examples + +- Considering: + ``` + master account: + 8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd + + active account: + 477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396 + ``` + +- Allow active account to publish `kind 1` and `kind 7` events on-behalf of the master account: + + ```json + { + "id": "567b41fc9060c758c4216fe5f8d3df7c57daad7ae757fa4606f0c39d4dd220ef", + "kind": "10100", + "pubkey": "8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd", + "tags": [ + [ + "p", + "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "", + "active:1674834236:1,7" + ] + ], + "content": "", + ... + "sig": "a9a4e2192eede77e6c9d24ddfab95ba3ff7c03fbd07ad011fff245abea431fb4d3787c2d04aad001cb039cb8de91d83ce30e9a94f82ac3c5a2372aa1294a96bd" + } + ``` + +- The active account, while the master account has a valid active attestation at its `kind 10100` list, can publish on-behalf of the master account, using the `b` tag on the event: + + ```json + { + "id": "e93c6095c3db1c31d15ac771f8fc5fb672f6e52cd25505099f62cd055523224f", + "pubkey": "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "created_at": 1677426298, + "kind": 1, + "tags": [ + [ + "b", + "8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd" + ] + ], + "content": "Hello, world!", + "sig": "633db60e2e7082c13a47a6b19d663d45b2a2ebdeaf0b4c35ef83be2738030c54fc7fd56d139652937cdca875ee61b51904a1d0d0588a6acd6168d7be2909d693" + } + ``` + + The event should be considered as published on-behalf of the master account, if at the timestamp `1677426298` the master account had a valid active attestation on its `kind 10100` list. If the `b` tag is not validated by an active attestation, that content is considered invalid and relays and clients can ignore it. + +- When master account decides to allow on-behalf active for all kinds: + + ```json + { + "id": "567b41fc9060c758c4216fe5f8d3df7c57daad7ae757fa4606f0c39d4dd220ef", + "kind": "10100", + "pubkey": "8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd", + "tags": [ + ["p", + "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "", + "active:1674834236:1,7"], + ["p", + "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "", + "active:1721934607"] + ], + "content": "", + ... + "sig": "a9a4e2192eede77e6c9d24ddfab95ba3ff7c03fbd07ad011fff245abea431fb4d3787c2d04aad001cb039cb8de91d83ce30e9a94f82ac3c5a2372aa1294a96bd" + } + ``` + +- Or otherwise, when master account decides to not allow on-behalf for `kind 7`, but keep `kind 1` active: + + ```json + { + "id": "567b41fc9060c758c4216fe5f8d3df7c57daad7ae757fa4606f0c39d4dd220ef", + "kind": "10100", + "pubkey": "8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd", + "tags": [ + ["p", + "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "", + "active:1674834236:1,7"], + ["p", + "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "", + "active:1721934607:1"] + ], + "content": "", + ... + "sig": "a9a4e2192eede77e6c9d24ddfab95ba3ff7c03fbd07ad011fff245abea431fb4d3787c2d04aad001cb039cb8de91d83ce30e9a94f82ac3c5a2372aa1294a96bd" + } + ``` + +- In the case that master decides to not permit on-behalf publishing for that active account anymore, but keep the already published events, for instance if the device that was using that active account is being substituted, and that key safely destroyed: + + ```json + { + "id": "567b41fc9060c758c4216fe5f8d3df7c57daad7ae757fa4606f0c39d4dd220ef", + "kind": "10100", + "pubkey": "8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd", + "tags": [ + ["p", + "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "", + "active:1674834236:1,7"], + ["p", + "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "", + "active:1721934607:1"], + ["p", + "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "", + "inactive:1722343578"] + ], + "content": "", + ... + "sig": "a9a4e2192eede77e6c9d24ddfab95ba3ff7c03fbd07ad011fff245abea431fb4d3787c2d04aad001cb039cb8de91d83ce30e9a94f82ac3c5a2372aa1294a96bd" + } + ``` + +- Or instead, if the active account got compromised, and it is best to consider all content published from that account,on-behalf of master account, to be compromised as well: + + ```json + { + "id": "567b41fc9060c758c4216fe5f8d3df7c57daad7ae757fa4606f0c39d4dd220ef", + "kind": "10100", + "pubkey": "8e0d3d3eb2881ec137a11debe736a9086715a8c8beeeda615780064d68bc25dd", + "tags": [ + ["p", + "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "", + "active:1674834236:1,7"], + ["p", + "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "", + "active:1721934607:1"], + ["p", + "477318cfb5427b9cfc66a9fa376150c1ddbc62115ae27cef72417eb959691396", + "", + "revoked:1722343578"] + ], + "content": "", + ... + "sig": "a9a4e2192eede77e6c9d24ddfab95ba3ff7c03fbd07ad011fff245abea431fb4d3787c2d04aad001cb039cb8de91d83ce30e9a94f82ac3c5a2372aa1294a96bd" + } + ``` + + +### Relay & Client Support + +Relays should answer requests such as `["REQ", "", {"authors": ["A"]}]` by querying both the `pubkey` and on-behalf `#b` tags `[1]` value. + +Relays SHOULD allow the master account to delete the events published by the active, inactive or revoked accounts, whenever the events have the on-behalf `b` tag present. \ No newline at end of file diff --git a/.ion-connect-protocol/ICIP-3000.md b/.ion-connect-protocol/ICIP-3000.md new file mode 100644 index 0000000..3afb1ac --- /dev/null +++ b/.ion-connect-protocol/ICIP-3000.md @@ -0,0 +1,242 @@ +ICIP-3000 +====== + +Moderated Large Scale Communities +------------------------------------ + +`draft` `optional` + +The goal of this ICIP is to enable large scale communities, from Reddit Style feeds to Telegram-like supergroups. + +# Community Definition + +The replaceable event `kind:31750` defines the community. It SHOULD include any tag that is relevant in doing so. + +A community definition event's `d` tag MAY be used as its name, but if a dedicated `name` tag is provided, it SHOULD be displayed instead of the `d` tag. If an about-like section needs to be displayed, the `description` tag can be used. + +A community definition SHOULD also contain one or more pictures, provided by 1 or more `imeta` tags. + +Each community is uniquely identified by its `h` tag, so clients MUST set it with an UUIDv7 value. + +The rules of the interactions between users and the community can be defined by 2 dimensions: openness and visibility, thus a community ca be `open` or `closed` and `public` or `private`. The rules matrix is as follows: + +| | open | closed | +|-------------|----------------------------------------------------------------------------------------------|----------------------------------------------------------------------| +| **public** | Anyone can look the community up and anyone can join it | Anyone can look the community up, but users can join only if invited | +| **private** | No one can look the community up, but anyone can join provided they have the invitation link | No one can look the community up and users can join only if invited | + +A community definition can also support adding settings for various use cases, one of such is the option to turn on/off the comments to its posts, making users unable to comment on any post of the community. Clients can do so by adding a `settings` tag with the following definition: +```jsonc +["settings", "", "", ], +``` +Supported settings: +* `comments_enabled` with a bool value +* `role_required_for_posting` with an enum value of `moderator` or `admin`; if this setting is missing, any role can create posts in the community + +Communities can also define 1 or more moderators and 1 or more admins. + +**_Community definition event example:_** +```jsonc +{ + "created_at": , + "kind": 31750, + "tags": [ + ["d", ""], + ["h", ""], + ["name", ""], + ["description", ""], + ["public"], // or ["private"] + ["open"], // or ["closed"] + ["settings", "comments_enabled", "true" or "false", ], + ["settings", "role_required_for_posting", "admin"/"moderator"], + ["imeta","url ","m image/webp",...], + + // moderators + ["p", "<32-bytes hex of a pubkey1>", "", "moderator"], + ["p", "<32-bytes hex of a pubkey2>", "", "moderator"], + ["p", "<32-bytes hex of a pubkey3>", "", "moderator"], + + // admins + ["p", "<32-bytes hex of a pubkey1>", "", "admin"], + ["p", "<32-bytes hex of a pubkey2>", "", "admin"], + ["p", "<32-bytes hex of a pubkey3>", "", "admin"], + //.. other tags relevant to defining the community + + ... + ], + // other fields... +} +``` + +# Joining a community + +Inviting into a community is done via a kind `1750` event. + +Users can also invite themselves into the community. + +If the community is `closed`, then an `authorization` tag MUST be added to the event with the stringified JSON of the kind `1750` event of an authorized user of that community (admin/moderator/owner) that authorizes the user to join the community. + +```jsonc +{ + "kind": 1750, + "tags": [ + ["h", ""], + ["p", "f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca"], + ["authorization", ], -- optonal -- + + //.. other tags relevant to the event + ], + "content": "optional reason for inviting to join the community", + // other fields... +} +``` + +# Posting to a community + +Kind `1` or `30023` events can be posted to a community. + +Reposts [(NIP 18)](https://github.com/nostr-protocol/nips/blob/master/18.md) `kind 6` to kind `1` events or `kind 16` to kind `30023` events can also be posted to a community. + +A community post can have replies/comments and those replies can have replies of their own as well. For those, clients MUST add the standard `e` [marker tag](https://github.com/nostr-protocol/nips/blob/master/10.md#marked-e-tags-preferred), pointing to the community post or comment they reply/comment to. + +Clients MUST add a community `h` tag to each posted event, including to replies/comments of those community posts. + +Users can react to any post or comment within the community via the kind `7` reactions. + +```jsonc +{ + "id": "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36", + "kind": 1, + "tags": [ + ["h", ""], + + //.. other tags relevant to the event + ], + "content": "hello world", + // other fields... +} +``` +```jsonc +{ + "kind": 1, + "tags": [ + ["h", ""], + ["e", "5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36", "", "root"], + + //.. other tags relevant to the event + ], + "content": "hello to you too", + // other fields... +} +``` + +Users can choose to delete their own posts or comments, or admins/moderators can choose to delete posts or comments of other users via a generic [kind 9](https://github.com/nostr-protocol/nips/blob/master/09.md) deletion request. + +# Transferring the ownership of the community +The current owner/author of the community can choose to transfer it to a different user, in doing so, a short-lived kind `1751` event is created with a `p` tag pointing to the new owner. +Clients MUST set both the `h` & the `a` tags that point to the community, as well as an `expiration` tag with a reasonable value. + +```jsonc +{ + "kind": 1751, + "tags": [ + ["a", "31750::"], + ["h", ""], + ["expiration", ], + ["p", "f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca"], + + //.. other tags relevant to the event + ], + "content": "optional reason for transfering the ownership", + // other fields... +} +``` + +The transfer is finalised when the recipient of kind `1751` publishes a kind `31750` event with the latest content and all the latest tags the community definition has and MUST also include an `a` tag pointing to the community definition variant of the previous owner. + +A community can be transferred multiple times so all `a` tags pointing to all previous community variants MUST be aggregated in the variant of the newest owner. + +# Managing & moderating the community + +Users that take part in the community have the following roles: + +1. `admin` can: + * invite other users into the community + * remove users from the community + * promote users to `moderator` or `admin` + * demote anyone to `moderator` or regular user + * update information about the community (name, description, picture, open etc.) + * change the visibility or the openness of the community + * change the settings of the community + * create posts or comments + * delete any posts or comments + * ban any user, including other admins, but not the community author/owner +2. `moderator` + * invite other users into the community + * remove users from the community, unless they are `admin` + * promote users to `moderator` + * demote anyone to regular user + * create posts or comments + * delete any posts or comments, unless of admin users + * ban any user, but not the community author/owner or admins +3. ` ` (none/empty) + * regular users can only create posts, comment or interact with other posts or comments, unless posting or commenting is disabled for them as per the community `settings` + +**_Banning_** is done through event kind `1752` and requires a revoking of the joining event (kind `1750`) of that user by deleting it beforehand via [kind 9](https://github.com/nostr-protocol/nips/blob/master/09.md) +```jsonc +{ + "kind": 1752, + "tags": [ + ["h", ""], + ["p", "f7234bd4c1394dda46d09f35bd384dd30cc552ad5541990f98844fb06676e9ca"], + + //.. other tags relevant to the event + ], + "content": "optional reason for banning", + // other fields... +} +``` + +Operations performed by authorised users (apart from the community owner/author) that change the community definition like: +* promoting users +* demoting users +* updating information about the community (name, description, picture, open etc.) +* changing the visibility or the openness of the community +* changing the settings of the community + +are done through kind `1753` events that are considered additive chronological patches to the community definition: +```jsonc +{ + "kind": 1753, + "tags": [ + ["h", ""], + ["name", ""], + ["description", ""], + ["public"], // or ["private"] + ["open"], // or ["closed"] + ["settings", "comments_enabled", "true" or "false", ], + ["settings", "role_required_for_posting", "admin"/"moderator"], + ["imeta","url ","m image/webp",...], + + // moderators + ["p", "<32-bytes hex of a pubkey1>", "", "moderator"], + ["p", "<32-bytes hex of a pubkey2>", "", "moderator"], + ["p", "<32-bytes hex of a pubkey3>", "", "moderator"], + + // admins + ["p", "<32-bytes hex of a pubkey1>", "", "admin"], + ["p", "<32-bytes hex of a pubkey2>", "", "admin"], + ["p", "<32-bytes hex of a pubkey3>", "", "admin"], + //.. other tags relevant to the event + ], + // other fields... +} +``` + +Clients MUST aggregate those patches and apply them incrementally and in a chronological fashion to the `31750` community definition. +Clients of the community author/owner MUST also send the updated `31750` event with all the applied patches to keep the definition consistent. + + +# Client & Relay considerations + +Both the clients and the relays MUST enforce all the constraints and safety checks mentioned in this ICIP. \ No newline at end of file diff --git a/.ion-connect-protocol/README.md b/.ion-connect-protocol/README.md new file mode 100644 index 0000000..0a5a842 --- /dev/null +++ b/.ion-connect-protocol/README.md @@ -0,0 +1,13 @@ +### ION Connect Protocol is an extension of [NOSTR Protocol](https://github.com/nostr-protocol/nips) + +##### This folder aggregates all modifications made to the NOSTR Protocol as well as all the custom ICIPs (ION Connect Implementation Possibilities) exclusive to ION Connect Protocol. + +###### Those modifications or additions are not **yet** supported by the NOSTR protocol. + +## protocol changes + +| ICIPs/NIPs | Change Type | NOSTR NIPs Pull Request | comments | +|------------|-------------|----------------------------------------------------------|------------------------------------------------------------------------------------| +| ICIP-1000 | Addition | [1522](https://github.com/nostr-protocol/nips/pull/1522) | | +| ICIP-2000 | Addition | [1482](https://github.com/nostr-protocol/nips/pull/1482) | | +| ICIP-3000 | Addition | | an extension of [NIP-72](https://github.com/nostr-protocol/nips/blob/master/72.md) |