fix: build proper q-tag with relay hint and author pubkey for replies

When sending replies in NIP-29 and NIP-C7 adapters, now build the full
q-tag format per NIP-C7 spec: ["q", eventId, relayUrl, pubkey]

Previously only the event ID was included, making it harder for clients
to fetch the referenced event. Now:
- NIP-29: includes group relay URL and author pubkey
- NIP-C7: includes seen relay hint and author pubkey

https://claude.ai/code/session_01Jy51Ayk57fzaFuuFFm1j1K
This commit is contained in:
Claude
2026-01-28 19:09:44 +00:00
parent f987ec7705
commit e0725ae97e
2 changed files with 27 additions and 3 deletions

View File

@@ -459,9 +459,18 @@ export class Nip29Adapter extends ChatProtocolAdapter {
},
);
// Add q-tag for replies (NIP-29 specific, not in blueprint yet)
// Add q-tag for replies (per NIP-C7 quote tag format)
// Format: ["q", eventId, relayUrl, pubkey]
if (options?.replyTo) {
draft.tags.push(["q", options.replyTo]);
// Look up the event to get the author's pubkey for the q-tag
const replyEvent = eventStore.getEvent(options.replyTo);
if (replyEvent) {
// Full q-tag with relay hint and author pubkey
draft.tags.push(["q", options.replyTo, relayUrl, replyEvent.pubkey]);
} else {
// Fallback: at minimum include the relay hint since we know it
draft.tags.push(["q", options.replyTo, relayUrl]);
}
}
// Add NIP-92 imeta tags for blob attachments (not yet handled by applesauce)

View File

@@ -20,6 +20,7 @@ import { isNip05, resolveNip05 } from "@/lib/nip05";
import { getDisplayName, getQuotePointer } from "@/lib/nostr-utils";
import { isValidHexPubkey } from "@/lib/nostr-validation";
import { getProfileContent } from "applesauce-core/helpers";
import { getSeenRelays } from "applesauce-core/helpers/relays";
import { EventFactory } from "applesauce-core/event-factory";
import { ReactionBlueprint } from "applesauce-common/blueprints";
@@ -232,8 +233,22 @@ export class NipC7Adapter extends ChatProtocolAdapter {
factory.setSigner(activeSigner);
const tags: string[][] = [["p", partner.pubkey]];
// Add q-tag for replies (per NIP-C7 quote tag format)
// Format: ["q", eventId, relayUrl, pubkey]
if (options?.replyTo) {
tags.push(["q", options.replyTo]); // NIP-C7 quote tag for threading
const replyEvent = eventStore.getEvent(options.replyTo);
if (replyEvent) {
// Get a relay hint from where we've seen this event
const seenRelays = getSeenRelays(replyEvent);
const relayHint =
seenRelays && seenRelays.size > 0 ? [...seenRelays][0] : "";
// Full q-tag with relay hint and author pubkey
tags.push(["q", options.replyTo, relayHint, replyEvent.pubkey]);
} else {
// Fallback: just the event ID
tags.push(["q", options.replyTo]);
}
}
// Add NIP-30 emoji tags