From 115a0756c3d2db202233165a4d6571a472edcaa6 Mon Sep 17 00:00:00 2001 From: Believethehype <1097224+believethehype@users.noreply.github.com> Date: Wed, 27 Mar 2024 11:59:52 +0100 Subject: [PATCH] updating golang, go-nostr, get more details from lnbits invoice check --- .gitignore | 1 + go.mod | 16 ++++++++++++---- go.sum | 18 ++++++++++++++++++ nostr.go | 45 ++++++++++++++++++++++++++++++++++++--------- waitforinvoice.go | 32 ++++++++++++++++++++++++++------ 5 files changed, 93 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index ada72ad..bcb7be4 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ *.db satdress nostdress +.DS_Store diff --git a/go.mod b/go.mod index 379d9e8..6b8876e 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/believethehype/nostdress -go 1.19 +go 1.21 + +toolchain go1.22.1 require ( github.com/cockroachdb/pebble v0.0.0-20230412222916-60cfeb46143b @@ -9,7 +11,7 @@ require ( github.com/gorilla/mux v1.8.0 github.com/kelseyhightower/envconfig v1.4.0 github.com/lib/pq v1.10.8 - github.com/nbd-wtf/go-nostr v0.16.12 + github.com/nbd-wtf/go-nostr v0.29.3 github.com/nbd-wtf/ln-decodepay v1.5.1 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 github.com/rs/cors v1.9.0 @@ -18,8 +20,14 @@ require ( ) require ( + github.com/gobwas/httphead v0.1.0 // indirect + github.com/gobwas/pool v0.2.1 // indirect + github.com/gobwas/ws v1.2.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/puzpuzpuz/xsync/v3 v3.0.2 // indirect ) require ( @@ -90,10 +98,10 @@ require ( github.com/tidwall/sjson v1.2.5 github.com/valyala/fastjson v1.6.4 // indirect golang.org/x/crypto v0.8.0 // indirect - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect + golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect golang.org/x/mod v0.10.0 // indirect golang.org/x/net v0.9.0 // indirect - golang.org/x/sys v0.7.0 // indirect + golang.org/x/sys v0.8.0 // indirect golang.org/x/term v0.7.0 // indirect golang.org/x/text v0.9.0 // indirect golang.org/x/tools v0.8.0 // indirect diff --git a/go.sum b/go.sum index 4c5503b..65f071a 100644 --- a/go.sum +++ b/go.sum @@ -261,8 +261,14 @@ github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AE github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-xmlpath/xmlpath v0.0.0-20150820204837-860cbeca3ebc/go.mod h1:EpsPHv/XcBVQlA5VTpx2EeK5qJma4oRfpjMfPQiUA3w= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= +github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gobwas/ws v1.2.0 h1:u0p9s3xLYpZCA1z5JgCkMeB34CKCMMQbM+G8Ii7YD0I= +github.com/gobwas/ws v1.2.0/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= @@ -456,6 +462,8 @@ github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwA github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= @@ -598,6 +606,8 @@ github.com/ltcsuite/ltcutil v0.0.0-20181217130922-17f3b04680b6/go.mod h1:8Vg/LTO github.com/lunixbochs/vtclean v0.0.0-20160125035106-4fbf7632a2c6/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/masterzen/azure-sdk-for-go v3.2.0-beta.0.20161014135628-ee4f0065d00c+incompatible/go.mod h1:mf8fjOu33zCqxUjuiU3I8S1lJMyEAlH+0F2+M5xl3hE= github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9/go.mod h1:kCEbxUJlNDEBNbdQMkPSp6yaKcRXVI6f4ddk8Riv4bc= github.com/masterzen/winrm v0.0.0-20161014151040-7a535cd943fc/go.mod h1:CfZSN7zwz5gJiFhZJz49Uzk7mEBHIceWmbFmYx7Hf7E= @@ -660,6 +670,8 @@ github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nbd-wtf/go-nostr v0.16.12 h1:+MpIxOCJo8wnKzwgVecSjG62bs36+MrY7SXCIOSXMrU= github.com/nbd-wtf/go-nostr v0.16.12/go.mod h1:yvUvLkncMo1zNNytdL1KXnWWc46N2uUQDsBmjHgHYC0= +github.com/nbd-wtf/go-nostr v0.29.3 h1:hgc5srr2LI+ApFlsAYCHXyj3lC4nlTbSjYVSce0/ZSk= +github.com/nbd-wtf/go-nostr v0.29.3/go.mod h1:tiKJY6fWYSujbTQb201Y+IQ3l4szqYVt+fsTnsm7FCk= github.com/nbd-wtf/ln-decodepay v1.5.1 h1:i/SMR94AXIL21KxE/CyWLg/1kKUOVfxHD4QJswaNRDc= github.com/nbd-wtf/ln-decodepay v1.5.1/go.mod h1:xzBXPaCj/7oRRaui+iYSIxy5LYUjoPfAyAGq2WCyNKk= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= @@ -724,6 +736,8 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/puzpuzpuz/xsync/v3 v3.0.2 h1:3yESHrRFYr6xzkz61LLkvNiPFXxJEAABanTQpKbAaew= +github.com/puzpuzpuz/xsync/v3 v3.0.2/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -947,6 +961,8 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 h1:5llv2sWeaMSnA3w2kS57ouQQ4pudlXrR0dCgw51QK9o= +golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1114,6 +1130,8 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= diff --git a/nostr.go b/nostr.go index 5c87fd4..b0721e1 100644 --- a/nostr.go +++ b/nostr.go @@ -36,6 +36,34 @@ type NostrEvent struct { Sig string `json:"sig"` } +type ProfileMetadata struct { + Name string `json:"name,omitempty"` + DisplayName string `json:"display_name,omitempty"` + About string `json:"about,omitempty"` + Website string `json:"website,omitempty"` + Picture string `json:"picture,omitempty"` + Banner string `json:"banner,omitempty"` + NIP05 string `json:"nip05,omitempty"` + LUD16 string `json:"lud16,omitempty"` +} + +func ParseMetadata(event nostr.Event) (*ProfileMetadata, error) { + if event.Kind != 0 { + return nil, fmt.Errorf("event %s is kind %d, not 0", event.ID, event.Kind) + } + + var meta ProfileMetadata + if err := json.Unmarshal([]byte(event.Content), &meta); err != nil { + cont := event.Content + if len(cont) > 100 { + cont = cont[0:99] + } + return nil, fmt.Errorf("failed to parse metadata (%s) from event %s: %w", cont, event.ID, err) + } + + return &meta, nil +} + var nip57Receipt nostr.Event var zapEventSerializedStr string var nip57ReceiptRelays []string @@ -108,7 +136,7 @@ func sendMessage(receiverKey string, message string) { event := nostr.Event{ PubKey: pubkey, - CreatedAt: time.Now(), + CreatedAt: nostr.Now(), Kind: nostr.KindEncryptedDirectMessage, Tags: tags, Content: encryptedMessage, @@ -168,8 +196,8 @@ func handleNip05(w http.ResponseWriter, r *http.Request) { } } -func GetNostrProfileMetaData(npub string, index int) (nostr.ProfileMetadata, error) { - var metadata *nostr.ProfileMetadata +func GetNostrProfileMetaData(npub string, index int) (ProfileMetadata, error) { + var metadata *ProfileMetadata // Prepend special purpose relay wss://purplepag.es to the list of relays var relays = append([]string{"wss://purplepag.es"}, Relays...) @@ -217,7 +245,7 @@ func GetNostrProfileMetaData(npub string, index int) (nostr.ProfileMetadata, err relay.Close() if len(evs) > 0 { - metadata, err = nostr.ParseMetadata(evs[0]) + metadata, err = ParseMetadata(evs[0]) log.Printf("Success getting Nostr Profile") break } else { @@ -228,7 +256,7 @@ func GetNostrProfileMetaData(npub string, index int) (nostr.ProfileMetadata, err } if metadata == nil { - return nostr.ProfileMetadata{}, fmt.Errorf("Couldn't download Profile for given relays") + return ProfileMetadata{}, fmt.Errorf("Couldn't download Profile for given relays") } return *metadata, nil } @@ -329,7 +357,6 @@ func publishNostrEvent(ev nostr.Event, relays []string) { var err error var conn *nostr.Relay - var status nostr.Status maxRetries := 3 retryDelay := 1 * time.Second @@ -349,7 +376,7 @@ func publishNostrEvent(ev nostr.Event, relays []string) { // Set a timeout for publishing to the relay pubCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - status, err = conn.Publish(pubCtx, ev) + err = conn.Publish(pubCtx, ev) cancel() if err != nil { @@ -358,7 +385,7 @@ func publishNostrEvent(ev nostr.Event, relays []string) { retryDelay *= 2 continue } else { - log.Printf("[NOSTR] published to %s: %s", url, status.String()) + log.Printf("[NOSTR] published to %s: %s", url, "sent") break } } @@ -396,7 +423,7 @@ func CreateNostrReceipt(zapEvent nostr.Event, invoice string) (nostr.Event, erro nip57Receipt := nostr.Event{ PubKey: pub, - CreatedAt: time.Now(), + CreatedAt: nostr.Now(), Kind: 9735, Tags: nostr.Tags{ *zapEvent.Tags.GetFirst([]string{"p"}), diff --git a/waitforinvoice.go b/waitforinvoice.go index 407f194..1405808 100644 --- a/waitforinvoice.go +++ b/waitforinvoice.go @@ -7,6 +7,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "io" "io/ioutil" "net/http" "net/url" @@ -86,7 +87,7 @@ func WaitForInvoicePaid(payvalues LNURLPayValuesCustom, params *Params) { Client.Transport = specialTransport var maxiterations = 100 - ticker := time.NewTicker(1 * time.Second) + ticker := time.NewTicker(100 * time.Millisecond) quit := make(chan struct{}) for { @@ -128,26 +129,44 @@ func WaitForInvoicePaid(payvalues LNURLPayValuesCustom, params *Params) { case LNBitsParams: - response, err := http.Get(backend.Host + "/api/v1/payments/" + bolt11.PaymentHash) + client := &http.Client{} + url := backend.Host + "/api/v1/payments/" + bolt11.PaymentHash + req, _ := http.NewRequest("GET", url, nil) + req.Header.Set("X-Api-Key", backend.Key) + req.Header.Set("Content-type", "application/json") + + response, err := client.Do(req) + + //response, err := http.Get(backend.Host + "/api/v1/payments/" + bolt11.PaymentHash) if err != nil { fmt.Print(err.Error()) return } - responseData, err := ioutil.ReadAll(response.Body) + + responseData, err := io.ReadAll(response.Body) + if err != nil { fmt.Print(err.Error()) return } var jsonMap map[string]interface{} err = json.Unmarshal([]byte(string(responseData)), &jsonMap) + if err != nil { fmt.Print(err.Error()) return } - if jsonMap["paid"].(bool) { + if jsonMap["paid"].(bool) == true { + payvalues.PaidAt = time.Now() + fmt.Print("LnBits says paid..\n") + fmt.Print("Payment hash:" + bolt11.PaymentHash + "\n") + fmt.Println(string(responseData)) payvalues.Paid = true + + } else { + fmt.Print("Checking invoice..\n") } case LNPayParams: @@ -167,10 +186,10 @@ func WaitForInvoicePaid(payvalues LNURLPayValuesCustom, params *Params) { } //If invoice is paid and DescriptionHash matches Nip57 DescriptionHash, publish Zap Nostr Event. This is rather a sanity check. - if payvalues.Paid { + if payvalues.Paid == true { var amount = bolt11.MSatoshi / 1000 - if *&payvalues.Nip57Receipt.Tags != nil { + if payvalues.Nip57Receipt.Tags != nil { var descriptionTag = *payvalues.Nip57Receipt.Tags.GetFirst([]string{"description"}) if bolt11.DescriptionHash == Nip57DescriptionHash(descriptionTag.Value()) { @@ -195,6 +214,7 @@ func WaitForInvoicePaid(payvalues LNURLPayValuesCustom, params *Params) { go sendMessage(params.Npub, "Received Profile Zap from "+payvalues.Sender+" with amount: "+strconv.FormatInt(amount, 10)+" "+satsr+" ⚡️.") } } + //payvalues.Nip57Receipt.String() log.Debug().Str("ZAPPED ⚡️", "Published zap on Nostr").Msg("Nostr") close(quit) return