{"id":"223c11b4895e61d9ad09f67d7c39ca307980a498586005a7f1c89f11e67efce8","pubkey":"a8d1560d6a647d501699167246f237b36fb123f89168fda11dc743533fec7a08","created_at":1783522186,"kind":30817,"tags":[["d","nip-fsf-free-speech-flags"],["title","NIP-FSF: Free Speech Flags"],["k","32239"],["client","nostrhub.io"]],"content":"`draft` `optional`\n\n## Kind 32239 — Free Speech Flag\n\nAn **addressable event** that encodes a \"Free Speech Flag\" — a visual flag whose vertical stripes are determined by the RGB values of a byte sequence.\n\n### Event Structure\n\n```json\n{\n  \"kind\": 32239,\n  \"content\": \"<human-readable title or description>\",\n  \"tags\": [\n    [\"d\", \"<unique identifier, e.g. nanoid or hash>\"],\n    [\"title\", \"<flag title>\"],\n    [\"data\", \"<hex-encoded byte sequence>\"],\n    [\"encoding\", \"text\" | \"hex\"],\n    [\"source\", \"<original text if encoding=text, else same as data>\"],\n    [\"blossom\", \"<blossom URL of SVG file (optional)>\"],\n    [\"alt\", \"Free Speech Flag: <title>\"]\n  ]\n}\n```\n\n### Field Descriptions\n\n| Tag | Required | Description |\n|-----|----------|-------------|\n| `d` | yes | Unique identifier for this flag (nanoid or SHA-256 of data) |\n| `title` | yes | Human-readable name for the flag |\n| `data` | yes | Lowercase hex-encoded byte sequence that defines the flag's colors |\n| `encoding` | yes | `\"text\"` if source was UTF-8 text, `\"hex\"` if entered as raw hex |\n| `source` | no | Original text input (only when `encoding=text`). Omitted if sensitive. |\n| `blossom` | no | URL to Blossom-hosted SVG of the rendered flag |\n| `alt` | yes | NIP-31 human-readable alternative (required for all custom kinds) |\n\n### Flag Rendering Algorithm\n\n1. Decode `data` tag value as hex bytes.\n2. Group bytes in chunks of 3. Each chunk → one vertical stripe with `rgb(b[0], b[1], b[2])`.\n3. If `bytes.length % 3 !== 0`, the remaining 1 or 2 bytes are shown as a hex string (e.g. `+C0` or `+B2 C2`) in the **bottom-right corner** of the last stripe, in white or black text depending on contrast.\n4. All stripes have equal width. The flag aspect ratio is 8:5 (standard flag ratio).\n\n### Example\n\nEncoding `09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0` (the HD DVD processing key):\n- 5 full stripes (15 bytes → 5 × RGB)\n- Remaining byte: `C0`\n- Bottom-right shows `+C0`\n\n### Querying\n\n```js\n// All flags\nnostr.query([{ kinds: [32239], limit: 50 }])\n\n// Flags by a specific author\nnostr.query([{ kinds: [32239], authors: [pubkey], limit: 50 }])\n```\n\n### Deletion\n\nAuthors may delete their flag by publishing a NIP-09 deletion event (kind 5) referencing the flag's event ID or the `a` tag coordinate (`32239:<pubkey>:<d-tag>`).\n\n### Notes on Ephemeral Publishing\n\nClients may publish flags using ephemeral (one-time) keypairs. Each new flag can use a fresh keypair for privacy. The keypair should be stored locally so the author can later delete or edit the flag.","sig":"b1e6ece9b354d7ea81d0d32e715947d12eea43a0c710e120e4c9cd14427fc5adc254d86e9f7d1cf876b2175ed9a933cb0831ef5c93a7b75ece557656dede4f84"}