From 0c604b26b1ca508ce2f9b5641e446e26ff45f1e7 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Mon, 20 Oct 2025 07:46:10 -0300 Subject: [PATCH 01/12] render_image skips the queue. --- enhanced_event.go | 9 +-------- nostr.go | 11 +++++++++++ queue.go => queue-middleware.go | 0 recovery_middleware.go => recovery.go | 0 render_image.go | 10 ++++++---- 5 files changed, 18 insertions(+), 12 deletions(-) rename queue.go => queue-middleware.go (100%) rename recovery_middleware.go => recovery.go (100%) diff --git a/enhanced_event.go b/enhanced_event.go index b24a8ad..db144c1 100644 --- a/enhanced_event.go +++ b/enhanced_event.go @@ -45,14 +45,7 @@ func NewEnhancedEvent( } } - if event.Kind == 0 { - spm, _ := sdk.ParseMetadata(event) - ee.author = spm - } else { - ctx, cancel := context.WithTimeout(ctx, time.Second*3) - defer cancel() - ee.author = sys.FetchProfileMetadata(ctx, event.PubKey) - } + ee.author = getMetadata(ctx, event) return ee } diff --git a/nostr.go b/nostr.go index 71c300c..c7a542e 100644 --- a/nostr.go +++ b/nostr.go @@ -176,6 +176,17 @@ func getEvent(ctx context.Context, code string) (*nostr.Event, error) { return event, err } +func getMetadata(ctx context.Context, event nostr.Event) sdk.ProfileMetadata { + if event.Kind == 0 { + spm, _ := sdk.ParseMetadata(event) + return spm + } else { + ctx, cancel := context.WithTimeout(ctx, time.Second*3) + defer cancel() + return sys.FetchProfileMetadata(ctx, event.PubKey) + } +} + func authorLastNotes(ctx context.Context, pubkey nostr.PubKey) (lastNotes []EnhancedEvent, justFetched bool) { limit := 100 diff --git a/queue.go b/queue-middleware.go similarity index 100% rename from queue.go rename to queue-middleware.go diff --git a/recovery_middleware.go b/recovery.go similarity index 100% rename from recovery_middleware.go rename to recovery.go diff --git a/render_image.go b/render_image.go index 351df4c..6687f61 100644 --- a/render_image.go +++ b/render_image.go @@ -56,20 +56,22 @@ func renderImage(w http.ResponseWriter, r *http.Request) { code = strings.TrimSuffix(code, ext) } - data, err := grabData(ctx, code) + event, _, err := sys.FetchSpecificEventFromInput(ctx, code, sdk.FetchSpecificEventParameters{}) if err != nil { w.Header().Set("Cache-Control", "public, immutable, s-maxage=604800, max-age=604800") log.Warn().Err(err).Str("code", code).Msg("event error on render_image") http.Error(w, "error fetching event: "+err.Error(), http.StatusNotFound) return - } else if data.event.Event == nil { + } else if event == nil { w.Header().Set("Cache-Control", "public, s-maxage=1200, max-age=1200") log.Warn().Err(err).Str("code", code).Msg("event not found on render_image") http.Error(w, "no event found", http.StatusNotFound) return } - content := data.event.Content + author := getMetadata(ctx, *event) + + content := event.Content content = strings.Replace(content, "\r\n", "\n", -1) content = multiNewlineRe.ReplaceAllString(content, "\n\n") content = strings.Replace(content, "\t", " ", -1) @@ -87,7 +89,7 @@ func renderImage(w http.ResponseWriter, r *http.Request) { string(INVISIBLE_SPACE), ) - img, err := drawImage(ctx, paragraphs, getPreviewStyle(r), data.event.author, data.event.CreatedAt.Time()) + img, err := drawImage(ctx, paragraphs, getPreviewStyle(r), author, event.CreatedAt.Time()) if err != nil { log.Warn().Err(err).Msg("failed to draw paragraphs as image") http.Error(w, "error writing image!", 500) From 0c9f56f9acf2ca0acbefeaa4f9b5ddba74ac74f5 Mon Sep 17 00:00:00 2001 From: Mostafa Khaldi <38285605+mostafa-khaldi@users.noreply.github.com> Date: Sun, 26 Oct 2025 11:05:29 +0800 Subject: [PATCH 02/12] Update yakihonneRelay URL format Update yakihonneRelay URL format --- clients.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients.go b/clients.go index 615d049..46bbc22 100644 --- a/clients.go +++ b/clients.go @@ -43,7 +43,7 @@ var ( lumilumiRelay = ClientReference{ID: "lumilumi", Name: "Lumilumi", Base: "https://lumilumi.app/relay/wss%3A%2F%2F{code}", Platform: platformWeb} chachiRelay = ClientReference{ID: "chachi", Name: "chachi", Base: "https://chachi.chat/relay/wss%3A%2F%2F{code}/feed"} yakihonne = ClientReference{ID: "yakihonne", Name: "YakiHonne", Base: "https://yakihonne.com/{code}", Platform: platformWeb} - yakihonneRelay = ClientReference{ID: "yakihonne", Name: "YakiHonne", Base: "https://yakihonne.com/r/?r=wss://{code}", Platform: platformWeb} + yakihonneRelay = ClientReference{ID: "yakihonne", Name: "YakiHonne", Base: "https://yakihonne.com/r/content?r=wss://{code}", Platform: platformWeb} zapStream = ClientReference{ID: "zap.stream", Name: "zap.stream", Base: "https://zap.stream/{code}", Platform: platformWeb} shosho = ClientReference{ID: "shosho", Name: "Shosho", Base: "https://shosho.live/live/{code}", Platform: platformWeb} From acff1d4ce33d533cb617dff76b56e791a305909a Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Sat, 1 Nov 2025 10:55:43 -0300 Subject: [PATCH 03/12] prevent panics when replacing malformed "nostr:" references. --- utils.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/utils.go b/utils.go index 97413e2..65051cb 100644 --- a/utils.go +++ b/utils.go @@ -249,6 +249,11 @@ func replaceNostrURLsWithHTMLTags(matcher *regexp.Regexp, input string) string { func shortenNostrURLs(input string) string { // match and replace npup1, nprofile1, note1, nevent1, etc return nostrEveryMatcher.ReplaceAllStringFunc(input, func(match string) string { + if len(match) < 60 { + // broken, return as is + return match + } + nip19 := match[len("nostr:"):] firstChars := nip19[:8] lastChars := nip19[len(nip19)-4:] @@ -286,6 +291,12 @@ func replaceUserReferencesWithNames(ctx context.Context, input []string, prefix nostrNpubNprofileMatcher.ReplaceAllStringFunc(line, func(match string) string { submatch := nostrNpubNprofileMatcher.FindStringSubmatch(match) nip19code := submatch[1] + + if len(nip19code) < 60 { + // broken, return as is + return match + } + name, ok := getNameFromNip19(ctx, nip19code) if ok { return prefix + strings.ReplaceAll(name, " ", string(THIN_SPACE)) From 61560524b1f68c0c87e82888bdaa02c038154e6b Mon Sep 17 00:00:00 2001 From: Mostafa Khaldi <38285605+mostafa-khaldi@users.noreply.github.com> Date: Sun, 9 Nov 2025 23:36:20 +0800 Subject: [PATCH 04/12] Adding YakiHonne web app to the kind 1,6 list (#135) --- clients.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clients.go b/clients.go index 46bbc22..79858b4 100644 --- a/clients.go +++ b/clients.go @@ -90,7 +90,7 @@ func generateClientList( native, damus, nostur, freeFromIOS, yakihonneIOS, nos, primalIOS, voyage, yakihonneAndroid, primalAndroid, freeFromAndroid, yanaAndroid, - nosotros, jumble, coracle, lumilumi, nostter, nostrudel, phoenix, primalWeb, iris, + nosotros, jumble, coracle, lumilumi, nostter, nostrudel, phoenix, primalWeb, iris, yakihonne, } case 20: clients = []ClientReference{ @@ -105,7 +105,7 @@ func generateClientList( native, nos, damus, nostur, primalIOS, freeFromIOS, yakihonneIOS, voyage, yakihonneAndroid, yanaAndroid, freeFromAndroid, primalAndroid, - nosotros, jumble, nosta, coracle, phoenix, nostter, nostrudel, primalWeb, iris, + nosotros, jumble, nosta, coracle, phoenix, nostter, nostrudel, primalWeb, iris, yakihonne, defaultWeb, } case 30023, 30024: From 21bc2f1ca43b94637b7873eaefbc9604a9e6d532 Mon Sep 17 00:00:00 2001 From: mattn Date: Sun, 23 Nov 2025 02:59:15 +0900 Subject: [PATCH 05/12] export clients.json (#136) --- clients.go | 184 +++++++--------------------- clients.json | 304 ++++++++++++++++++++++++++++++++++++++++++++++ render_event.go | 2 +- render_profile.go | 4 +- 4 files changed, 353 insertions(+), 141 deletions(-) create mode 100644 clients.json diff --git a/clients.go b/clients.go index 79858b4..bc62764 100644 --- a/clients.go +++ b/clients.go @@ -1,6 +1,9 @@ package main import ( + "encoding/json" + "os" + "strconv" "strings" "github.com/a-h/templ" @@ -14,158 +17,63 @@ type ClientReference struct { Platform string } -const ( - platformWeb = "web" - platformIOS = "ios" - platformAndroid = "android" -) - -var ( - native = ClientReference{ID: "native", Name: "Your default app", Base: "nostr:{code}", Platform: "native"} - defaultWeb = ClientReference{ID: "default-web", Name: "Your default web app", Base: "web+nostr:{code}", Platform: "web"} - - nosotros = ClientReference{ID: "nosotros", Name: "Nosotros", Base: "https://dev.nosotros.app/{code}", Platform: platformWeb} - nosotrosRelay = ClientReference{ID: "nosotros", Name: "Nosotros", Base: "https://dev.nosotros.app/feed?kind=%5B1%2C6%5D&limit=100&type=relayfeed&relay=wss%3A%2F%2F{code}", Platform: platformWeb} - nosta = ClientReference{ID: "nosta", Name: "Nosta", Base: "https://nosta.me/{code}", Platform: platformWeb} - phoenix = ClientReference{ID: "phoenix", Name: "Phoenix", Base: "https://phoenix.social/{code}", Platform: platformWeb} - olasWeb = ClientReference{ID: "olas", Name: "Olas", Base: "https://olas.app/e/{code}", Platform: platformWeb} - primalWeb = ClientReference{ID: "primal", Name: "Primal", Base: "https://primal.net/e/{code}", Platform: platformWeb} - nostrudel = ClientReference{ID: "nostrudel", Name: "Nostrudel", Base: "https://nostrudel.ninja/l/{code}", Platform: platformWeb} - nostter = ClientReference{ID: "nostter", Name: "Nostter", Base: "https://nostter.app/{code}", Platform: platformWeb} - nostterRelay = ClientReference{ID: "nostter", Name: "Nostter", Base: "https://nostter.app/relays/wss%3A%2F%2F{code}", Platform: platformWeb} - jumble = ClientReference{ID: "jumble", Name: "Jumble", Base: "https://jumble.social/{code}", Platform: platformWeb} - jumbleRelay = ClientReference{ID: "jumble", Name: "Jumble", Base: "https://jumble.social/?r=wss://{code}", Platform: platformWeb} - coracle = ClientReference{ID: "coracle", Name: "Coracle", Base: "https://coracle.social/{code}", Platform: platformWeb} - coracleRelay = ClientReference{ID: "coracle", Name: "Coracle", Base: "https://coracle.social/relays/wss%3A%2F%2F{code}", Platform: platformWeb} - relayTools = ClientReference{ID: "relay.tools", Name: "relay.tools", Base: "https://relay.tools/posts/?relay=wss://{code}"} - iris = ClientReference{ID: "iris", Name: "Iris", Base: "https://iris.to/{code}", Platform: "web"} - lumilumi = ClientReference{ID: "lumilumi", Name: "Lumilumi", Base: "https://lumilumi.app/{code}", Platform: platformWeb} - lumilumiRelay = ClientReference{ID: "lumilumi", Name: "Lumilumi", Base: "https://lumilumi.app/relay/wss%3A%2F%2F{code}", Platform: platformWeb} - chachiRelay = ClientReference{ID: "chachi", Name: "chachi", Base: "https://chachi.chat/relay/wss%3A%2F%2F{code}/feed"} - yakihonne = ClientReference{ID: "yakihonne", Name: "YakiHonne", Base: "https://yakihonne.com/{code}", Platform: platformWeb} - yakihonneRelay = ClientReference{ID: "yakihonne", Name: "YakiHonne", Base: "https://yakihonne.com/r/content?r=wss://{code}", Platform: platformWeb} - - zapStream = ClientReference{ID: "zap.stream", Name: "zap.stream", Base: "https://zap.stream/{code}", Platform: platformWeb} - shosho = ClientReference{ID: "shosho", Name: "Shosho", Base: "https://shosho.live/live/{code}", Platform: platformWeb} - - habla = ClientReference{ID: "habla", Name: "Habla", Base: "https://habla.news/a/{code}", Platform: platformWeb} - pareto = ClientReference{ID: "pareto", Name: "Pareto", Base: "https://pareto.space/a/{code}", Platform: platformWeb} - - voyage = ClientReference{ID: "voyage", Name: "Voyage", Base: "intent:{code}#Intent;scheme=nostr;package=com.dluvian.voyage;end`;", Platform: platformAndroid} - olasAndroid = ClientReference{ID: "olas", Name: "Olas", Base: "intent:{code}#Intent;scheme=nostr;package=com.pablof7z.snapstr;end`;", Platform: platformAndroid} - primalAndroid = ClientReference{ID: "primal", Name: "Primal", Base: "intent:{code}#Intent;scheme=nostr;package=net.primal.android;end`;", Platform: platformAndroid} - yakihonneAndroid = ClientReference{ID: "yakihonne", Name: "Yakihonne", Base: "intent:{code}#Intent;scheme=nostr;package=com.yakihonne.yakihonne;end`;", Platform: platformAndroid} - freeFromAndroid = ClientReference{ID: "freefrom", Name: "FreeFrom", Base: "intent:{code}#Intent;scheme=nostr;package=com.freefrom;end`;", Platform: platformAndroid} - yanaAndroid = ClientReference{ID: "yana", Name: "Yana", Base: "intent:{code}#Intent;scheme=nostr;package=yana.nostr;end`;", Platform: platformAndroid} - amethyst = ClientReference{ID: "amethyst", Name: "Amethyst", Base: "intent:{code}#Intent;scheme=nostr;package=com.vitorpamplona.amethyst;end`;", Platform: platformAndroid} +type clientsConfig struct { + Clients map[string]clientData `json:"clients"` + KindMappings map[string][]string `json:"kindMappings"` +} - nos = ClientReference{ID: "nos", Name: "Nos", Base: "nos:{code}", Platform: platformIOS} - damus = ClientReference{ID: "damus", Name: "Damus", Base: "damus:{code}", Platform: platformIOS} - nostur = ClientReference{ID: "nostur", Name: "Nostur", Base: "nostur:{code}", Platform: platformIOS} - olasIOS = ClientReference{ID: "olas", Name: "Olas", Base: "olas:{code}", Platform: platformIOS} - primalIOS = ClientReference{ID: "primal", Name: "Primal", Base: "primal:{code}", Platform: platformIOS} - freeFromIOS = ClientReference{ID: "freefrom", Name: "FreeFrom", Base: "freefrom:{code}", Platform: platformIOS} - yakihonneIOS = ClientReference{ID: "yakihonne", Name: "Yakihonne", Base: "yakihhone:{code}", Platform: platformIOS} +type clientData struct { + Name string `json:"name"` + Base string `json:"base"` + Platform string `json:"platform"` +} - wikistr = ClientReference{ID: "wikistr", Name: "Wikistr", Base: "https://Wikistr.com/{handle}*{authorPubkey}", Platform: "web"} - wikifreedia = ClientReference{ID: "wikifreedia", Name: "Wikifreedia", Base: "https://wikifreedia.xyz/{handle}/{npub}", Platform: "web"} +var ( + config clientsConfig ) +func init() { + data, err := os.ReadFile("clients.json") + if err != nil { + panic("Failed to read clients.json: " + err.Error()) + } + if err := json.Unmarshal(data, &config); err != nil { + panic("Failed to parse clients.json: " + err.Error()) + } +} + func generateClientList( kind int, code string, withModifiers ...func(ClientReference, string) string, ) []ClientReference { - var clients []ClientReference - switch kind { - case -1: // relays - clients = []ClientReference{ - native, - nostur, yakihonneAndroid, yakihonneIOS, - jumbleRelay, yakihonneRelay, chachiRelay, nosotrosRelay, lumilumiRelay, coracleRelay, relayTools, nostterRelay, - defaultWeb, - } - case 1, 6: - clients = []ClientReference{ - native, - damus, nostur, freeFromIOS, yakihonneIOS, nos, primalIOS, - voyage, yakihonneAndroid, primalAndroid, freeFromAndroid, yanaAndroid, - nosotros, jumble, coracle, lumilumi, nostter, nostrudel, phoenix, primalWeb, iris, yakihonne, - } - case 20: - clients = []ClientReference{ - native, - olasAndroid, - olasIOS, - nosotros, lumilumi, jumble, olasWeb, coracle, - defaultWeb, - } - case 0: - clients = []ClientReference{ - native, - nos, damus, nostur, primalIOS, freeFromIOS, yakihonneIOS, - voyage, yakihonneAndroid, yanaAndroid, freeFromAndroid, primalAndroid, - nosotros, jumble, nosta, coracle, phoenix, nostter, nostrudel, primalWeb, iris, yakihonne, - defaultWeb, - } - case 30023, 30024: - clients = []ClientReference{ - native, - damus, nos, nostur, yakihonneIOS, - yakihonneAndroid, amethyst, - yakihonne, lumilumi, coracle, pareto, habla, - defaultWeb, - } - case 1063: - clients = []ClientReference{ - native, - amethyst, - lumilumi, phoenix, coracle, nostrudel, - defaultWeb, - } - case 9802: - clients = []ClientReference{ - coracle, - nostrudel, - lumilumi, - jumble, - defaultWeb, - } - case 30311: - clients = []ClientReference{ - native, - amethyst, - nostur, - zapStream, shosho, lumilumi, nostrudel, - defaultWeb, - } - case 30818: - clients = []ClientReference{ - native, - wikistr, wikifreedia, - defaultWeb, - } - case 31922, 31923: - clients = []ClientReference{ - native, - coracle, - defaultWeb, + kindKey := strconv.Itoa(kind) + clientIDs, ok := config.KindMappings[kindKey] + if !ok { + clientIDs = config.KindMappings["default"] + } + + clients := make([]ClientReference, 0, len(clientIDs)) + for _, id := range clientIDs { + clientInfo, ok := config.Clients[id] + if !ok { + continue } - default: - clients = []ClientReference{ - native, - yakihonneIOS, nos, damus, nostur, primalIOS, freeFromIOS, - voyage, amethyst, yakihonneAndroid, yanaAndroid, freeFromAndroid, voyage, - yakihonne, coracle, phoenix, nostter, nostrudel, primalWeb, iris, - defaultWeb, + + c := ClientReference{ + ID: id, + Name: clientInfo.Name, + Base: clientInfo.Base, + Platform: clientInfo.Platform, } - } - for i, c := range clients { - clients[i].URL = templ.SafeURL(strings.Replace(c.Base, "{code}", code, -1)) + url := strings.Replace(c.Base, "{code}", code, -1) for _, modifier := range withModifiers { - clients[i].URL = templ.SafeURL(modifier(c, string(clients[i].URL))) + url = modifier(c, url) } + c.URL = templ.SafeURL(url) + + clients = append(clients, c) } return clients diff --git a/clients.json b/clients.json new file mode 100644 index 0000000..2c4dc7a --- /dev/null +++ b/clients.json @@ -0,0 +1,304 @@ +{ + "clients": { + "native": { + "name": "Your default app", + "base": "nostr:{code}", + "platform": "native" + }, + "default-web": { + "name": "Your default web app", + "base": "web+nostr:{code}", + "platform": "web" + }, + "nosotros": { + "name": "Nosotros", + "base": "https://dev.nosotros.app/{code}", + "platform": "web" + }, + "nosotros-relay": { + "name": "Nosotros", + "base": "https://dev.nosotros.app/feed?kind=%5B1%2C6%5D&limit=100&type=relayfeed&relay=wss%3A%2F%2F{code}", + "platform": "web" + }, + "nosta": { + "name": "Nosta", + "base": "https://nosta.me/{code}", + "platform": "web" + }, + "phoenix": { + "name": "Phoenix", + "base": "https://phoenix.social/{code}", + "platform": "web" + }, + "olas-web": { + "name": "Olas", + "base": "https://olas.app/e/{code}", + "platform": "web" + }, + "primal-web": { + "name": "Primal", + "base": "https://primal.net/e/{code}", + "platform": "web" + }, + "nostrudel": { + "name": "Nostrudel", + "base": "https://nostrudel.ninja/l/{code}", + "platform": "web" + }, + "nostter": { + "name": "Nostter", + "base": "https://nostter.app/{code}", + "platform": "web" + }, + "nostter-relay": { + "name": "Nostter", + "base": "https://nostter.app/relays/wss%3A%2F%2F{code}", + "platform": "web" + }, + "jumble": { + "name": "Jumble", + "base": "https://jumble.social/{code}", + "platform": "web" + }, + "jumble-relay": { + "name": "Jumble", + "base": "https://jumble.social/?r=wss://{code}", + "platform": "web" + }, + "coracle": { + "name": "Coracle", + "base": "https://coracle.social/{code}", + "platform": "web" + }, + "coracle-relay": { + "name": "Coracle", + "base": "https://coracle.social/relays/wss%3A%2F%2F{code}", + "platform": "web" + }, + "relay-tools": { + "name": "relay.tools", + "base": "https://relay.tools/posts/?relay=wss://{code}", + "platform": "web" + }, + "iris": { + "name": "Iris", + "base": "https://iris.to/{code}", + "platform": "web" + }, + "lumilumi": { + "name": "Lumilumi", + "base": "https://lumilumi.app/{code}", + "platform": "web" + }, + "lumilumi-relay": { + "name": "Lumilumi", + "base": "https://lumilumi.app/relay/wss%3A%2F%2F{code}", + "platform": "web" + }, + "chachi-relay": { + "name": "chachi", + "base": "https://chachi.chat/relay/wss%3A%2F%2F{code}/feed", + "platform": "web" + }, + "yakihonne": { + "name": "YakiHonne", + "base": "https://yakihonne.com/{code}", + "platform": "web" + }, + "yakihonne-relay": { + "name": "YakiHonne", + "base": "https://yakihonne.com/r/content?r=wss://{code}", + "platform": "web" + }, + "zap-stream": { + "name": "zap.stream", + "base": "https://zap.stream/{code}", + "platform": "web" + }, + "shosho": { + "name": "Shosho", + "base": "https://shosho.live/live/{code}", + "platform": "web" + }, + "habla": { + "name": "Habla", + "base": "https://habla.news/a/{code}", + "platform": "web" + }, + "pareto": { + "name": "Pareto", + "base": "https://pareto.space/a/{code}", + "platform": "web" + }, + "voyage": { + "name": "Voyage", + "base": "intent:{code}#Intent;scheme=nostr;package=com.dluvian.voyage;end`;", + "platform": "android" + }, + "olas-android": { + "name": "Olas", + "base": "intent:{code}#Intent;scheme=nostr;package=com.pablof7z.snapstr;end`;", + "platform": "android" + }, + "primal-android": { + "name": "Primal", + "base": "intent:{code}#Intent;scheme=nostr;package=net.primal.android;end`;", + "platform": "android" + }, + "yakihonne-android": { + "name": "Yakihonne", + "base": "intent:{code}#Intent;scheme=nostr;package=com.yakihonne.yakihonne;end`;", + "platform": "android" + }, + "freefrom-android": { + "name": "FreeFrom", + "base": "intent:{code}#Intent;scheme=nostr;package=com.freefrom;end`;", + "platform": "android" + }, + "yana-android": { + "name": "Yana", + "base": "intent:{code}#Intent;scheme=nostr;package=yana.nostr;end`;", + "platform": "android" + }, + "amethyst": { + "name": "Amethyst", + "base": "intent:{code}#Intent;scheme=nostr;package=com.vitorpamplona.amethyst;end`;", + "platform": "android" + }, + "nos": { + "name": "Nos", + "base": "nos:{code}", + "platform": "ios" + }, + "damus": { + "name": "Damus", + "base": "damus:{code}", + "platform": "ios" + }, + "nostur": { + "name": "Nostur", + "base": "nostur:{code}", + "platform": "ios" + }, + "olas-ios": { + "name": "Olas", + "base": "olas:{code}", + "platform": "ios" + }, + "primal-ios": { + "name": "Primal", + "base": "primal:{code}", + "platform": "ios" + }, + "freefrom-ios": { + "name": "FreeFrom", + "base": "freefrom:{code}", + "platform": "ios" + }, + "yakihonne-ios": { + "name": "Yakihonne", + "base": "yakihhone:{code}", + "platform": "ios" + }, + "wikistr": { + "name": "Wikistr", + "base": "https://Wikistr.com/{handle}*{authorPubkey}", + "platform": "web" + }, + "wikifreedia": { + "name": "Wikifreedia", + "base": "https://wikifreedia.xyz/{handle}/{npub}", + "platform": "web" + } + }, + "kindMappings": { + "-1": [ + "native", + "nostur", "yakihonne-android", "yakihonne-ios", + "jumble-relay", "yakihonne-relay", "chachi-relay", "nosotros-relay", "lumilumi-relay", "coracle-relay", "relay-tools", "nostter-relay", + "default-web" + ], + "1": [ + "native", + "damus", "nostur", "freefrom-ios", "yakihonne-ios", "nos", "primal-ios", + "voyage", "yakihonne-android", "primal-android", "freefrom-android", "yana-android", + "nosotros", "jumble", "coracle", "lumilumi", "nostter", "nostrudel", "phoenix", "primal-web", "iris", "yakihonne" + ], + "6": [ + "native", + "damus", "nostur", "freefrom-ios", "yakihonne-ios", "nos", "primal-ios", + "voyage", "yakihonne-android", "primal-android", "freefrom-android", "yana-android", + "nosotros", "jumble", "coracle", "lumilumi", "nostter", "nostrudel", "phoenix", "primal-web", "iris", "yakihonne" + ], + "20": [ + "native", + "olas-android", + "olas-ios", + "nosotros", "lumilumi", "jumble", "olas-web", "coracle", + "default-web" + ], + "0": [ + "native", + "nos", "damus", "nostur", "primal-ios", "freefrom-ios", "yakihonne-ios", + "voyage", "yakihonne-android", "yana-android", "freefrom-android", "primal-android", + "nosotros", "jumble", "nosta", "coracle", "phoenix", "nostter", "nostrudel", "primal-web", "iris", "yakihonne", + "default-web" + ], + "30023": [ + "native", + "damus", "nos", "nostur", "yakihonne-ios", + "yakihonne-android", "amethyst", + "yakihonne", "lumilumi", "coracle", "pareto", "habla", + "default-web" + ], + "30024": [ + "native", + "damus", "nos", "nostur", "yakihonne-ios", + "yakihonne-android", "amethyst", + "yakihonne", "lumilumi", "coracle", "pareto", "habla", + "default-web" + ], + "1063": [ + "native", + "amethyst", + "lumilumi", "phoenix", "coracle", "nostrudel", + "default-web" + ], + "9802": [ + "coracle", + "nostrudel", + "lumilumi", + "jumble", + "default-web" + ], + "30311": [ + "native", + "amethyst", + "nostur", + "zap-stream", "shosho", "lumilumi", "nostrudel", + "default-web" + ], + "30818": [ + "native", + "wikistr", "wikifreedia", + "default-web" + ], + "31922": [ + "native", + "coracle", + "default-web" + ], + "31923": [ + "native", + "coracle", + "default-web" + ], + "default": [ + "native", + "yakihonne-ios", "nos", "damus", "nostur", "primal-ios", "freefrom-ios", + "voyage", "amethyst", "yakihonne-android", "yana-android", "freefrom-android", "voyage", + "yakihonne", "coracle", "phoenix", "nostter", "nostrudel", "primal-web", "iris", + "default-web" + ] + } +} diff --git a/render_event.go b/render_event.go index 7eb2409..7549e93 100644 --- a/render_event.go +++ b/render_event.go @@ -454,7 +454,7 @@ func renderEvent(w http.ResponseWriter, r *http.Request) { LiveEvent: *data.kind30311Metadata, Clients: generateClientList(int(data.event.Kind), data.naddr, func(c ClientReference, s string) string { - if c == nostrudel { + if c.ID == "nostrudel" { s = strings.Replace(s, "/u/", "/streams/", 1) } return s diff --git a/render_profile.go b/render_profile.go index 1a5afdc..16a443c 100644 --- a/render_profile.go +++ b/render_profile.go @@ -125,10 +125,10 @@ func renderProfile(ctx context.Context, r *http.Request, w http.ResponseWriter, LastNotes: lastNotes, Clients: generateClientList(0, nprofile, func(c ClientReference, s string) string { - if c == nostrudel { + if c.ID == "nostrudel" { s = strings.Replace(s, "/n/", "/u/", 1) } - if c == primalWeb { + if c.ID == "primal-web" { s = strings.Replace( strings.Replace(s, "/e/", "/p/", 1), nprofile, profile.Npub(), 1) From 8439f545363871f35bf0e325c6bb2599815a5b7a Mon Sep 17 00:00:00 2001 From: mattn Date: Sun, 23 Nov 2025 18:27:38 +0900 Subject: [PATCH 06/12] customizable clients config path (#137) --- clients.go | 16 ++++++++-------- main.go | 5 +++++ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/clients.go b/clients.go index bc62764..9526880 100644 --- a/clients.go +++ b/clients.go @@ -17,7 +17,7 @@ type ClientReference struct { Platform string } -type clientsConfig struct { +type ClientsConfig struct { Clients map[string]clientData `json:"clients"` KindMappings map[string][]string `json:"kindMappings"` } @@ -29,15 +29,15 @@ type clientData struct { } var ( - config clientsConfig + clientConfig ClientsConfig ) -func init() { - data, err := os.ReadFile("clients.json") +func loadClientsConfig(configPath string) { + data, err := os.ReadFile(configPath) if err != nil { panic("Failed to read clients.json: " + err.Error()) } - if err := json.Unmarshal(data, &config); err != nil { + if err := json.Unmarshal(data, &clientConfig); err != nil { panic("Failed to parse clients.json: " + err.Error()) } } @@ -48,14 +48,14 @@ func generateClientList( withModifiers ...func(ClientReference, string) string, ) []ClientReference { kindKey := strconv.Itoa(kind) - clientIDs, ok := config.KindMappings[kindKey] + clientIDs, ok := clientConfig.KindMappings[kindKey] if !ok { - clientIDs = config.KindMappings["default"] + clientIDs = clientConfig.KindMappings["default"] } clients := make([]ClientReference, 0, len(clientIDs)) for _, id := range clientIDs { - clientInfo, ok := config.Clients[id] + clientInfo, ok := clientConfig.Clients[id] if !ok { continue } diff --git a/main.go b/main.go index da833f1..bf23d55 100644 --- a/main.go +++ b/main.go @@ -28,6 +28,7 @@ type Settings struct { HintsMemoryDumpPath string `envconfig:"HINTS_SAVE_PATH" default:"/tmp/njump-hints.json"` TailwindDebug bool `envconfig:"TAILWIND_DEBUG"` RelayConfigPath string `envconfig:"RELAY_CONFIG_PATH"` + ClientsConfigPath string `envconfig:"CLIENTS_CONFIG_PATH" default:"clients.json"` MediaAlertAPIKey string `envconfig:"MEDIA_ALERT_API_KEY"` ErrorLogPath string `envconfig:"ERROR_LOG_PATH" default:"/tmp/njump-errors.jsonl"` @@ -87,6 +88,10 @@ func main() { } } + if s.ClientsConfigPath != "" { + loadClientsConfig(s.ClientsConfigPath) + } + // if we're in tailwind debug mode, initialize the runtime tailwind stuff if s.TailwindDebug { configb, err := os.ReadFile("tailwind.config.js") From 53a23f16a6bcdd7ee06525b34ab08eef97e619a7 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Sun, 23 Nov 2025 07:04:46 -0300 Subject: [PATCH 07/12] update nostrlib dependency with nip10 fixes. fixes https://github.com/fiatjaf/njump/issues/138 --- go.mod | 30 +++++++++++++++---------- go.sum | 71 +++++++++++++++++++++++++++++++++++----------------------- 2 files changed, 61 insertions(+), 40 deletions(-) diff --git a/go.mod b/go.mod index efba7cd..a5aaed4 100644 --- a/go.mod +++ b/go.mod @@ -3,9 +3,9 @@ module github.com/fiatjaf/njump go 1.24.2 require ( - fiatjaf.com/nostr v0.0.0-20250929200447-1e40fecdc26d + fiatjaf.com/nostr v0.0.0-20251123095754-8458e262918a github.com/PuerkitoBio/goquery v1.10.1 - github.com/a-h/templ v0.3.943 + github.com/a-h/templ v0.3.960 github.com/bytesparadise/libasciidoc v0.8.0 github.com/dgraph-io/ristretto v1.0.0 github.com/fogleman/gg v1.3.0 @@ -27,7 +27,7 @@ require ( github.com/texttheater/golang-levenshtein v1.0.1 github.com/tylermmorton/tmpl v0.0.0-20231025031313-5552ee818c6d golang.org/x/image v0.17.0 - golang.org/x/sync v0.17.0 + golang.org/x/sync v0.18.0 mvdan.cc/xurls/v2 v2.5.0 ) @@ -40,7 +40,8 @@ require ( github.com/andybalholm/cascadia v1.3.3 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/bep/debounce v1.2.1 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.5 // indirect + github.com/btcsuite/btcd v0.24.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.6 // indirect github.com/btcsuite/btcd/btcutil v1.1.5 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -51,9 +52,10 @@ require ( github.com/dgraph-io/ristretto/v2 v2.3.0 // indirect github.com/dlclark/regexp2 v1.4.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/elnosh/gonuts v0.4.2 // indirect github.com/fasthttp/websocket v1.5.12 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect - github.com/golang/protobuf v1.5.4 // indirect github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect github.com/gorilla/css v1.0.1 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -69,19 +71,23 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 // indirect - github.com/sirupsen/logrus v1.7.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/templexxx/cpu v0.1.1 // indirect + github.com/templexxx/xhex v0.0.0-20200614015412-aed53437177b // indirect github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.2.0 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.59.0 // indirect + github.com/x448/float16 v0.8.4 // indirect go.etcd.io/bbolt v1.4.2 // indirect - golang.org/x/exp v0.0.0-20250911091902-df9299821621 // indirect - golang.org/x/mod v0.28.0 // indirect - golang.org/x/net v0.44.0 // indirect - golang.org/x/sys v0.36.0 // indirect - golang.org/x/text v0.29.0 // indirect - golang.org/x/tools v0.37.0 // indirect + golang.org/x/crypto v0.44.0 // indirect + golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/text v0.31.0 // indirect + golang.org/x/tools v0.39.0 // indirect google.golang.org/protobuf v1.36.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 2981ffd..0a5aa0b 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -fiatjaf.com/nostr v0.0.0-20250929200447-1e40fecdc26d h1:mXqA+f1TNri7iWUeN5mc5BHVQfpla1Qel2TRnjhvlcE= -fiatjaf.com/nostr v0.0.0-20250929200447-1e40fecdc26d/go.mod h1:Nq86Jjsd0OmsOEImUg0iCcLuqM5B67Nj2eu/2dP74Ss= +fiatjaf.com/nostr v0.0.0-20251123095754-8458e262918a h1:r4AH4MyJdMUuz9MdgrTYxpKYSaE8iQdPbWbxFXtJx9w= +fiatjaf.com/nostr v0.0.0-20251123095754-8458e262918a/go.mod h1:TLv5JlgQg1rMVoQFgV8y8OOIqOahHvvaRXw43DtZk8k= github.com/DataDog/gostackparse v0.5.0 h1:jb72P6GFHPHz2W0onsN51cS3FkaMDcjb0QzgxxA4gDk= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= github.com/FastFilter/xorfilter v0.2.1 h1:lbdeLG9BdpquK64ZsleBS8B4xO/QW1IM0gMzF7KaBKc= @@ -10,8 +10,8 @@ github.com/PowerDNS/lmdb-go v1.9.3 h1:AUMY2pZT8WRpkEv39I9Id3MuoHd+NZbTVpNhruVkPT github.com/PowerDNS/lmdb-go v1.9.3/go.mod h1:TE0l+EZK8Z1B4dx070ZxkWTlp8RG1mjN0/+FkFRQMtU= github.com/PuerkitoBio/goquery v1.10.1 h1:Y8JGYUkXWTGRB6Ars3+j3kN0xg1YqqlwvdTV8WTFQcU= github.com/PuerkitoBio/goquery v1.10.1/go.mod h1:IYiHrOMps66ag56LEH7QYDDupKXyo5A8qrjIx3ZtujY= -github.com/a-h/templ v0.3.943 h1:o+mT/4yqhZ33F3ootBiHwaY4HM5EVaOJfIshvd5UNTY= -github.com/a-h/templ v0.3.943/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo= +github.com/a-h/templ v0.3.960 h1:trshEpGa8clF5cdI39iY4ZrZG8Z/QixyzEyUnA7feTM= +github.com/a-h/templ v0.3.960/go.mod h1:oCZcnKRf5jjsGpf2yELzQfodLphd2mwecwG4Crk5HBo= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/alecthomas/chroma/v2 v2.3.0 h1:83xfxrnjv8eK+Cf8qZDzNo3PPF9IbTWHs7z28GY6D0U= github.com/alecthomas/chroma/v2 v2.3.0/go.mod h1:mZxeWZlxP2Dy+/8cBob2PYd8O2DwNAzave5AY7A2eQw= @@ -28,10 +28,12 @@ github.com/bep/debounce v1.2.1/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3IS github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= +github.com/btcsuite/btcd v0.24.2 h1:aLmxPguqxza+4ag8R1I2nnJjSu2iFn/kqtHTIImswcY= +github.com/btcsuite/btcd v0.24.2/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.5 h1:dpAlnAwmT1yIBm3exhT1/8iUSD98RDJM5vqJVQDQLiU= -github.com/btcsuite/btcd/btcec/v2 v2.3.5/go.mod h1:m22FrOAiuxl/tht9wIqAoGHcbnCCaPWyauO8y2LGGtQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.6 h1:IzlsEr9olcSRKB/n7c4351F3xHKxS2lma+1UFGCYd4E= +github.com/btcsuite/btcd/btcec/v2 v2.3.6/go.mod h1:m22FrOAiuxl/tht9wIqAoGHcbnCCaPWyauO8y2LGGtQ= github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8= @@ -83,6 +85,8 @@ github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55k github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= +github.com/elnosh/gonuts v0.4.2 h1:/WubPAWGxTE+okJ0WPvmtEzTzpi04RGxiTHAF1FYU+M= +github.com/elnosh/gonuts v0.4.2/go.mod h1:vgZomh4YQk7R3w4ltZc0sHwCmndfHkuX6V4sga/8oNs= github.com/fasthttp/websocket v1.5.12 h1:e4RGPpWW2HTbL3zV0Y/t7g0ub294LkiuXXUuTOUInlE= github.com/fasthttp/websocket v1.5.12/go.mod h1:I+liyL7/4moHojiOgUOIKEWm9EIxHqxZChS+aMFltyg= github.com/felixge/fgtrace v0.1.0 h1:cuMLI5NoBg/9IxIVmJzsxA3Aoz5eIKRca6WE1U2C1zc= @@ -93,6 +97,8 @@ github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-text/typesetting-utils v0.0.0-20231211103740-d9332ae51f04 h1:zBx+p/W2aQYtNuyZNcTfinWvXBQwYtDfme051PR/lAY= @@ -118,9 +124,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= @@ -191,8 +196,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg= github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= @@ -202,14 +207,13 @@ github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38 h1:D0vL7YNisV2yqE55 github.com/savsgio/gotils v0.0.0-20240704082632-aef3928b8a38/go.mod h1:sM7Mt7uEoCeFSCBM+qBrqvEo+/9vdmj19wzp3yzUhmg= github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ= github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -217,6 +221,11 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/templexxx/cpu v0.0.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk= +github.com/templexxx/cpu v0.1.1 h1:isxHaxBXpYFWnk2DReuKkigaZyrjs2+9ypIdGP4h+HI= +github.com/templexxx/cpu v0.1.1/go.mod h1:w7Tb+7qgcAlIyX4NhLuDKt78AHA5SzPmq0Wj6HiEnnk= +github.com/templexxx/xhex v0.0.0-20200614015412-aed53437177b h1:XeDLE6c9mzHpdv3Wb1+pWBaWv/BlHK0ZYIu/KaL6eHg= +github.com/templexxx/xhex v0.0.0-20200614015412-aed53437177b/go.mod h1:7rwmCH0wC2fQvNEvPZ3sKXukhyCTyiaZ5VTZMQYpZKQ= github.com/texttheater/golang-levenshtein v1.0.1 h1:+cRNoVrfiwufQPhoMzB6N0Yf/Mqajr6t1lOv8GyGE2U= github.com/texttheater/golang-levenshtein v1.0.1/go.mod h1:PYAKrbF5sAiq9wd+H82hs7gNaen0CplQ9uvm6+enD/8= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= @@ -227,12 +236,16 @@ github.com/tidwall/match v1.2.0/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/tylermmorton/tmpl v0.0.0-20231025031313-5552ee818c6d h1:DZ25KkbqQMYQE9Dk5x4WMJlBg39HSOn0HIn0t6cCSjI= github.com/tylermmorton/tmpl v0.0.0-20231025031313-5552ee818c6d/go.mod h1:aFT85F39qRY7ZZT5pHU01s1Ru3o9EOmbd+UjbrxxHw4= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.59.0 h1:Qu0qYHfXvPk1mSLNqcFtEk6DpxgA26hy6bmydotDpRI= github.com/valyala/fasthttp v1.59.0/go.mod h1:GTxNb9Bc6r2a9D0TWNSPwDz78UxnTGBViY3xZNEqyYU= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -248,8 +261,10 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU= -golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 h1:zfMcR1Cs4KNuomFFgGefv5N0czO2XZpUbxGUy8i8ug0= +golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6/go.mod h1:46edojNIoXTNOhySWIWdix628clX9ODXwPsQuG6hsK0= golang.org/x/image v0.17.0 h1:nTRVVdajgB8zCMZVsViyzhnMKPwYeroEERRC64JuLco= golang.org/x/image v0.17.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -258,8 +273,8 @@ golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= -golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U= -golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -276,8 +291,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I= -golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -287,14 +302,13 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -306,6 +320,7 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -315,8 +330,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= -golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -337,8 +352,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= -golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190830223141-573d9926052a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -347,8 +362,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= -golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= -golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 7323b4df7e68cd991182fb06383475c802b726a9 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Sun, 23 Nov 2025 15:57:24 -0300 Subject: [PATCH 08/12] default to default clients.json --- clients.go | 12 ------------ main.go | 20 ++++++++++++++++++-- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/clients.go b/clients.go index 9526880..6c8d1d7 100644 --- a/clients.go +++ b/clients.go @@ -1,8 +1,6 @@ package main import ( - "encoding/json" - "os" "strconv" "strings" @@ -32,16 +30,6 @@ var ( clientConfig ClientsConfig ) -func loadClientsConfig(configPath string) { - data, err := os.ReadFile(configPath) - if err != nil { - panic("Failed to read clients.json: " + err.Error()) - } - if err := json.Unmarshal(data, &clientConfig); err != nil { - panic("Failed to parse clients.json: " + err.Error()) - } -} - func generateClientList( kind int, code string, diff --git a/main.go b/main.go index bf23d55..9583b19 100644 --- a/main.go +++ b/main.go @@ -28,7 +28,7 @@ type Settings struct { HintsMemoryDumpPath string `envconfig:"HINTS_SAVE_PATH" default:"/tmp/njump-hints.json"` TailwindDebug bool `envconfig:"TAILWIND_DEBUG"` RelayConfigPath string `envconfig:"RELAY_CONFIG_PATH"` - ClientsConfigPath string `envconfig:"CLIENTS_CONFIG_PATH" default:"clients.json"` + ClientsConfigPath string `envconfig:"CLIENTS_CONFIG_PATH"` MediaAlertAPIKey string `envconfig:"MEDIA_ALERT_API_KEY"` ErrorLogPath string `envconfig:"ERROR_LOG_PATH" default:"/tmp/njump-errors.jsonl"` @@ -39,6 +39,9 @@ type Settings struct { //go:embed static/* var static embed.FS +//go:embed clients.json +var embeddedClientsJSON string + var ( s Settings log = zerolog.New(os.Stderr).Output(zerolog.ConsoleWriter{Out: os.Stdout}). @@ -89,7 +92,20 @@ func main() { } if s.ClientsConfigPath != "" { - loadClientsConfig(s.ClientsConfigPath) + data, err := os.ReadFile(s.ClientsConfigPath) + if err != nil { + log.Fatal().Err(err).Msg("failed to load clients config") + return + } + if err := json.Unmarshal(data, &clientConfig); err != nil { + log.Fatal().Err(err).Msg("failed to parse clients config") + return + } + } else { + if err := json.Unmarshal([]byte(embeddedClientsJSON), &clientConfig); err != nil { + log.Fatal().Err(err).Msg("failed to parse embedded clients config") + return + } } // if we're in tailwind debug mode, initialize the runtime tailwind stuff From 4bdc93ee540f6e9809b18c9377e759d0581be966 Mon Sep 17 00:00:00 2001 From: dtonon Date: Mon, 24 Nov 2025 15:58:46 +0000 Subject: [PATCH 09/12] Add CLIENTS_CONFIG_PATH to the readme --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 362e78b..cdeecfd 100644 --- a/README.md +++ b/README.md @@ -58,9 +58,12 @@ DISK_CACHE_PATH="/tmp/njump-internal" EVENT_STORE_PATH="/tmp/njump-db" TAILWIND_DEBUG= RELAY_CONFIG_PATH= +CLIENTS_CONFIG_PATH= TRUSTED_PUBKEYS=npub1...,npub1... ``` +--- + `RELAY_CONFIG_PATH` is path to json file to update relay configuration. You can set relay list like below: ```json @@ -75,3 +78,7 @@ TRUSTED_PUBKEYS=npub1...,npub1... See `relay-config.json.sample` for example. For example, when running from a precompiled binary you can do something like `PORT=5000 ./njump`. + +--- + +`CLIENTS_CONFIG_PATH` is path to json file to update the clients list. You can find the default at [/clients.json](./clients.json) From faf967f32395a093403463b75cbcdcf42b354b66 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Mon, 24 Nov 2025 20:14:14 -0300 Subject: [PATCH 10/12] use our own system relay sets rather than the defaults. --- nostr.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/nostr.go b/nostr.go index c7a542e..4dfd707 100644 --- a/nostr.go +++ b/nostr.go @@ -86,6 +86,23 @@ func initSystem() func() { sys.KVStore = kv sys.Store = db + sys.RelayListRelays = sdk.NewRelayStream("wss://purplepag.es", "wss://user.kindpag.es", "wss://relay.nos.social", "wss://relay.vertexlab.io", "wss://indexer.coracle.social") + sys.FollowListRelays = sdk.NewRelayStream("wss://purplepag.es", "wss://user.kindpag.es", "wss://relay.nos.social", "wss://relay.vertexlab.io", "wss://indexer.coracle.social") + sys.MetadataRelays = sdk.NewRelayStream("wss://purplepag.es", "wss://user.kindpag.es", "wss://relay.nos.social", "wss://relay.vertexlab.io", "wss://indexer.coracle.social") + sys.FallbackRelays = sdk.NewRelayStream( + "wss://offchain.pub", + "wss://relay.damus.io", + "wss://relay.primal.net", + "wss://nostr.mom", + "wss://nos.lol", + "wss://relay.mostr.pub", + "wss://nostr.wine", + ) + sys.JustIDRelays = sdk.NewRelayStream( + "wss://cache2.primal.net/v1", + "wss://relay.nostr.band", + ) + return db.Close } From f1cef7eccab8e738fc46bbea0bc0686bea1db5fa Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Wed, 26 Nov 2025 09:07:24 -0300 Subject: [PATCH 11/12] support nip05 addresses again. fixes https://github.com/fiatjaf/njump/issues/139 --- go.mod | 4 ++-- go.sum | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index a5aaed4..1e2e676 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module github.com/fiatjaf/njump -go 1.24.2 +go 1.25 require ( - fiatjaf.com/nostr v0.0.0-20251123095754-8458e262918a + fiatjaf.com/nostr v0.0.0-20251126120447-7261a4b515ed github.com/PuerkitoBio/goquery v1.10.1 github.com/a-h/templ v0.3.960 github.com/bytesparadise/libasciidoc v0.8.0 diff --git a/go.sum b/go.sum index 0a5aa0b..07f79a6 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -fiatjaf.com/nostr v0.0.0-20251123095754-8458e262918a h1:r4AH4MyJdMUuz9MdgrTYxpKYSaE8iQdPbWbxFXtJx9w= -fiatjaf.com/nostr v0.0.0-20251123095754-8458e262918a/go.mod h1:TLv5JlgQg1rMVoQFgV8y8OOIqOahHvvaRXw43DtZk8k= +fiatjaf.com/nostr v0.0.0-20251126120447-7261a4b515ed h1:dip4Bxlfj4/N2oIIGCZpcYRrvfMObcXRcyBM5uYswnM= +fiatjaf.com/nostr v0.0.0-20251126120447-7261a4b515ed/go.mod h1:ue7yw0zHfZj23Ml2kVSdBx0ENEaZiuvGxs/8VEN93FU= github.com/DataDog/gostackparse v0.5.0 h1:jb72P6GFHPHz2W0onsN51cS3FkaMDcjb0QzgxxA4gDk= github.com/DataDog/gostackparse v0.5.0/go.mod h1:lTfqcJKqS9KnXQGnyQMCugq3u1FP6UZMfWR0aitKFMM= github.com/FastFilter/xorfilter v0.2.1 h1:lbdeLG9BdpquK64ZsleBS8B4xO/QW1IM0gMzF7KaBKc= From 032de519d0e47a7cfc681b264e9a3104c7a16ebd Mon Sep 17 00:00:00 2001 From: Bui Anh Tuan Date: Fri, 28 Nov 2025 17:32:45 +0700 Subject: [PATCH 12/12] build(docker): fix build issues by switching to golang:1-alpine --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 6123fcd..d70e843 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ RUN npm install tailwindcss RUN npx tailwind -i base.css -o tailwind-bundle.min.css --minify #### Go build stage -FROM golang:1.24.2-alpine AS gobuilder +FROM golang:1-alpine AS gobuilder # Add package RUN apk add --no-cache autoconf automake libtool build-base musl-dev git