# Addressable Events Feature for event.html

## Overview

Add an "Addressable Kinds" button to `www/event.html` that fetches addressable events (kinds 30023, 30024, 30078) from all relays, groups them by kind:d-tag pair, and lets the user browse, inspect, and republish them.

## Problem

The current event.html handles kinds 0, 3, and 10002 (replaceable events). Addressable events (kinds 30000-39999) are different — they're keyed by the combination of `kind + pubkey + d-tag`. A user may have many addressable events with different d-tag values, and each relay may have different versions. There's no easy way to audit which relays have the latest version of each addressable event.

## Solution

Add a new button + dropdown workflow:
1. Click "Addressable Kinds" to fetch kinds 30023, 30024, 30078 from all relays
2. Group results by `kind:d-tag` pair
3. Populate a dropdown with all discovered pairs
4. Selecting a pair shows the relay status table and event JSON using the existing UI
5. User can Repost or Resign & Post to update outdated relays

## Architecture

```mermaid
flowchart TD
    A[User clicks Addressable Kinds button] --> B[Fetch kinds 30023 + 30024 + 30078 from all relays]
    B --> C[Collect all events from all relays]
    C --> D[Group by kind:d-tag pair]
    D --> E[For each group find latest event by created_at]
    E --> F[Populate dropdown with kind:d-tag pairs]
    F --> G[User selects item from dropdown]
    G --> H[Filter eventsByRelay to only matching kind:d events]
    H --> I[Display in existing relay table and txtEventJson]
    I --> J{User action}
    J -->|Repost| K[Publish signed event as-is]
    J -->|Resign and Post| L[New timestamp + re-sign + publish]
    L --> M[d-tag preserved via tags array copy]
```

## Target Kinds (Initial)

| Kind  | Label              | NIP   |
|-------|--------------------|-------|
| 30023 | Long-form Article  | NIP-23 |
| 30024 | Draft Article      | NIP-23 |
| 30078 | App-specific Data  | NIP-78 |

These are defined in a configurable array at the top of the script for easy expansion later.

## Dropdown Display Format

Each option: `Kind XXXXX - Label: d-tag-value`

Examples:
- `Kind 30078 - App-specific Data: my-app-settings`
- `Kind 30023 - Long-form Article: my-blog-post-slug`
- `Kind 30024 - Draft Article: draft-in-progress`

Long d-tag values are truncated with ellipsis.

## Implementation Details

### File Changed

Only `www/event.html` — the page is self-contained with inline styles and scripts.

### HTML Changes (around line 257-261)

Add after existing kind buttons:

```html
<button id="btnAddressable" class="btnKind">Addressable Kinds</button>
```

Add new dropdown container between kind buttons and event list table:

```html
<div id="divAddressableSelector" style="display: none;">
  <select id="selAddressable">
    <option value="">-- Select an addressable event --</option>
  </select>
</div>
```

### CSS Changes

```css
#divAddressableSelector {
  margin: 10px 0;
}

#selAddressable {
  width: 100%;
  padding: 10px;
  border: var(--border-width) solid var(--muted-color);
  border-radius: var(--border-radius);
  font-family: var(--font-family);
  font-size: 14px;
  background-color: var(--secondary-color);
  color: var(--primary-color);
  cursor: pointer;
}
```

### JavaScript Changes

#### New Config (top of script section)

```javascript
// Addressable event kinds to fetch
const ADDRESSABLE_KINDS = [30023, 30024, 30078];
const ADDRESSABLE_KIND_LABELS = {
  30023: 'Long-form Article',
  30024: 'Draft Article',
  30078: 'App-specific Data'
};
```

#### New Global Variables

```javascript
let addressableEventGroups = new Map(); // Map<'kind:d-value', { latestEvent, eventsByRelay }>
let currentAddressableKey = null;
```

#### New Function: loadAddressableEvents()

1. Set button active state, clear UI
2. Call `fetchEventsFromAllRelays({ kinds: ADDRESSABLE_KINDS, authors: [currentPubkey] })`
3. Group all returned events by `kind:d-tag` pair
4. For each group, find the latest event (highest `created_at`)
5. Store in `addressableEventGroups`
6. Call `populateAddressableDropdown()`

#### New Function: populateAddressableDropdown()

1. Clear and populate `selAddressable` with options
2. Each option value = `kind:d-value` key
3. Each option text = `Kind XXXXX - Label: d-tag-value` (truncated)
4. Show `divAddressableSelector`

#### New Function: onAddressableSelected()

1. Get selected key from dropdown
2. Look up group from `addressableEventGroups`
3. Set `eventsByRelay` to the group's filtered relay data
4. Call `populateEventListFromFetch()` to show relay table
5. Call `loadEventFromData()` with the latest event to show JSON and relay status

#### Event Handler Wiring

```javascript
document.getElementById('btnAddressable').addEventListener('click', loadAddressableEvents);
document.getElementById('selAddressable').addEventListener('change', onAddressableSelected);
```

### No Changes Needed to Existing Functions

- `loadEventFromData()` — works with any event object
- `populateEventListFromFetch()` — works with any `eventsByRelay` data
- `resignAndPost()` — preserves `tags` array which includes the `d` tag
- `repostEvent()` — publishes event as-is
- `updateValidationStatus()` — validates any event JSON

### Key Detail: d-tag Extraction

To get the d-tag value from an event:
```javascript
const dTag = event.tags.find(t => t[0] === 'd');
const dValue = dTag ? dTag[1] : '';
```

The grouping key is: `${event.kind}:${dValue}`

## Future Expansion

To add more addressable kinds:
1. Add the kind number to `ADDRESSABLE_KINDS` array
2. Add a label to `ADDRESSABLE_KIND_LABELS` map
3. No other changes needed

To fetch ALL addressable kinds (30000-39999), generate the array:
```javascript
const ALL_ADDRESSABLE = Array.from({length: 10000}, (_, i) => 30000 + i);
```
Note: This creates a large filter (~60KB) that some relays may reject. Errors are handled gracefully per-relay.

## Todo List

- [ ] Add "Addressable Kinds" button to divKindButtons in HTML
- [ ] Add dropdown select element for kind:d-tag pairs in HTML
- [ ] Add CSS styles for the new dropdown and addressable UI elements
- [ ] Add new global variables and config constants
- [ ] Implement loadAddressableEvents function
- [ ] Implement grouping logic - group events by kind:d-tag pair
- [ ] Implement populateAddressableDropdown
- [ ] Implement onAddressableSelected - handle dropdown change
- [ ] Wire up button click and dropdown change event handlers
- [ ] Verify Resign & Post preserves d-tag for addressable events
- [ ] Test the full flow
