Skip to content

Commit c94b9da

Browse files
committed
fix: use ephemeral kind 20003 for typing indicators, throttle to 5s
- Kind 10003 → 20003 (ephemeral range 20000-29999 per NIP-01) - Relays MUST NOT store ephemeral events, only forward to subscribers - Sending throttle: every 5s while typing (was 3s) - Receiving: show 'is typing...' for 5s, reset on new event - Both NIP-04 (plain) and NIP-17 (gift-wrapped) paths updated
1 parent 6578753 commit c94b9da

1 file changed

Lines changed: 13 additions & 11 deletions

File tree

cmd/dm_ui.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
476478
func 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

Comments
 (0)