package nostr import ( "encoding/json" "net" "net/http" "strings" "git.devvul.com/asara/gologger" "git.devvul.com/asara/well-goknown/config" ) func GetNostrAddr(w http.ResponseWriter, r *http.Request) { l := gologger.Get(config.GetConfig().LogLevel).With().Caller().Logger() // get query string for username r.ParseForm() name := strings.ToLower(r.FormValue("name")) if name == "_" { name = "" } // normalize domain domain, _, err := net.SplitHostPort(r.Host) if err != nil { domain = r.Host } // get owner id for nip05 request var uid int err = DB.QueryRow("SELECT owner_id FROM nip05s WHERE name=$1 AND domain=$2", name, domain).Scan(&uid) if err != nil { l.Debug().Msgf("user (%s@%s) doesn't exist: %s", name, domain, err.Error()) http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } // get the pubkey and relays associated with the nip05 user := nostrUser{} err = DB.QueryRow("SELECT pubkey, relays FROM users WHERE id=$1", uid).Scan(&user.Pubkey, &user.Relays) if err != nil { l.Debug().Msgf("unable to get user info for uid %v: %s", uid, err.Error()) http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } // get all names associated with the pubkey names := []string{} err = DB.Select(&names, "SELECT nip05s.name FROM nip05s JOIN users ON nip05s.owner_id = users.id WHERE nip05s.owner_id = $1", uid) if err != nil { l.Debug().Msgf("unable to get nip05 names for uid %v: %s", uid, err.Error()) http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } // map of names n := make(map[string]string) for _, name := range names { if name == "" { n["_"] = user.Pubkey } else { n[name] = user.Pubkey } } // map of relays s := make(map[string][]string) if user.Relays != nil { if strings.Contains(*user.Relays, ",") { s[user.Pubkey] = strings.Split(*user.Relays, ",") } else { s[user.Pubkey] = []string{*user.Relays} } } // map of nip46 t := make(map[string][]string) t[user.Pubkey] = []string{"wss://relay.devvul.com"} ret := nostrWellKnown{ Names: n, Relays: s, NIP46: t, } j, err := json.Marshal(ret) if err != nil { l.Error().Msgf("unable to marshal nip05 response: %s", err.Error()) http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } l.Debug().Msgf("returning nip05 for %s@%s: %s", name, domain, user.Pubkey) w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) w.Write(j) return }