Compare commits

...

3 commits

Author SHA1 Message Date
ce9fc3516a feat: first pass at lnurlp 2024-02-24 19:29:17 -05:00
900f01166f Merge pull request 'matrix msc3575 support' (#2) from msc3575 into main
Reviewed-on: #2
2024-02-12 03:36:55 +00:00
393d8f1422 matrix msc3575 support 2024-02-11 22:02:24 -05:00
5 changed files with 109 additions and 31 deletions

View file

@ -13,6 +13,7 @@ type (
LogLevel string LogLevel string
MatrixIdentityServer string MatrixIdentityServer string
MatrixWellKnownAddress string MatrixWellKnownAddress string
MatrixMsc3575Address string
NostrAddrFee string NostrAddrFee string
} }
) )
@ -26,6 +27,7 @@ func GetConfig() Config {
LogLevel: getEnv("LOG_LEVEL", "INFO"), LogLevel: getEnv("LOG_LEVEL", "INFO"),
MatrixIdentityServer: getEnv("MATRIX_IDENTITY_SERVER", ""), MatrixIdentityServer: getEnv("MATRIX_IDENTITY_SERVER", ""),
MatrixWellKnownAddress: getEnv("MATRIX_WELL_KNOWN_ADDRESS", ""), MatrixWellKnownAddress: getEnv("MATRIX_WELL_KNOWN_ADDRESS", ""),
MatrixMsc3575Address: getEnv("MATRIX_MSC3575_ADDRESS", ""),
NostrAddrFee: getEnv("NOSTR_ADDR_FEE", "0"), NostrAddrFee: getEnv("NOSTR_ADDR_FEE", "0"),
} }
} }

62
lnurlp/lnurlp.go Normal file
View file

@ -0,0 +1,62 @@
package lnurlp
import (
"context"
b64 "encoding/base64"
"encoding/json"
"fmt"
"net/http"
"strings"
"git.minhas.io/asara/well-goknown/logger"
"git.minhas.io/asara/well-goknown/redis"
)
type ErrorMessage struct {
Error string `json:"error"`
}
type Response struct {
Payload string `json:"request_key"`
}
func GetLnurlpUser(w http.ResponseWriter, r *http.Request) {
ctx := context.TODO()
l := logger.Get()
// connect to redis
redisCli := redis.LnurlpRedisConn.Client
// search for user@domain
search := getRkey("lnurlp", "asara", r.Host)
addr, err := redisCli.Get(ctx, search).Result()
if err != nil {
l.Info().Msg(fmt.Sprintf("get %s: not found", search))
w.WriteHeader(http.StatusNotFound)
json.NewEncoder(w).Encode(&ErrorMessage{
Error: "username not registered",
})
return
}
dec, err := b64.StdEncoding.DecodeString(addr)
if err != nil {
l.Error().Msg(fmt.Sprintf("get %s: unable to decode key", search))
w.WriteHeader(http.StatusInternalServerError)
json.NewEncoder(w).Encode(&ErrorMessage{
Error: "internal server error",
})
return
}
l.Info().Msg(fmt.Sprintf("get %s: found and returned", search))
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
w.Write(dec)
}
func getRkey(prefix string, user string, hostname string) string {
if strings.Contains(hostname, ":") {
hostname = strings.Split(hostname, ":")[0]
}
return fmt.Sprintf("%s:%s@%s", prefix, user, hostname)
}

14
main.go
View file

