{"id":"719882512e65e5030063606d9f1af1f52c0d1ef1b9048758cb14ae4e862bf3b1","pubkey":"da19f1cd34beca44be74da4b306d9d1dd86b6343cef94ce22c49c6f59816e5bd","created_at":1774618268,"kind":30817,"tags":[["title","NIP-REPUTATION: Structured Reputation & Reviews"],["k","30520"],["d","nip-reputation"]],"content":"NIP-REPUTATION\n===============\n\nStructured Reputation & Reviews\n---------------------------------\n\n`draft` `optional`\n\nOne addressable event kind for completion-verified ratings on Nostr. Credential attestations use [NIP-VA](https://github.com/forgesworn/nostr-attestations/blob/main/NIP-VA.md) kind 31000 (Verifiable Attestation) with `type: credential`.\n\n> **Standalone.** This NIP works independently on any Nostr application.\n\n## Motivation\n\nNostr has NIP-32 for generic labels and NIP-58 for badges, but neither provides structured reviews tied to verified completions. A freelancer with 500 five-star jobs on one platform starts at zero on another. Current Nostr reputation approaches lack:\n\n- **Completion verification** - no proof that the rater actually transacted with the rated party\n- **Multi-criterion scoring** - no way to rate punctuality separately from quality\n- **Stake weighting** - a review from a 10-sat transaction weighs the same as one from a 500,000-sat transaction\n- **Portable credentials** - professional qualifications have no machine-readable format\n\nThis NIP defines one event kind where ratings are cryptographically signed, tied to verifiable completion events, and portable across any Nostr client. Review responses use NIP-22 comments (kind 1111) rather than a dedicated kind. Activity evidence (proof of delivery, certifications earned, portfolio artefacts) is handled by [NIP-EVIDENCE](./NIP-EVIDENCE.md) (kind 30578). Reputation summaries are computed client-side from kind 30520 events rather than defined as a protocol kind.\n\n## Relationship to Existing NIPs\n\n- **[NIP-32](https://github.com/nostr-protocol/nips/blob/master/32.md) (Labelling):** Generic labels lack completion verification, multi-criterion scoring, and stake weighting. NIP-REPUTATION provides structured, verifiable ratings that NIP-32 labels cannot express.\n- **[NIP-58](https://github.com/nostr-protocol/nips/blob/master/58.md) (Badges):** Display-oriented awards, not structured reviews tied to verified completions. NIP-58 provides static credentials (\"You hold this certification\"); NIP-REPUTATION provides dynamic transactional ratings (\"How well you performed this job\"). Together they create a two-layer trust signal: credentials plus transaction history.\n- **[NIP-25](https://github.com/nostr-protocol/nips/blob/master/25.md) (Reactions):** Lightweight sentiment with no structured criteria, verification, or stake weighting.\n- **[NIP-22](https://github.com/nostr-protocol/nips/blob/master/22.md) (Comments):** Review responses use NIP-22 comments (kind 1111) referencing the Rating event. This enables threaded discussion on any rating without requiring a dedicated kind.\n- **[NIP-EVIDENCE](./NIP-EVIDENCE.md) (kind 30578):** Activity evidence (proof of delivery, certifications earned, portfolio artefacts) SHOULD be recorded as NIP-EVIDENCE records. A Rating (kind 30520) MAY reference evidence records via `e` tags for verifiable proof backing the review.\n- **[NIP-VA](https://github.com/forgesworn/nostr-attestations/blob/main/NIP-VA.md) (kind 31000):** Credential attestations use NIP-VA with `type: credential`. See the NIP-VA specification.\n\nUses [NIP-02](https://github.com/nostr-protocol/nips/blob/master/02.md) (Contact Lists) for social-graph-weighted reputation scoring.\n\n### Relationship to Community NIPs\n\n- **NIP-85 Trusted Assertions (kinds 30382–30385):** NIP-85 providers compute aggregate metrics (follower counts, WoT rankings, engagement scores) and publish them as addressable events. NIP-REPUTATION provides first-party, completion-verified ratings tied to specific transactions — the raw input data that NIP-85 providers could ingest and aggregate. NIP-85 computes; NIP-REPUTATION records.\n- **TSM Ranking Services (kind 37573):** The Trust Service Machines framework provides a request/response pattern for trust computation services, including ranking. TSM ranks subjects algorithmically from network data; NIP-REPUTATION records individual human ratings with structured criteria and stake weighting. TSM could consume NIP-REPUTATION events as input for its ranking algorithms.\n- **Service Attestations (kinds 38383/38384):** Service Attestations define a fixed schema for bilateral service ratings with `service` categories, `rating` scores, and optional Namecoin identity anchoring. NIP-REPUTATION differs in three ways: ratings are tied to verified completion events (not self-reported), support multi-criterion scoring (not single-score), and include stake weighting. Service Attestations are better suited for simple marketplace reviews; NIP-REPUTATION is designed for high-assurance contexts where the rating must be backed by verifiable evidence of the transaction.\n\n## Kinds\n\n| kind  | description             |\n| ----- | ----------------------- |\n| 30520 | Rating                  |\n\n> Credential attestations use NIP-VA kind 31000 with `type: credential`. Application-specific tags (credential_type, issuer_type, etc.) are carried on the NIP-VA event. See the [NIP-VA specification](https://github.com/forgesworn/nostr-attestations/blob/main/NIP-VA.md) for details.\n\n---\n\n## Kind 30520: Rating\n\nPublished by a participant after transaction completion to rate the counterparty. Each participant publishes exactly one rating per transaction, enforced by the `d` tag format. The `e` tag references a completion event, providing cryptographic proof the rater participated.\n\n```json\n{\n    \"kind\": 30520,\n    \"pubkey\": \"<rater-hex-pubkey>\",\n    \"created_at\": 1698765500,\n    \"tags\": [\n        [\"d\", \"tx_abc123:rating:requester\"],\n        [\"p\", \"<rated-party-pubkey>\"],\n        [\"e\", \"<completion-event-id>\", \"<relay-hint>\"],\n        [\"alt\", \"Rating: 4/5 overall for freelance provider\"],\n        [\"domain\", \"freelance\"],\n        [\"t\", \"domain:freelance\"],\n        [\"role\", \"provider\"],\n        [\"rating\", \"overall\", \"4\"],\n        [\"rating\", \"quality\", \"5\"],\n        [\"rating\", \"communication\", \"4\"],\n        [\"rating\", \"punctuality\", \"3\"],\n        [\"stake_evidence\", \"50000\", \"SAT\"],\n        [\"payment_method\", \"lightning\"]\n    ],\n    \"content\": \"Excellent work on the logo design. Delivered on time with minor revisions needed. Great communication throughout.\",\n    \"id\": \"<32-byte-hex>\",\n    \"sig\": \"<64-byte-hex>\"\n}\n```\n\nTags:\n\n* `d` (REQUIRED): Format `<transaction_id>:rating:<rater_role>`. Ensures one rating per role per transaction via addressable event semantics. Role values are application-defined. Common conventions include `buyer`/`seller`, `client`/`contractor`, `requester`/`provider`, or `reviewer`/`subject`. For three-party transactions, a third role (e.g. `beneficiary`, `recipient`) enables three ratings per transaction.\n* `p` (REQUIRED): Pubkey of the party being rated.\n* `e` (REQUIRED): References a completion/confirmation event. Verifiable proof the rater participated. Implementations SHOULD verify: the event exists with a valid signature, the rater's pubkey appears as a participant, and the transaction reached a terminal state.\n* `domain` (RECOMMENDED): Category this transaction belonged to. This is a multi-letter tag; relays cannot filter on it. Clients MUST post-filter by `domain` after retrieval.\n* `t` (RECOMMENDED when `domain` is present): `[\"t\", \"domain:<category>\"]` (e.g. `[\"t\", \"domain:freelance\"]`). Enables relay-side discovery by domain via `#t` filters. The `domain` tag remains the canonical source; the `t` tag is a relay-filterable mirror.\n* `role` (RECOMMENDED): Whether the rated party was `provider`, `requester`, or `beneficiary`.\n* `rating` (REQUIRED, at least one): Multi-value tag: `[\"rating\", \"<criterion>\", \"<value>\"]`. The `overall` criterion MUST be present. Values are integers 1-5. Additional criteria are application-defined.\n* `stake_evidence` (RECOMMENDED): `[\"stake_evidence\", \"<amount>\", \"<currency>\"]`. How much was at stake. Higher stakes imply greater credibility.\n* `payment_method` (OPTIONAL): Payment method used for the transaction (e.g. `lightning`, `ecash`, `cash`, `onchain`). Including `payment_method` provides context for the rating. A rating from a Lightning-settled transaction demonstrates different trust properties than one from a cash transaction; the former proves cryptographic payment completion, while the latter relies on the rater's attestation.\n* `content` (OPTIONAL): Free-text review.\n\n### Rating Scale\n\n| Value | Meaning                            |\n| ----- | ---------------------------------- |\n| 1     | Unacceptable - serious issues      |\n| 2     | Poor - below expectations          |\n| 3     | Adequate - met basic expectations  |\n| 4     | Good - above expectations          |\n| 5     | Excellent - outstanding            |\n\n### Three-Party Transactions\n\nWhen three distinct participants are involved (e.g. buyer, courier, and recipient), the `beneficiary` role enables up to three ratings per transaction, one per role, each with a unique `d` tag.\n\n### Timing\n\nRatings SHOULD be published within 30 days of transaction completion. Implementations SHOULD reject ratings published after this window.\n\n### REQ Filters\n\nNIP-01 defines subscription filters for single-letter tag names only. The `domain` tag is client-side metadata; filter by `#p` at the relay, then post-filter by `domain` tag client-side.\n\n```json\n[\n    {\"kinds\": [30520], \"#p\": [\"<provider-pubkey>\"]},\n    {\"kinds\": [30520], \"authors\": [\"<provider-pubkey>\"]}\n]\n```\n\n---\n\n## Composing with NIP-22\n\nReview responses use [NIP-22](https://github.com/nostr-protocol/nips/blob/master/22.md) comments (kind 1111) referencing the Rating event. The rated party publishes a comment on the rating rather than a dedicated response kind. This keeps review threads consistent with how comments work across Nostr.\n\nNIP-22 comments use uppercase `K` for the root kind and uppercase `E` for the root event reference.\n\n```json\n{\n    \"kind\": 1111,\n    \"tags\": [\n        [\"K\", \"30520\"],\n        [\"E\", \"<rating-event-id>\", \"wss://relay.example.com\"],\n        [\"p\", \"<rater-pubkey>\"]\n    ],\n    \"content\": \"Thank you for the feedback. The delay was due to a supply chain issue that has since been resolved.\"\n}\n```\n\nClients SHOULD display NIP-22 comments alongside the rating they reference. Multiple comments are permitted, enabling threaded discussion on any rating.\n\n---\n\n## Composing with NIP-EVIDENCE\n\nActivity evidence (proof of work completed, certifications earned, portfolio artefacts) SHOULD be recorded using [NIP-EVIDENCE](./NIP-EVIDENCE.md) kind 30578 rather than a reputation-specific kind. A rating MAY reference one or more evidence records to provide verifiable backing.\n\n### Example: Rating with Evidence Reference\n\nA provider completes a freelance project. The completion evidence is recorded as a NIP-EVIDENCE event, and the subsequent rating references it.\n\n**Step 1: Record evidence (kind 30578)**\n\n```json\n{\n    \"kind\": 30578,\n    \"pubkey\": \"<publisher-hex-pubkey>\",\n    \"created_at\": 1698780000,\n    \"tags\": [\n        [\"d\", \"<publisher-pubkey>:evidence:1698780000\"],\n        [\"evidence_type\", \"project_completion\"],\n        [\"p\", \"<subject-pubkey>\"],\n        [\"domain\", \"freelance\"],\n        [\"date\", \"2024-10-31\"],\n        [\"outcome\", \"delivered\"]\n    ],\n    \"content\": \"\",\n    \"id\": \"aaaa1111bbbb2222cccc3333dddd4444eeee5555ffff6666aaaa1111bbbb2222\",\n    \"sig\": \"<64-byte-hex>\"\n}\n```\n\n**Step 2: Rating references the evidence (kind 30520)**\n\n```json\n{\n    \"kind\": 30520,\n    \"pubkey\": \"<rater-hex-pubkey>\",\n    \"created_at\": 1698785000,\n    \"tags\": [\n        [\"d\", \"tx_def456:rating:requester\"],\n        [\"p\", \"<rated-party-pubkey>\"],\n        [\"e\", \"<completion-event-id>\", \"<relay-hint>\"],\n        [\"e\", \"aaaa1111bbbb2222cccc3333dddd4444eeee5555ffff6666aaaa1111bbbb2222\", \"<relay-hint>\"],\n        [\"domain\", \"freelance\"],\n        [\"t\", \"domain:freelance\"],\n        [\"role\", \"provider\"],\n        [\"rating\", \"overall\", \"5\"],\n        [\"rating\", \"quality\", \"5\"],\n        [\"stake_evidence\", \"100000\", \"SAT\"]\n    ],\n    \"content\": \"Outstanding delivery with full documentation.\",\n    \"id\": \"<32-byte-hex>\",\n    \"sig\": \"<64-byte-hex>\"\n}\n```\n\nThe second `e` tag references the NIP-EVIDENCE record, allowing clients to verify the evidence backing the rating.\n\n---\n\n## Reputation Aggregation\n\nThis NIP deliberately does not define a summary kind. Reputation summaries are an application-level concern, not a protocol primitive. Applications SHOULD compute summaries client-side by fetching kind 30520 events for a given pubkey and applying their chosen weighting and aggregation strategy.\n\nAggregators MAY publish pre-computed summaries using application-specific kinds for caching and performance, but such kinds are outside the scope of this NIP.\n\n### Bayesian Averaging\n\nImplementations SHOULD use Bayesian averaging to prevent small-sample manipulation:\n\n`adjusted = (C * M + R * N) / (C + N)`\n\nWhere C = confidence threshold (e.g. 10 ratings), M = global mean, R = provider's raw average, N = provider's rating count.\n\n---\n\n## Trust Weighting\n\nImplementations SHOULD weight ratings using available trust signals:\n\n1. **Stake weight** - Ratings from higher-value transactions carry more weight.\n2. **Social distance** - Ratings from pubkeys in the user's NIP-02 contact list (or 2-hop follows) carry more weight than ratings from strangers.\n3. **Recency** - Recent ratings MAY be weighted more heavily than old ones.\n4. **Credential backing** - Ratings from credentialed participants (verified via `kind:31000`) MAY carry additional weight.\n\nThe protocol deliberately does not prescribe a scoring algorithm; implementations choose their own weighting and aggregation strategies.\n\n## Stake Weighting\n\nRatings carry different weight based on the economic stake of the underlying transaction. A 5-star rating from a 500,000-sat job is more meaningful than one from a 100-sat micro-task.\n\n### Informational: Reference Weighting Algorithm\n\nThis algorithm is illustrative. Applications SHOULD define their own weighting logic suited to their domain and trust requirements.\n\n```\nweight(rating) = log2(1 + amount_sats) * recency_factor * completion_factor\n```\n\nWhere:\n- `amount_sats` - transaction amount converted to satoshis (from `amount` and `currency` tags)\n- `recency_factor` - `1.0` for ratings < 30 days old, decaying by `0.95^months` thereafter\n- `completion_factor` - `1.0` if rating references a verified completion or settlement event, `0.5` otherwise\n\n### Informational: Reference Aggregation\n\nA provider's aggregate score for criterion `c` could be computed as:\n\n```\nscore(c) = sum(rating_c * weight) / sum(weight)\n```\n\nThis weighted average naturally surfaces ratings backed by significant transactions while still counting smaller ones. Applications MAY use alternative aggregation strategies.\n\n### Why Stake Weighting Matters\n\nWithout stake weighting, an attacker can inflate ratings cheaply by creating many low-value transactions and rating them highly. With stake weighting, inflating reputation requires proportional economic commitment.\n\n---\n\n## Protocol Flow\n\n\n![Rating Flow](https://raw.githubusercontent.com/forgesworn/nip-drafts/main/images/reputation-1.png)\n\n```mermaid\nsequenceDiagram\n    participant R as Requester\n    participant P as Provider\n    participant Relay as Nostr Relay\n\n    Note over R,P: Transaction completes\n\n    R->>Relay: kind 30578 (Evidence Record, optional)\n    R->>Relay: kind 30520 (Rating of Provider)\n    P->>Relay: kind 30520 (Rating of Requester)\n\n    Note over P: Provider reads rating\n\n    P->>Relay: kind 1111 (NIP-22 Comment, optional)\n```\n\n---\n\n## Example Applications\n\n### Marketplace Seller Ratings\n\nNIP-15 marketplace implementations can use NIP-REPUTATION to rate sellers after purchase. The `stake_evidence` tag ties the rating to the actual transaction value.\n\n### Content Creator Reviews\n\nReaders rate paid content (articles, courses, media). Stake weighting ensures reviews from higher-value purchases carry more weight.\n\n### Mentor/Tutor Ratings\n\nStudents rate mentors after paid sessions. Multi-criterion scoring (knowledge, communication, punctuality) provides actionable feedback.\n\n### Peer Code Review\n\nDevelopers rate code reviewers. The `completion_event` references a merged PR or closed bounty, proving the review actually happened.\n\n---\n\n## Security Considerations\n\n* **Completion verification.** The `e` tag on `kind:30520` references a completion event, preventing rating fabrication. Implementations SHOULD verify this link.\n* **One rating per role per transaction.** Addressable event semantics (`d` tag) enforce uniqueness. Republishing replaces the previous rating.\n* **Sybil resistance.** Stake evidence and social distance weighting reduce the impact of fake ratings. Zero-stake ratings from unknown pubkeys carry minimal weight.\n* **Self-declared credentials.** `kind:31000` supports `issuer_type: self_declared`; implementations SHOULD display these distinctly from authority-issued credentials.\n* **Timing attacks.** The 30-day rating window limits delayed reputation manipulation. Implementations SHOULD enforce this window and MAY apply reduced weight to ratings published near the deadline.\n\n## Privacy\n\n* Rating `content` is public by default. For sensitive domains, implementations MAY encrypt review text using NIP-44.\n* The `e` tag linking a rating to a completion event reveals that a transaction occurred between two parties. Participants should be aware that publishing a rating creates a public association.\n* Evidence records referenced by ratings (kind 30578) MAY use NIP-44 encryption for sensitive categories (healthcare, education).\n\n---\n\n## Test Vectors\n\n### Kind 30520 - Rating\n\n```json\n{\n  \"kind\": 30520,\n  \"pubkey\": \"a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2\",\n  \"created_at\": 1709740800,\n  \"tags\": [\n    [\"d\", \"tx_abc123:rating:requester\"],\n    [\"p\", \"b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3\"],\n    [\"e\", \"dddd4444eeee5555ffff6666aaaa1111bbbb2222cccc3333dddd4444eeee5555\", \"wss://relay.example.com\"],\n    [\"alt\", \"Rating: 4/5 overall for freelance provider\"],\n    [\"domain\", \"freelance\"],\n    [\"t\", \"domain:freelance\"],\n    [\"role\", \"provider\"],\n    [\"rating\", \"overall\", \"4\"],\n    [\"rating\", \"quality\", \"5\"],\n    [\"rating\", \"communication\", \"4\"],\n    [\"rating\", \"punctuality\", \"3\"],\n    [\"stake_evidence\", \"50000\", \"SAT\"],\n    [\"payment_method\", \"lightning\"]\n  ],\n  \"content\": \"Excellent work on the logo design. Delivered on time with minor revisions needed.\",\n  \"id\": \"<32-byte-hex>\",\n  \"sig\": \"<64-byte-hex>\"\n}\n```\n\n---\n\n## Dependencies\n\n* [NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md): Basic protocol flow, addressable events\n* [NIP-02](https://github.com/nostr-protocol/nips/blob/master/02.md): Contact lists (social distance weighting)\n* [NIP-22](https://github.com/nostr-protocol/nips/blob/master/22.md): Comments (review responses)\n* [NIP-32](https://github.com/nostr-protocol/nips/blob/master/32.md): Labelling (category classification)\n* [NIP-58](https://github.com/nostr-protocol/nips/blob/master/58.md): Badges (credential compatibility)\n* [NIP-EVIDENCE](./NIP-EVIDENCE.md): Evidence recording (activity evidence, proof of delivery)\n\n## Reference Implementation\n\nNo public reference implementation exists yet. Implementors SHOULD refer to the kind definitions above.\n\nA minimal implementation requires:\n\n1. A Nostr client that supports addressable event publishing and NIP-02 contact list queries.\n2. A scoring engine that weights ratings by stake, social distance, and recency.\n3. Verification logic that checks the `e` tag on `kind:30520` ratings references a valid completion event.","sig":"b0e3e72a9f23c98eecb43f70f05269137286c8c64bb6a954a59283484145519f8b4945dafd148b8ad327f88a53086ef0aad7c36da36b23f7c32bdefc0a9d0d94"}