@@ -323,9 +323,9 @@ func (m dmModel) handleDMKey(msg tea.KeyMsg) (tea.Model, tea.Cmd) {
323323
324324 var cmds []tea.Cmd
325325
326- // Send typing indicator on keystroke (throttled)
326+ // Send typing indicator on keystroke (throttled every 5s )
327327 if msg .Type == tea .KeyRunes || msg .Type == tea .KeySpace {
328- if time .Since (m .lastTypingSent ) > 3 * time .Second {
328+ if time .Since (m .lastTypingSent ) > 5 * time .Second {
329329 m .lastTypingSent = time .Now ()
330330 cmds = append (cmds , m .sendTypingCmd ())
331331 }
@@ -469,16 +469,18 @@ func (m dmModel) sendTypingCmd() tea.Cmd {
469469 }
470470}
471471
472- // publishTypingIndicator sends a typing indicator event.
473- // In NIP-04 mode it publishes a plain ephemeral kind 10003.
474- // In NIP-17 mode it gift-wraps the kind 10003 rumor so the relay
472+ // publishTypingIndicator sends an ephemeral typing indicator event (kind 20003).
473+ // Kind 20003 is in the ephemeral range (20000-29999) per NIP-01, so relays
474+ // MUST NOT store it — they only forward it to connected subscribers.
475+ // In NIP-04 mode it publishes a plain ephemeral event.
476+ // In NIP-17 mode it gift-wraps the kind 20003 rumor so the relay
475477// only sees random pubkey + recipient — no sender leak.
476478func publishTypingIndicator (skHex , myHex , targetHex string , relays []string , useNip04 bool ) {
477479 ctx := context .Background ()
478480
479481 if useNip04 {
480482 event := nostr.Event {
481- Kind : 10003 ,
483+ Kind : 20003 ,
482484 Content : "" ,
483485 Tags : nostr.Tags {{"p" , targetHex }},
484486 CreatedAt : nostr .Now (),
@@ -491,7 +493,7 @@ func publishTypingIndicator(skHex, myHex, targetHex string, relays []string, use
491493
492494 // NIP-17: gift-wrap the typing indicator
493495 rumor := nostr.Event {
494- Kind : 10003 ,
496+ Kind : 20003 ,
495497 Content : "" ,
496498 Tags : nostr.Tags {{"p" , targetHex }},
497499 CreatedAt : nostr .Now (),
@@ -767,7 +769,7 @@ func interactiveDMBubbleTea(npub, skHex, myHex, targetHex, inputName string, rel
767769 continue
768770 }
769771 // Skip typing indicators from history
770- if rumor .Kind == 10003 {
772+ if rumor .Kind == 20003 {
771773 continue
772774 }
773775 if rumor .Kind != 14 {
@@ -877,9 +879,9 @@ func interactiveDMBubbleTea(npub, skHex, myHex, targetHex, inputName string, rel
877879 }()
878880 }
879881
880- // Typing indicators from target (ephemeral kind 10003 )
882+ // Typing indicators from target (ephemeral kind 20003 )
881883 typingSub , err := relay .Subscribe (ctx , nostr.Filters {{
882- Kinds : []int {10003 },
884+ Kinds : []int {20003 },
883885 Authors : []string {targetHex },
884886 Tags : nostr.TagMap {"p" : []string {myHex }},
885887 Since : & since ,
@@ -925,7 +927,7 @@ func interactiveDMBubbleTea(npub, skHex, myHex, targetHex, inputName string, rel
925927 continue
926928 }
927929 // Gift-wrapped typing indicator
928- if rumor .Kind == 10003 && rumor .PubKey == targetHex {
930+ if rumor .Kind == 20003 && rumor .PubKey == targetHex {
929931 p .Send (typingMsg {})
930932 continue
931933 }
0 commit comments