@ -4,6 +4,7 @@ import (
"net/http" "net/http"
"git.minhas.io/asara/well-goknown/config" "git.minhas.io/asara/well-goknown/config"
"git.minhas.io/asara/well-goknown/lnurlp"
"git.minhas.io/asara/well-goknown/logger" "git.minhas.io/asara/well-goknown/logger"
"git.minhas.io/asara/well-goknown/matrix" "git.minhas.io/asara/well-goknown/matrix"
"git.minhas.io/asara/well-goknown/nostr" "git.minhas.io/asara/well-goknown/nostr"
@ -22,6 +23,10 @@ func main() {
if err != nil { if err != nil {
l.Fatal().Msg("unable to connect to redis") l.Fatal().Msg("unable to connect to redis")
} }
redis.LnurlpRedisConn, err = redis.New("localhost:6379", "", redis.LnurlpKeyspace)
if err != nil {
l.Fatal().Msg("unable to connect to redis")
}
// matrix endpoints // matrix endpoints
l.Debug().Msg("enabling matrix server endpoint") l.Debug().Msg("enabling matrix server endpoint")
@ -33,12 +38,17 @@ func main() {
l.Debug().Msg("enabling nostr user endpoint") l.Debug().Msg("enabling nostr user endpoint")
http.HandleFunc("/.well-known/nostr.json", nostr.GetNostrAddr) http.HandleFunc("/.well-known/nostr.json", nostr.GetNostrAddr)
addr := config.GetConfig().LndAddr // enable requesting of nostr addresses
if addr != "" { lndAddr := config.GetConfig().LndAddr
if lndAddr != "" {
l.Debug().Msg("enabling nostr request endpoint") l.Debug().Msg("enabling nostr request endpoint")
http.HandleFunc("/request/nostr", nostr.RequestNostrAddr) http.HandleFunc("/request/nostr", nostr.RequestNostrAddr)
} }
//lnurlp endpoints
l.Debug().Msg("enabling lnurlp endpoint")
http.HandleFunc("/.well-known/lnurlp/", lnurlp.GetLnurlpUser)
// start server // start server
port := config.GetConfig().ListenAddr port := config.GetConfig().ListenAddr
l.Info().Msgf("starting server on %s", port) l.Info().Msgf("starting server on %s", port)

View file

@ -21,9 +21,14 @@ type matrixIdentityServer struct {
BaseUrl string `json:"base_url,omitempty"` BaseUrl string `json:"base_url,omitempty"`
} }
type msc3575address struct {
Url string `json:"url,omitempty"`
}
type matrixClientWellKnown struct { type matrixClientWellKnown struct {
HomeServer *matrixBaseUrl `json:"m.homeserver"` Homeserver *matrixBaseUrl `json:"m.homeserver"`
IdentityServer *matrixIdentityServer `json:"m.identity_server,omitempty"` IdentityServer *matrixIdentityServer `json:"m.identity_server,omitempty"`
Msc3575 *msc3575address `json:"org.matrix.msc3575.proxy,omitempty"`
} }
func MatrixServer(w http.ResponseWriter, req *http.Request) { func MatrixServer(w http.ResponseWriter, req *http.Request) {
@ -46,36 +51,33 @@ func MatrixServer(w http.ResponseWriter, req *http.Request) {
func MatrixClient(w http.ResponseWriter, req *http.Request) { func MatrixClient(w http.ResponseWriter, req *http.Request) {
l := logger.Get() l := logger.Get()
// uses an environment variable for now m := &matrixClientWellKnown{}
wellKnownAddr := config.GetConfig().MatrixWellKnownAddress wellKnownAddr := config.GetConfig().MatrixWellKnownAddress
// no matrix config set
if wellKnownAddr == "" { if wellKnownAddr == "" {
w.WriteHeader(http.StatusNotFound) w.WriteHeader(http.StatusNotFound)
l.Debug().Str("path", "matrix/client").Msg("matrix well known address unset") l.Debug().Str("path", "matrix/client").Msg("matrix well known address unset")
return return
} }
identityServer := config.GetConfig().MatrixIdentityServer m.Homeserver = &matrixBaseUrl{
if identityServer == "" { BaseUrl: fmt.Sprintf("https://%s", wellKnownAddr),
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
baseUrl := &matrixClientWellKnown{
HomeServer: &matrixBaseUrl{
BaseUrl: fmt.Sprintf("https://%s", wellKnownAddr),
},
}
json.NewEncoder(w).Encode(baseUrl)
} else {
identityServer = fmt.Sprintf("https://%s", identityServer)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
baseUrl := &matrixClientWellKnown{
HomeServer: &matrixBaseUrl{
BaseUrl: fmt.Sprintf("https://%s", wellKnownAddr),
},
IdentityServer: &matrixIdentityServer{
BaseUrl: identityServer,
},
}
json.NewEncoder(w).Encode(baseUrl)
} }
identityServer := config.GetConfig().MatrixIdentityServer
if identityServer != "" {
m.IdentityServer = &matrixIdentityServer{
BaseUrl: identityServer,
}
}
msc3575 := config.GetConfig().MatrixMsc3575Address
if msc3575 != "" {
m.Msc3575 = &msc3575address{
Url: msc3575,
}
}
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(m)
} }

View file

@ -7,8 +7,9 @@ import (
) )
const ( const (
NostrKeyspace = iota NostrKeyspace = iota
LndKeyspace = iota LndKeyspace = iota
LnurlpKeyspace = iota
) )
type Redis struct { type Redis struct {
@ -16,8 +17,9 @@ type Redis struct {
} }
var ( var (
NostrRedisConn *Redis NostrRedisConn *Redis
LndRedisConn *Redis LndRedisConn *Redis
LnurlpRedisConn *Redis
) )
func New(address string, password string, database int) (*Redis, error) { func New(address string, password string, database int) (*Redis, error) {