nostr-addressable-event-d-tag-requirement

Par divinevideo · divine-mobile

Corrige les événements Nostr dupliqués (événements remplaçables paramétrés Kind 30000+) causés par un d-tag manquant. À utiliser lorsque : (1) le même contenu apparaît plusieurs fois sur un relay pour le même pubkey, (2) les événements ne sont pas remplacés/mis à jour comme prévu, (3) la publication d'événements vidéo NIP-71 (Kind 34236) ou d'autres événements adressables génère des doublons. Le d-tag est OBLIGATOIRE pour l'adressabilité — sans lui, chaque publication crée un nouvel événement non remplaçable.

npx skills add https://github.com/divinevideo/divine-mobile --skill nostr-addressable-event-d-tag-requirement

Exigence du d-tag pour les événements adressables Nostr

Problème

Lors de la publication d'événements remplaçables paramétrés (Kind 30000-39999, y compris les événements vidéo NIP-71 Kind 34236), les événements apparaissent comme des doublons sur le relay au lieu de se remplacer les uns les autres. Le même contenu s'affiche plusieurs fois pour le même utilisateur.

Contexte / Conditions de déclenchement

  • Publication d'événements Kind 30000+ (événements remplaçables paramétrés)
  • La même vidéo/contenu apparaît plusieurs fois dans le fil de l'utilisateur
  • Les événements ont les mêmes pubkey, kind et contenu mais des ID d'événement différents
  • Le relay retourne plusieurs événements alors qu'on en attend un
  • Utilisation de NIP-71 (Kind 34236) pour les événements vidéo
  • Utilisation de NIP-23 (Kind 30023) pour le contenu long format
  • Tout type d'événement adressable affichant des doublons

Solution

Cause racine

Les événements remplaçables paramétrés (Kind 30000-39999) nécessitent un tag d pour être adressables. La combinaison pubkey + kind + valeur du d-tag forme l'adresse unique. Sans tag d, le relay traite chaque événement comme un événement distinct non remplaçable.

Correctif

Toujours inclure un tag d avec un identifiant unique pour le contenu :

// CORRECT - a un d tag, sera remplaçable
const event = {
  kind: 34236, // NIP-71 video
  pubkey: userPubkey,
  content: "Video description",
  tags: [
    ["d", videoId],  // REQUIS pour l'adressabilité
    ["title", "My Video"],
    ["url", "https://..."],
    // ... autres tags
  ]
};

// INCORRECT - d tag manquant, crée un nouvel événement à chaque fois
const badEvent = {
  kind: 34236,
  pubkey: userPubkey,
  content: "Video description",
  tags: [
    ["title", "My Video"],  // Pas de d tag!
    ["url", "https://..."],
  ]
};

Pour les événements vidéo NIP-71

Utiliser l'identifiant unique de la vidéo (vine_id, video_id, etc.) comme valeur du d-tag :

tags.push(["d", video.id]);

Nettoyage des doublons existants

  1. Récupérer tous les événements pour la pubkey : { kinds: [34236], authors: [pubkey] }
  2. Identifier les événements sans d-tags (ce sont les doublons)
  3. Publier des événements de suppression NIP-09 (Kind 5) référençant les mauvais ID d'événement
  4. Republier avec les d-tags corrects

Vérification

Après ajout du d-tag :

  1. Publier le même contenu deux fois
  2. Interroger le relay pour les événements avec cette pubkey+kind
  3. Devrait retourner UN SEUL événement (le plus récent)
  4. L'ID d'événement changera mais l'adresse du d-tag reste constante
// Vérifier l'absence de doublons
const events = await ndk.fetchEvents({ kinds: [34236], authors: [pubkey] });
const byDTag = new Map();
for (const e of events) {
  const d = e.tags.find(t => t[0] === 'd')?.[1];
  if (!byDTag.has(d)) byDTag.set(d, []);
  byDTag.get(d).push(e);
}
// Chaque valeur de d-tag devrait avoir exactement 1 événement
for (const [d, evts] of byDTag) {
  if (evts.length > 1) console.log(`Duplicate: d=${d} has ${evts.length} events`);
}

Exemple

Avant le correctif - les événements sans d-tag créent des doublons :

Event 1: id=abc123, kind=34236, tags=[["title", "My Video"]]
Event 2: id=def456, kind=34236, tags=[["title", "My Video"]]  // Doublon!

Après le correctif - les événements avec d-tag se remplacent les uns les autres :

Event 1: id=abc123, kind=34236, tags=[["d", "video-001"], ["title", "My Video"]]
// Republication du même contenu...
Event 2: id=xyz789, kind=34236, tags=[["d", "video-001"], ["title", "My Video Updated"]]
// Event 1 est remplacé, seul Event 2 existe

Notes

  • La valeur du d-tag devrait être stable entre les republications (utiliser l'ID du contenu, pas une valeur aléatoire)
  • Une chaîne vide ["d", ""] est valide mais signifie un seul événement de ce kind par pubkey
  • Les événements remplaçables réguliers (Kind 0, 3, 10000-19999) ne nécessitent pas de d-tag
  • Ceci s'applique à TOUS les événements remplaçables paramétrés, pas seulement les vidéos
  • La mise en cache frontend peut afficher les anciens doublons même après nettoyage du relay - actualisation complète nécessaire

Références

Skills similaires