clone

every nostr nip as a chapter of an illustrated, early-2000s printed game manual

main
nip.guide / site / nips / 58.html
58.html 22.6K
1<!DOCTYPE html>2<html lang="en">3<head>4<meta charset="utf-8">5<meta name="viewport" content="width=device-width, initial-scale=1">6<title>NIP-58 - Badges — Nostr Instruction Manual</title>7<meta name="description" content="NIP-58: badges. Badge definitions, badge awards, profile badges, and badge sets. Kinds 30009, 8, 10008, and 30008. Complete manual page.">8<link rel="preload" href="../assets/fonts/michroma-400-latin.woff2" as="font" type="font/woff2" crossorigin>9<link rel="preload" href="../assets/fonts/exo2-var-latin.woff2" as="font" type="font/woff2" crossorigin>10<link rel="preload" href="../assets/fonts/sairacondensed-600-latin.woff2" as="font" type="font/woff2" crossorigin>11<link rel="preload" href="../assets/fonts/sairacondensed-700-latin.woff2" as="font" type="font/woff2" crossorigin>12<link rel="preload" href="../assets/fonts/sairacondensed-500-latin.woff2" as="font" type="font/woff2" crossorigin>13<link rel="preload" href="../assets/fonts/sharetechmono-400-latin.woff2" as="font" type="font/woff2" crossorigin>14<link rel="preload" href="../assets/fonts/exo2-400i-latin.woff2" as="font" type="font/woff2" crossorigin>15<link rel="icon" href="../assets/favicon.svg" type="image/svg+xml">16<link rel="stylesheet" href="../assets/manual.css">17</head>18<body>1920<svg width="0" height="0" style="position:absolute">21 <defs>22 <marker id="arr" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto">23 <path d="M1,1 L8,4.5 L1,8 Z" fill="#f26a00"/>24 </marker>25 <marker id="arrb" markerWidth="9" markerHeight="9" refX="7" refY="4.5" orient="auto">26 <path d="M1,1 L8,4.5 L1,8 Z" fill="#2e5f9e"/>27 </marker>28 </defs>29</svg>3031<div class="page">32 <span class="staple s1"></span><span class="staple s2"></span>3334 <header class="band">35 <a class="logo" href="../index.html">NOSTR<b>▸</b>PROTOCOL MANUAL</a>36 <span class="booklet-note">Chapter 58 - Social</span>37 </header>38 <nav class="tabs">39 <a href="../index.html">Contents</a>40 <a href="#overview" class="on">Overview</a>41 <a href="#spec">Spec</a>42 <a href="#examples">Examples</a>43 <a href="#history">History</a>44 </nav>4546 <div class="chapter">47 <div class="nipno" data-n="58">58</div>48 <div class="titles">49 <div class="kicker">Nostr Implementation Possibility - Hex № 58</div>50 <h1>Badges</h1>51 <p class="sub">Four event kinds let issuers define and award badges, and let users accept, order, and display them on their profiles.</p>52 </div>53 </div>5455 <main class="spread">56 <div class="main">5758 <h2 class="bar" id="overview"><span class="num">1</span> Overview</h2>59 <p>A <strong>badge</strong> is a small honor that one user gives to another. An <strong>issuer</strong> may award badges in recognition, in gratitude, for participation, or in appreciation of a goal, task, or cause. An <strong>awardee</strong> may decorate their profile with badges from issuers they deem reputable, for fame, notoriety, recognition, or support.</p>60 <p>This NIP defines four special event kinds. A <strong>Badge Definition</strong> (kind <code>30009</code>) describes a badge. A <strong>Badge Award</strong> (kind <code>8</code>) gives that badge to one or more pubkeys. A <strong>Profile Badges</strong> event (kind <code>10008</code>) lists the badges a user accepts and the order to display them. A <strong>Badge Set</strong> (kind <code>30008</code>) groups accepted badges under a label.</p>61 <p>Awards are one-way. An awarded badge is immutable and non-transferable. Only the awardee decides whether it appears on their profile.</p>6263 <div class="box hint">64 <span class="tag">Hint!</span>65 <p>Think of it as the sticker page in the back of the manual. Anyone can print stickers (definitions) and hand them out (awards). But only you decide which stickers go on your own console (profile badges).</p>66 </div>6768 <figure class="diagram">69 <div class="frame">70 <svg viewBox="0 0 560 210" role="img" aria-label="Issuer publishes a badge definition and a badge award to a relay; the awardee accepts with a profile badges event; viewers read all three">71 <rect class="d-actor" x="10" y="80" width="110" height="50" rx="8"/>72 <text class="d-actor-label" x="65" y="102" text-anchor="middle">Issuer</text>73 <text class="d-note" x="65" y="119" text-anchor="middle">Alice</text>74 <rect class="d-actor" x="225" y="80" width="110" height="50" rx="8"/>75 <text class="d-actor-label" x="280" y="109" text-anchor="middle">Relay</text>76 <rect class="d-actor" x="440" y="14" width="110" height="50" rx="8"/>77 <text class="d-actor-label" x="495" y="36" text-anchor="middle">Awardee</text>78 <text class="d-note" x="495" y="53" text-anchor="middle">Bob</text>79 <rect class="d-actor" x="440" y="146" width="110" height="50" rx="8"/>80 <text class="d-actor-label" x="495" y="175" text-anchor="middle">Viewers</text>81 <path class="d-msg d-flow" d="M122,105 L222,105"/>82 <text class="d-label" x="172" y="97" text-anchor="middle">30009 + 8</text>83 <path class="d-msg blue d-flow" d="M337,92 C380,80 395,60 438,46"/>84 <text class="d-label" x="388" y="54" text-anchor="middle">award</text>85 <path class="d-msg d-flow" d="M438,66 C395,80 380,84 340,92"/>86 <text class="d-label" x="392" y="90" text-anchor="middle">10008</text>87 <path class="d-msg blue d-flow" d="M337,118 C380,130 395,150 438,164"/>88 <text class="d-label" x="380" y="152" text-anchor="middle">badges</text>89 <circle r="4" fill="#f26a00">90 <animateMotion dur="2.6s" repeatCount="indefinite" path="M122,105 L222,105"/>91 </circle>92 <circle r="4" fill="#2e5f9e">93 <animateMotion dur="2.6s" begin="1.3s" repeatCount="indefinite" path="M337,118 C380,130 395,150 438,164"/>94 </circle>95 </svg>96 </div>97 <figcaption>Fig. 58-1 — <b>Badge lifecycle.</b> The issuer defines and awards. The awardee accepts. Viewers render the accepted badges.</figcaption>98 </figure>99100 <h2 class="bar" id="spec"><span class="num">2</span> Badge Definition (kind 30009)</h2>101 <p>A Badge Definition is an <em>addressable event</em> (<a href="01.html">NIP-01</a>) with kind <code>30009</code>, published by the badge issuer. Its <code>d</code> tag value uniquely identifies the badge, for example <code>bravery</code>. The issuer can update the definition later: relays keep only the latest event per issuer and <code>d</code> value.</p>102 <p>One tag is required. The rest are optional:</p>103104 <div class="tscroll"><table class="ref">105 <caption>Badge Definition tags</caption>106 <tr><th>Tag</th><th>Required</th><th>Rule</th></tr>107 <tr><td class="btn">d</td><td>MUST</td><td>The unique name of the badge. Identifies the badge within the issuer's pubkey.</td></tr>108 <tr><td class="btn">name</td><td>MAY</td><td>A short display name for the badge.</td></tr>109 <tr><td class="btn">image</td><td>MAY</td><td>URL of a high-resolution image for the badge. An optional second value gives the dimensions as <code>&lt;width&gt;x&lt;height&gt;</code> in pixels. Recommended size: 1024x1024.</td></tr>110 <tr><td class="btn">description</td><td>MAY</td><td>Text that may describe the image, the meaning of the badge, or the reason for its issuance.</td></tr>111 <tr><td class="btn">thumb</td><td>MAY, repeatable</td><td>URL of a thumbnail version of the <code>image</code>. An optional second value gives the dimensions as <code>&lt;width&gt;x&lt;height&gt;</code> in pixels. One tag per thumbnail size.</td></tr>112 </table></div>113114 <div class="crt">115 <div class="titlebar">Badge Definition - kind 30009</div>116<pre>{117 <span class="k">"pubkey"</span>: <span class="c">&lt;issuer pubkey, "alice"&gt;</span>,118 <span class="k">"kind"</span>: 30009,119 <span class="k">"tags"</span>: [120 [<span class="s">"d"</span>, <span class="s">"bravery"</span>],121 [<span class="s">"name"</span>, <span class="s">"Medal of Bravery"</span>],122 [<span class="s">"description"</span>, <span class="s">"Awarded to users demonstrating bravery"</span>],123 [<span class="s">"image"</span>, <span class="s">"https://nostr.academy/awards/bravery.png"</span>, <span class="s">"1024x1024"</span>],124 [<span class="s">"thumb"</span>, <span class="s">"https://nostr.academy/awards/bravery_256x256.png"</span>, <span class="s">"256x256"</span>]125 ]126 <span class="c">// other fields...</span>127}</pre>128 </div>129130 <h2 class="bar"><span class="num">3</span> Badge Award (kind 8)</h2>131 <p>A Badge Award is a regular event with kind <code>8</code>, published by the issuer. It hands the badge to one or more pubkeys. Awarded badges are immutable and non-transferable.</p>132 <div class="tscroll"><table class="ref">133 <caption>Badge Award tags</caption>134 <tr><th>Tag</th><th>Required</th><th>Rule</th></tr>135 <tr><td class="btn">a</td><td>MUST, single</td><td>References the kind <code>30009</code> Badge Definition, as <code>30009:&lt;issuer pubkey&gt;:&lt;d value&gt;</code>. Exactly one per award.</td></tr>136 <tr><td class="btn">p</td><td>MUST, one or more</td><td>One tag for each pubkey the issuer wishes to award.</td></tr>137 </table></div>138139 <div class="crt">140 <div class="titlebar">Badge Award - kind 8</div>141<pre>{142 <span class="k">"id"</span>: <span class="c">&lt;badge award event id&gt;</span>,143 <span class="k">"kind"</span>: 8,144 <span class="k">"pubkey"</span>: <span class="c">&lt;issuer pubkey, "alice"&gt;</span>,145 <span class="k">"tags"</span>: [146 [<span class="s">"a"</span>, <span class="s">"30009:alice:bravery"</span>],147 [<span class="s">"p"</span>, <span class="s">"bob"</span>, <span class="s">"wss://relay"</span>],148 [<span class="s">"p"</span>, <span class="s">"charlie"</span>, <span class="s">"wss://relay"</span>]149 ]150 <span class="c">// other fields...</span>151}</pre>152 </div>153154 <h2 class="bar"><span class="num">4</span> Profile Badges (kind 10008)</h2>155 <p>The number of badges a pubkey can be awarded is unbounded. The Profile Badges event lets a user accept or reject awarded badges. It also sets the display order of badges on the profile.</p>156 <p>A Profile Badges event is a <em>replaceable event</em> with kind <code>10008</code>, defined as a <a href="51.html">NIP-51</a> standard list. All tags are optional:</p>157 <ul>158 <li>Zero or more ordered, consecutive pairs of <code>a</code> and <code>e</code> tags. Each pair references a kind <code>30009</code> Badge Definition and a kind <code>8</code> Badge Award, in that order.</li>159 <li>Clients SHOULD ignore an <code>a</code> tag without a matching <code>e</code> tag, and an <code>e</code> tag without a matching <code>a</code> tag.</li>160 <li>The Badge Award referenced by each <code>e</code> tag should contain the same <code>a</code> tag as its pair.</li>161 <li>The event may also contain <code>a</code> tags that reference Badge Set events (see §5).</li>162 </ul>163164 <figure class="diagram">165 <div class="frame">166 <svg viewBox="0 0 560 200" role="img" aria-label="Profile badges tags form ordered pairs: each a tag names a definition and the next e tag names its award; an unpaired tag is ignored">167 <text class="d-actor-label" x="10" y="20">"tags" in kind 10008</text>168 <rect class="d-actor" x="10" y="34" width="330" height="26" rx="4"/>169 <text class="d-label" x="20" y="51">["a", "30009:alice:bravery"]</text>170 <rect class="d-actor" x="10" y="66" width="330" height="26" rx="4"/>171 <text class="d-label" x="20" y="83">["e", &lt;bravery award id&gt;, "wss://…"]</text>172 <rect class="d-actor" x="10" y="102" width="330" height="26" rx="4"/>173 <text class="d-label" x="20" y="119">["a", "30009:alice:honor"]</text>174 <rect class="d-actor" x="10" y="134" width="330" height="26" rx="4"/>175 <text class="d-label" x="20" y="151">["e", &lt;honor award id&gt;, "wss://…"]</text>176 <rect x="10" y="170" width="330" height="26" rx="4" fill="none" stroke="#7d8794" stroke-dasharray="4 3"/>177 <text class="d-label" x="20" y="187">["a", "30009:carol:grit"] no "e" tag</text>178 <path class="d-msg" d="M348,47 C380,50 380,72 350,79"/>179 <text class="d-note" x="392" y="66">pair 1 - shown first</text>180 <path class="d-msg" d="M348,115 C380,118 380,140 350,147"/>181 <text class="d-note" x="392" y="134">pair 2 - shown second</text>182 <text class="d-note" x="392" y="187">unpaired: ignored</text>183 </svg>184 </div>185 <figcaption>Fig. 58-2 — <b>Ordered pairs.</b> Each <code>a</code> + <code>e</code> pair is one accepted badge. Tags without a partner do not count.</figcaption>186 </figure>187188 <div class="box warn">189 <span class="tag">Warning!</span>190 <p>An earlier version of this NIP used an addressable kind <code>30008</code> event with the <code>d</code> tag value <code>profile_badges</code> for the Profile Badges event. Clients should treat these old events as equivalent to kind <code>10008</code> and migrate to the new format.</p>191 </div>192193 <h2 class="bar"><span class="num">5</span> Badge Sets (kind 30008)</h2>194 <p>A Badge Set is an <em>addressable event</em> with kind <code>30008</code>, defined as a <a href="51.html">NIP-51</a> set. Badge Sets let a user categorize accepted badges into labeled groups. Like the Profile Badges event, a Badge Set contains ordered pairs of <code>a</code> and <code>e</code> tags. Each pair references a Badge Definition and a Badge Award for one badge in the set. A Profile Badges event may reference Badge Sets with <code>a</code> tags.</p>195196 <div class="box tech">197 <span class="tag">Tech Note</span>198 <p>Kind <code>30008</code> now carries two meanings. New events are Badge Sets. Old events with <code>d</code> = <code>profile_badges</code> are legacy Profile Badges. A client must inspect the <code>d</code> tag to tell them apart. The spec also gives no label mechanism or example for Badge Sets beyond the <a href="51.html">NIP-51</a> set conventions, and it does not say how a Profile Badges <code>a</code> reference to a set interleaves with its own <code>a</code>/<code>e</code> pairs. Implementations differ here.</p>199 </div>200201 <div class="tscroll"><table class="ref">202 <caption>Kind summary</caption>203 <tr><th>Kind</th><th>Event</th><th>Storage class</th><th>Author</th></tr>204 <tr><td class="btn">30009</td><td>Badge Definition</td><td>addressable, by <code>d</code></td><td>issuer</td></tr>205 <tr><td class="btn">8</td><td>Badge Award</td><td>regular, immutable</td><td>issuer</td></tr>206 <tr><td class="btn">10008</td><td>Profile Badges</td><td>replaceable</td><td>awardee</td></tr>207 <tr><td class="btn">30008</td><td>Badge Set</td><td>addressable, by <code>d</code></td><td>awardee</td></tr>208 </table></div>209210 <h2 class="bar"><span class="num">6</span> Recommendations</h2>211 <p>Clients MAY whitelist badge issuer pubkeys. This keeps badges valuable and special for their users.</p>212 <p>The recommended badge image aspect ratio is 1:1, with a high-resolution size of 1024x1024 pixels. Recommended thumbnail dimensions are:</p>213 <div class="tscroll"><table class="ref">214 <caption>Thumbnail sizes</caption>215 <tr><th>Label</th><th>Dimensions</th></tr>216 <tr><td class="btn">xl</td><td>512x512</td></tr>217 <tr><td class="btn">l</td><td>256x256</td></tr>218 <tr><td class="btn">m</td><td>64x64</td></tr>219 <tr><td class="btn">s</td><td>32x32</td></tr>220 <tr><td class="btn">xs</td><td>16x16</td></tr>221 </table></div>222 <p>Rendering rules for clients:</p>223 <ul>224 <li>Clients MAY render fewer badges than the user lists in the Profile Badges event.</li>225 <li>Clients MAY replace the badge image and thumbnails with ones that fit the client's theme.</li>226 <li>Clients SHOULD pick the most appropriate thumbnail for the number of badges shown and the space available.</li>227 <li>Clients SHOULD render the high-resolution image on user action: click, tap, or hover.</li>228 </ul>229230 <h2 class="bar" id="examples"><span class="num">7</span> Worked Example</h2>231 <p>Alice issues the <code>bravery</code> badge and awards it to Bob and Charlie. Bob accepts it, next to an earlier <code>honor</code> badge, and files both into a set. Orange lines go to the relay. Blue lines come from the relay.</p>232 <div class="crt">233 <div class="titlebar">Session transcript - wss://nostr.academy</div>234<pre><span class="c">-- Alice (issuer) publishes the definition, then the award --</span>235<span class="send">→ ["EVENT", {"kind":30009,"pubkey":"a11ce…","tags":[["d","bravery"],236 ["name","Medal of Bravery"],["description","Awarded to users demonstrating bravery"],237 ["image","https://nostr.academy/awards/bravery.png","1024x1024"],238 ["thumb","https://nostr.academy/awards/bravery_256x256.png","256x256"]], …}]</span>239<span class="recv">← ["OK", "c0ffee11…", true, ""]</span>240<span class="send">→ ["EVENT", {"kind":8,"pubkey":"a11ce…","tags":[["a","30009:a11ce…:bravery"],241 ["p","b0b…","wss://relay"],["p","c4a121e…","wss://relay"]], …}]</span>242<span class="recv">← ["OK", "aa4a5d01…", true, ""]</span>243244<span class="c">-- Bob's client looks for awards to Bob --</span>245<span class="send">→ ["REQ", "hon", {"kinds":[8], "#p":["b0b…"]}]</span>246<span class="recv">← ["EVENT", "hon", {"kind":8, "id":"aa4a5d01…", "tags":[["a","30009:a11ce…:bravery"], …], …}]</span>247<span class="recv">← ["EOSE", "hon"]</span>248249<span class="c">-- Bob accepts: Profile Badges, ordered a/e pairs --</span>250<span class="send">→ ["EVENT", {"kind":10008,"pubkey":"b0b…","tags":[251 ["a","30009:a11ce…:bravery"],["e","aa4a5d01…","wss://nostr.academy"],252 ["a","30009:a11ce…:honor"],["e","77e1de40…","wss://nostr.academy"]], …}]</span>253<span class="recv">← ["OK", "b1adge55…", true, ""]</span>254255<span class="c">-- Bob also groups them into a Badge Set --</span>256<span class="send">→ ["EVENT", {"kind":30008,"pubkey":"b0b…","tags":[["d","virtues"],257 ["a","30009:a11ce…:bravery"],["e","aa4a5d01…","wss://nostr.academy"],258 ["a","30009:a11ce…:honor"],["e","77e1de40…","wss://nostr.academy"]], …}]</span>259<span class="recv">← ["OK", "5e7c0de1…", true, ""]</span></pre>260 </div>261 <p>A viewer's client now fetches Bob's kind <code>10008</code> event, resolves each <code>a</code>/<code>e</code> pair, checks that the award's <code>a</code> tag matches, and renders the <code>thumb</code> that fits the layout.</p>262263 <h2 class="bar" id="history"><span class="num">8</span> Version History</h2>264 <p>NIP-58 arrived in early 2023 and kept its shape for three years. The one big change moved Profile Badges to a new kind. Notable changes, newest first:</p>265 <ul class="patchnotes">266 <li><span class="ver">2026</span><span class="when">2026-04</span>Profile Badges moved from kind <code>30008</code> (<code>d</code> = <code>profile_badges</code>) to replaceable kind <code>10008</code>. Kind <code>30008</code> was redefined as the Badge Set event for categorizing badges.</li>267 <li><span class="ver">2024</span><span class="when">2024-08</span>Terminology updated: "parameterized replaceable event" became "addressable event", following the <a href="01.html">NIP-01</a> rename.</li>268 <li><span class="ver">2023</span><span class="when">2023-12</span>Removed the section on proof-of-work (<a href="13.html">NIP-13</a>) as an anti-spam signal for badges.</li>269 <li><span class="ver">2023</span><span class="when">2023-11</span>Author lists removed from all NIPs, this one included.</li>270 <li class="minor"><span class="ver">2023+</span><span class="when">2023-2026</span>Typo fixes, JSON formatting, and example cleanups.</li>271 <li><span class="ver">Origin</span><span class="when">2023-02</span>Ricardo Arturo Cabral Mejía added the badge events and profile badges spec in PR #229.</li>272 </ul>273274 <div class="credits">275 <h3 class="cardhead">Original Proposal - Credits</h3>276 <table>277 <tr><td>Author</td><td>Ricardo Arturo Cabral Mejía</td></tr>278 <tr><td>First commit</td><td>2023-02-22 — “docs: add nip-58 badge event and profile badges” (<a href="https://github.com/nostr-protocol/nips/pull/229">PR #229</a>)</td></tr>279 <tr><td>Status</td><td>draft - optional — clients choose whether to support badges</td></tr>280 <tr><td>Source</td><td><a href="https://github.com/nostr-protocol/nips/blob/master/58.md">58.md on GitHub</a> - <a href="https://github.com/nostr-protocol/nips/commits/master/58.md">full change history</a></td></tr>281 </table>282 </div>283284 <h2 class="bar"><span class="num">9</span> See Also</h2>285 <ul>286 <li><a href="01.html">NIP-01</a> — the base protocol: events, tags, replaceable and addressable storage classes.</li>287 <li><a href="51.html">NIP-51</a> — lists and sets; Profile Badges is a standard list, Badge Set is a set.</li>288 <li><a href="13.html">NIP-13</a> — proof of work; an earlier draft suggested it as a badge anti-spam signal.</li>289 <li><a href="19.html">NIP-19</a> — bech32 encodings for sharing badge event pointers.</li>290 <li><a href="25.html">NIP-25</a> — reactions; a lighter-weight way to show appreciation than a badge.</li>291 </ul>292 </div>293294 <aside>295 <div class="cartridge">296 <div class="inner">297 <h3 class="cardhead">Spec Card</h3>298 <div class="lights"><span class="led on"></span><span class="led on"></span><span class="led on"></span></div>299 <dl>300 <dt>Status</dt><dd><span class="chip draft">draft</span><span class="chip optional">optional</span></dd>301 <dt>Defines</dt><dd>Badge Definition - Badge Award - Profile Badges - Badge Set</dd>302 <dt>Kinds</dt><dd>30009 - 8 - 10008 - 30008</dd>303 <dt>Tags</dt><dd>d - name - image - description - thumb - a - e - p</dd>304 <dt>Requires</dt><dd><a href="01.html">NIP-01</a> - <a href="51.html">NIP-51</a></dd>305 <dt>First commit</dt><dd>2023-02-22</dd>306 <dt>Last updated</dt><dd>2026-06-13</dd>307 </dl>308 </div>309 </div>310 </aside>311 </main>312313 <nav class="navbtns">314 <a href="57.html">◀ NIP-57: Lightning Zaps</a>315 <a href="59.html">NIP-59: Gift Wrap ▶</a>316 </nav>317318 <footer class="pagefoot">319 <a href="../index.html">Nostr Protocol Manual</a>320 <span class="pageno">NIP 58 / F4</span>321 </footer>322</div>323324<script src="../assets/webmcp.js" defer></script>325</body>326</html>