Files
nips/C1.md
2026-02-16 08:51:23 +00:00

120 lines
2.9 KiB
Markdown

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