Compare commits

..

1 Commits

Author SHA1 Message Date
pablof7z
b5a16a3264 NIP-C1: Collaborative Ownership 2026-02-16 08:51:23 +00:00
3 changed files with 122 additions and 35 deletions

36
85.md
View File

@@ -10,7 +10,7 @@ Certain Webs of Trust calculations require access to a large volume of events an
## Assertion Events ## Assertion Events
Trusted Assertions are always addressable (replaceable) events with the `d` tag pointing to the "subject" of the assertion. This NIP currently recognizes four distinct target "subjects" on which such calculations can be performed: *pubkeys*, *regular events*, *addressable events*, and *nip73 identifiers*. Each subject type is mapped to an event kind: Trusted Assertions are always addressable (replaceable) events with the `d` tag pointing to the "subject" of the assertion. This NIP currently recognizes three distinct target "subjects" on which such calculations can be performed: *pubkeys*, *regular events*, and *addressable events*. Each subject type is mapped to an event kind:
| Subject | Event Kind | `d` tag value | | Subject | Event Kind | `d` tag value |
| ------------------ | -------------- | ----------------- | | ------------------ | -------------- | ----------------- |
@@ -26,7 +26,6 @@ Example of ranking a pubkey with a web of trust score of `89`:
```jsonc ```jsonc
{ {
"kind": 30382, "kind": 30382,
"pubkey": "<service pubkey>",
"tags": [ "tags": [
["d", "e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"], // target user's public key ["d", "e88a691e98d9987c964521dff60025f60700378a4879180dcbbb4a5027850411"], // target user's public key
["rank", "89"], ["rank", "89"],
@@ -36,8 +35,6 @@ Example of ranking a pubkey with a web of trust score of `89`:
} }
``` ```
Service providers MUST use different service keys for distinct algorithms, including a key per user when the algorithm is personalized to that user's point of view or settings.
## Kind 30382: Users as Subject: ## Kind 30382: Users as Subject:
The following result types have been declared: The following result types have been declared:
@@ -112,17 +109,11 @@ Kind `10040` lists the user's authorized providers for each result. Each `kind:t
{ {
"kind": 10040, "kind": 10040,
"tags": [ "tags": [
["<kind:tag>", "<service key>", "<relay hint>"],
// examples
["30382:rank", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"], ["30382:rank", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"],
["30382:rank", "3d842afecd5e293f28b6627933704a3fb8ce153aa91d790ab11f6a752d44a42d", "wss://nostr.wine"], ["30382:rank", "3d842afecd5e293f28b6627933704a3fb8ce153aa91d790ab11f6a752d44a42d", "wss://nostr.wine"],
["30382:zap_amt_sent", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"], ["30382:zap_amt_sent", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"],
], ],
"content": nip44Encrypt(JSON.stringify([ "content": nip44Encrypt(JSON.stringify([
["<kind:tag>", "<service key>", "<relay hint>"],
// examples
["30383:rank", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"], ["30383:rank", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"],
["30384:rank", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"], ["30384:rank", "4fd5e210530e4f6b2cb083795834bfe5108324f1ed9f00ab73b9e8fcfe5f12fe", "wss://nip85.nostr.band"],
]), ]),
@@ -139,28 +130,3 @@ Service providers SHOULD update Trusted Assertions as fast as new information ar
Service providers MAY limit access to the results by using paid relays. Service providers MAY limit access to the results by using paid relays.
In TAs, `p`, `e`, and `a` tags with the same value as the `d` tag MAY be used to add a relay hint to the home relay of that user or event. In TAs, `p`, `e`, and `a` tags with the same value as the `d` tag MAY be used to add a relay hint to the home relay of that user or event.
## Appendix 1: Service provider discoverability
Service Providers SHOULD sign a kind `0` of each service key that explains who controls the key and what the current version of the algorithm is about.
```jsonc
{
"kind": 0,
"pubkey": "<service pubkey>",
"tags": [],
"content": "{
\"name\" = \"Vitor's Brainstormer\",
\"about\" = \"A Web of Trust algorithm from Vitor's point of view that considers Follows and Mutes, but no reports, and gives extra score points for anyone around Boston\",
\"picture\" = \"https://brainstorm.com/logo.png\",
\"website\" = \"https://brainstorm.com\"
}",
// other fields...
}
```
Clients wishing to offer a list of Service Providers to their users SHOULD:
1. Download kind `10040` events of the user's follow list
2. Connect to each of the listed relays and download the kind `0` of the respective service keys
3. Parse the kind `0` and collect the `website` property
4. Load the OpenGraph tags of that website and display them as clickable items

119
C1.md Normal file
View File

@@ -0,0 +1,119 @@
NIP-C1
======
Collaborative Ownership
-----------------------
`draft` `optional`
This NIP defines a mechanism for multiple pubkeys to collaboratively maintain addressable events while preserving backwards compatibility.
## Motivation
Certain applications require shared ownership where:
1. **Attribution matters**: Each collaborator signs with their own key
2. **Dynamic membership**: Owners can be added or removed
3. **Backwards compatibility**: Non-supporting clients see normal events
## Specification
### Collaborative Pointer Event
A new addressable event kind `39382` serves as a pointer to collaboratively-owned content:
```jsonc
{
"kind": 39382,
"pubkey": "<creator-pubkey>",
"tags": [
["d", "<target-kind>-<slug>"],
["k", "<target-kind>"],
["p", "<owner-1-pubkey>"],
["p", "<owner-2-pubkey>"],
["p", "<owner-3-pubkey>"],
["relay", "wss://relay1.example.com"],
["relay", "wss://relay2.example.com"]
],
"content": "",
"created_at": 1234567890
}
```
#### Tag Definitions
| Tag | Required | Description |
|-----|----------|-------------|
| `d` | Yes | `<target-kind>-<slug>` - prevents collisions across kinds |
| `k` | Yes | Target event kind (avoids string parsing of `d` tag) |
| `p` | Yes | Owner pubkeys (one or more) |
| `relay` | No | Relay hints; if absent, use NIP-65 outbox model |
### Resolution Algorithm
To resolve the current state of collaboratively-owned content:
1. Parse the `39382` pointer event to extract owners (`p` tags) and target kind (`k` tag)
2. Extract the slug from the `d` tag (everything after the first `-`)
3. Query: `{"kinds": [<target-kind>], "authors": [<all-owners>], "#d": ["<slug>"], "limit": 1}`
4. Use `relay` tags if present; otherwise fall back to NIP-65 outbox relays
5. Return the event with the highest `created_at`
### Back-Reference (Optional)
Target events MAY include an `a` tag pointing to the `39382` pointer:
```jsonc
{
"kind": 30023,
"tags": [
["d", "my-article"],
["a", "39382:<pointer-creator-pubkey>:30023-my-article"]
]
}
```
This enables clients to discover that an event is part of a collaborative set.
## Example
### Pointer Event
```jsonc
{
"kind": 39382,
"pubkey": "alice-pubkey",
"tags": [
["d", "30023-collaborative-guide"],
["k", "30023"],
["p", "alice-pubkey"],
["p", "bob-pubkey"],
["p", "carol-pubkey"],
["relay", "wss://relay.example.com"]
],
"content": ""
}
```
### Target Article (by any owner)
```jsonc
{
"kind": 30023,
"pubkey": "bob-pubkey",
"tags": [
["d", "collaborative-guide"],
["title", "A Collaborative Guide"],
["a", "39382:alice-pubkey:30023-collaborative-guide"]
],
"content": "..."
}
```
### Client Resolution
1. Client receives `naddr` for the `39382` pointer
2. Parses owners: `[alice, bob, carol]`
3. Queries: `{"kinds": [30023], "authors": ["alice", "bob", "carol"], "#d": ["collaborative-guide"], "limit": 1}`
4. Returns most recent version regardless of which owner published it

View File

@@ -109,6 +109,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
- [NIP-B7: Blossom](B7.md) - [NIP-B7: Blossom](B7.md)
- [NIP-BE: Nostr BLE Communications Protocol](BE.md) - [NIP-BE: Nostr BLE Communications Protocol](BE.md)
- [NIP-C0: Code Snippets](C0.md) - [NIP-C0: Code Snippets](C0.md)
- [NIP-C1: Collaborative Ownership](C1.md)
- [NIP-C7: Chats](C7.md) - [NIP-C7: Chats](C7.md)
- [NIP-EE: E2EE Messaging using MLS Protocol](EE.md) --- **unrecommended**: superseded by the [Marmot Protocol](https://github.com/marmot-protocol/marmot) - [NIP-EE: E2EE Messaging using MLS Protocol](EE.md) --- **unrecommended**: superseded by the [Marmot Protocol](https://github.com/marmot-protocol/marmot)
@@ -294,6 +295,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `39000-9` | Group metadata events | [29](29.md) | | `39000-9` | Group metadata events | [29](29.md) |
| `39089` | Starter packs | [51](51.md) | | `39089` | Starter packs | [51](51.md) |
| `39092` | Media starter packs | [51](51.md) | | `39092` | Media starter packs | [51](51.md) |
| `39382` | Collaborative Pointer | [C1](C1.md) |
| `39701` | Web bookmarks | [B0](B0.md) | | `39701` | Web bookmarks | [B0](B0.md) |
[NUD: Custom Feeds]: https://wikifreedia.xyz/cip-01/ [NUD: Custom Feeds]: https://wikifreedia.xyz/cip-01/