diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 00000000..51e516c1 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: gomod + directory: / + schedule: + interval: weekly \ No newline at end of file diff --git a/alby.go b/alby.go index 47413833..3d4064d3 100644 --- a/alby.go +++ b/alby.go @@ -104,7 +104,7 @@ func (svc *AlbyOAuthService) MakeInvoice(ctx context.Context, senderPubkey strin "description": description, "descriptionHash": descriptionHash, "expiry": expiry, - }).Errorf("amount must be 1000 msat or greater"); + }).Errorf("amount must be 1000 msat or greater") return "", "", errors.New("amount must be 1000 msat or greater") } @@ -199,17 +199,17 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str }).Error if err != nil { svc.Logger.WithFields(logrus.Fields{ - "senderPubkey": senderPubkey, - "paymentHash": paymentHash, + "senderPubkey": senderPubkey, + "paymentHash": paymentHash, }).Errorf("App not found: %v", err) return "", false, err } svc.Logger.WithFields(logrus.Fields{ - "senderPubkey": senderPubkey, - "paymentHash": paymentHash, - "appId": app.ID, - "userId": app.User.ID, + "senderPubkey": senderPubkey, + "paymentHash": paymentHash, + "appId": app.ID, + "userId": app.User.ID, }).Info("Processing lookup invoice request") tok, err := svc.FetchUserToken(ctx, app) if err != nil { @@ -232,14 +232,14 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str resp, err := client.Do(req) if err != nil { svc.Logger.WithFields(logrus.Fields{ - "senderPubkey": senderPubkey, - "paymentHash": paymentHash, - "appId": app.ID, - "userId": app.User.ID, + "senderPubkey": senderPubkey, + "paymentHash": paymentHash, + "appId": app.ID, + "userId": app.User.ID, }).Errorf("Failed to lookup invoice: %v", err) return "", false, err } - + if resp.StatusCode < 300 { responsePayload := &LookupInvoiceResponse{} err = json.NewDecoder(resp.Body).Decode(responsePayload) @@ -247,12 +247,12 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str return "", false, err } svc.Logger.WithFields(logrus.Fields{ - "senderPubkey": senderPubkey, - "paymentHash": paymentHash, - "appId": app.ID, - "userId": app.User.ID, - "paymentRequest": responsePayload.PaymentRequest, - "settled": responsePayload.Settled, + "senderPubkey": senderPubkey, + "paymentHash": paymentHash, + "appId": app.ID, + "userId": app.User.ID, + "paymentRequest": responsePayload.PaymentRequest, + "settled": responsePayload.Settled, }).Info("Lookup invoice successful") return responsePayload.PaymentRequest, responsePayload.Settled, nil } @@ -260,10 +260,10 @@ func (svc *AlbyOAuthService) LookupInvoice(ctx context.Context, senderPubkey str errorPayload := &ErrorResponse{} err = json.NewDecoder(resp.Body).Decode(errorPayload) svc.Logger.WithFields(logrus.Fields{ - "senderPubkey": senderPubkey, - "paymentHash": paymentHash, - "appId": app.ID, - "userId": app.User.ID, + "senderPubkey": senderPubkey, + "paymentHash": paymentHash, + "appId": app.ID, + "userId": app.User.ID, "APIHttpStatus": resp.StatusCode, }).Errorf("Lookup invoice failed %s", string(errorPayload.Message)) return "", false, errors.New(errorPayload.Message) diff --git a/echo_handlers.go b/echo_handlers.go index 1ec4eecc..fd1bce83 100644 --- a/echo_handlers.go +++ b/echo_handlers.go @@ -241,8 +241,8 @@ func getEndOfBudgetString(endOfBudget time.Time) (result string) { func (svc *Service) AppsNewHandler(c echo.Context) error { appName := c.QueryParam("name") - if (appName == "") { - // c - for client (deprecated) + if appName == "" { + // c - for client (deprecated) appName = c.QueryParam("c") } pubkey := c.QueryParam("pubkey") @@ -297,7 +297,7 @@ func (svc *Service) AppsNewHandler(c echo.Context) error { for k, v := range nip47MethodDescriptions { requestMethodHelper[k] = &RequestMethodHelper{ Description: v, - Icon: nip47MethodIcons[k], + Icon: nip47MethodIcons[k], } } @@ -354,7 +354,7 @@ func (svc *Service) AppsCreateHandler(c echo.Context) error { expiresAt := time.Time{} if c.FormValue("ExpiresAt") != "" { expiresAt, err = time.Parse(time.RFC3339, c.FormValue("ExpiresAt")) - if (err != nil) { + if err != nil { return fmt.Errorf("Invalid ExpiresAt: %v", err) } } @@ -405,16 +405,16 @@ func (svc *Service) AppsCreateHandler(c echo.Context) error { return c.Redirect(302, "/apps") } - publicRelayUrl := svc.cfg.PublicRelay; - if (publicRelayUrl == "") { - publicRelayUrl = svc.cfg.Relay; + publicRelayUrl := svc.cfg.PublicRelay + if publicRelayUrl == "" { + publicRelayUrl = svc.cfg.Relay } if c.FormValue("returnTo") != "" { returnToUrl, err := url.Parse(c.FormValue("returnTo")) if err == nil { query := returnToUrl.Query() - query.Add("relay", publicRelayUrl); + query.Add("relay", publicRelayUrl) query.Add("pubkey", svc.cfg.IdentityPubkey) if user.LightningAddress != "" { query.Add("lud16", user.LightningAddress) diff --git a/go.mod b/go.mod index e78b76d2..665369b7 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/gorilla/sessions v1.2.1 github.com/labstack/echo-contrib v0.14.1 github.com/labstack/echo/v4 v4.10.2 - github.com/nbd-wtf/go-nostr v0.13.2 + github.com/nbd-wtf/go-nostr v0.25.5 github.com/nbd-wtf/ln-decodepay v1.11.1 github.com/stretchr/testify v1.8.2 golang.org/x/oauth2 v0.4.0 @@ -49,7 +49,7 @@ require ( github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/decred/dcrd/lru v1.1.1 // indirect - github.com/dgraph-io/ristretto v0.1.0 // indirect + github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvyukov/go-fuzz v0.0.0-20220726122315-1d375ef9f9f6 // indirect github.com/fergusstrange/embedded-postgres v1.19.0 // indirect @@ -59,6 +59,9 @@ require ( github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-macaroon-bakery/macaroonpb v1.0.0 // indirect + 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/gofrs/uuid v4.2.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect @@ -117,6 +120,7 @@ require ( github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.40.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect + github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230126093431-47fa9a501578 // indirect github.com/rogpeppe/fastuuid v1.2.0 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect @@ -125,6 +129,9 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/tidwall/gjson v1.14.4 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.0 // indirect github.com/tinylib/msgp v1.1.6 // indirect github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect @@ -182,8 +189,8 @@ require ( github.com/SaveTheRbtz/generic-sync-map-go v0.0.0-20220414055132-a37292614db8 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect - github.com/decred/dcrd/crypto/blake256 v1.0.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect + github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/glebarez/sqlite v1.5.0 github.com/gorilla/websocket v1.5.0 // indirect github.com/jackc/pgx/v5 v5.4.3 @@ -193,6 +200,6 @@ require ( github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/sirupsen/logrus v1.9.0 github.com/valyala/fastjson v1.6.3 // indirect - golang.org/x/exp v0.0.0-20221106115401-f9659909a136 // indirect + golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect gorm.io/driver/postgres v1.5.2 ) diff --git a/go.sum b/go.sum index b7f055fe..a26ad40e 100644 --- a/go.sum +++ b/go.sum @@ -196,15 +196,21 @@ github.com/davrux/echo-logrus/v4 v4.0.3 h1:V5bM43A+3PNdpiGC2TS8HKAeaUWQph/j8utG7 github.com/davrux/echo-logrus/v4 v4.0.3/go.mod h1:+1y03d0joOKfwnPN4GSFhh/ViG3newZtYZfAPB6yf+g= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/decred/dcrd/lru v1.1.1 h1:kWFDaW0OWx6AD6Ki342c+JPmHbiVdE6rK81pT3fuo/Y= github.com/decred/dcrd/lru v1.1.1/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/denisenkom/go-mssqldb v0.11.0 h1:9rHa233rhdOyrz2GcP9NM+gi2psgJZ4GWDpL/7ND8HI= github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= +github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8= +github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= @@ -270,6 +276,12 @@ github.com/go-macaroon-bakery/macaroonpb v1.0.0/go.mod h1:UzrGOcbiwTXISFP2XDLDPj github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +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.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og= +github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +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/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= @@ -625,6 +637,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nbd-wtf/go-nostr v0.13.2 h1:w/TgXbkWqkZQsPRZffPZpvR/uskOSSUCGYhtW6I3xPI= github.com/nbd-wtf/go-nostr v0.13.2/go.mod h1:qFFTIxh15H5GGN0WsBI/P73DteqsevnhSEW/yk8nEf4= +github.com/nbd-wtf/go-nostr v0.25.5 h1:CqjicJePCLwPjBNo9N98UfYFnUGrxc7Ts8zwIZgzzwg= +github.com/nbd-wtf/go-nostr v0.25.5/go.mod h1:bkffJI+x914sPQWum9ZRUn66D7NpDnAoWo1yICvj3/0= github.com/nbd-wtf/ln-decodepay v1.11.1 h1:MPiT4a4qZ2cKY27Aj0dI8sLFrLz5Ycu72Z3EG1HfPjk= github.com/nbd-wtf/ln-decodepay v1.11.1/go.mod h1:xzBXPaCj/7oRRaui+iYSIxy5LYUjoPfAyAGq2WCyNKk= github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= @@ -691,6 +705,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/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= +github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20230126093431-47fa9a501578 h1:VstopitMQi3hZP0fzvnsLmzXZdQGc4bEcgu24cp+d4M= github.com/remyoudompheng/bigfft v0.0.0-20230126093431-47fa9a501578/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= @@ -755,6 +771,12 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= +github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tinylib/msgp v1.1.6 h1:i+SbKraHhnrf9M5MYmvQhFnbLhAXSDWF8WWsuyRdocw= github.com/tinylib/msgp v1.1.6/go.mod h1:75BAfg2hauQhs3qedfdDZmWAPcFMAvJE5b9rGOMufyw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -914,6 +936,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20221106115401-f9659909a136 h1:Fq7F/w7MAa1KJ5bt2aJ62ihqp9HDcRuyILskkpIAurw= golang.org/x/exp v0.0.0-20221106115401-f9659909a136/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= @@ -1080,6 +1104,8 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc 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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.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= diff --git a/handle_balance_request.go b/handle_balance_request.go index 28b274ac..036fddbc 100644 --- a/handle_balance_request.go +++ b/handle_balance_request.go @@ -37,9 +37,9 @@ func (svc *Service) HandleGetBalanceEvent(ctx context.Context, request *Nip47Req return svc.createResponse(event, Nip47Response{ ResultType: NIP_47_GET_BALANCE_METHOD, Error: &Nip47Error{ - Code: code, - Message: message, - }}, ss) + Code: code, + Message: message, + }}, ss) } svc.Logger.WithFields(logrus.Fields{ diff --git a/handle_lookup_invoice_request.go b/handle_lookup_invoice_request.go index 3141d33b..8db69f54 100644 --- a/handle_lookup_invoice_request.go +++ b/handle_lookup_invoice_request.go @@ -36,9 +36,9 @@ func (svc *Service) HandleLookupInvoiceEvent(ctx context.Context, request *Nip47 return svc.createResponse(event, Nip47Response{ ResultType: NIP_47_LOOKUP_INVOICE_METHOD, Error: &Nip47Error{ - Code: code, - Message: message, - }}, ss) + Code: code, + Message: message, + }}, ss) } // TODO: move to a shared generic function @@ -54,23 +54,23 @@ func (svc *Service) HandleLookupInvoiceEvent(ctx context.Context, request *Nip47 } svc.Logger.WithFields(logrus.Fields{ - "eventId": event.ID, - "eventKind": event.Kind, - "appId": app.ID, - "invoice": lookupInvoiceParams.Invoice, - "paymentHash": lookupInvoiceParams.PaymentHash, + "eventId": event.ID, + "eventKind": event.Kind, + "appId": app.ID, + "invoice": lookupInvoiceParams.Invoice, + "paymentHash": lookupInvoiceParams.PaymentHash, }).Info("Looking up invoice") paymentHash := lookupInvoiceParams.PaymentHash - if (paymentHash == "") { + if paymentHash == "" { paymentRequest, err := decodepay.Decodepay(lookupInvoiceParams.Invoice) if err != nil { svc.Logger.WithFields(logrus.Fields{ "eventId": event.ID, "eventKind": event.Kind, "appId": app.ID, - "invoice": lookupInvoiceParams.Invoice, + "invoice": lookupInvoiceParams.Invoice, }).Errorf("Failed to decode bolt11 invoice: %v", err) return svc.createResponse(event, Nip47Response{ @@ -87,11 +87,11 @@ func (svc *Service) HandleLookupInvoiceEvent(ctx context.Context, request *Nip47 invoice, paid, err := svc.lnClient.LookupInvoice(ctx, event.PubKey, paymentHash) if err != nil { svc.Logger.WithFields(logrus.Fields{ - "eventId": event.ID, - "eventKind": event.Kind, - "appId": app.ID, - "invoice": lookupInvoiceParams.Invoice, - "paymentHash": lookupInvoiceParams.PaymentHash, + "eventId": event.ID, + "eventKind": event.Kind, + "appId": app.ID, + "invoice": lookupInvoiceParams.Invoice, + "paymentHash": lookupInvoiceParams.PaymentHash, }).Infof("Failed to lookup invoice: %v", err) nostrEvent.State = NOSTR_EVENT_STATE_HANDLER_ERROR svc.db.Save(&nostrEvent) @@ -104,16 +104,16 @@ func (svc *Service) HandleLookupInvoiceEvent(ctx context.Context, request *Nip47 }, ss) } - responsePayload := &Nip47LookupInvoiceResponse { + responsePayload := &Nip47LookupInvoiceResponse{ Invoice: invoice, - Paid: paid, + Paid: paid, } nostrEvent.State = NOSTR_EVENT_STATE_HANDLER_EXECUTED svc.db.Save(&nostrEvent) return svc.createResponse(event, Nip47Response{ ResultType: NIP_47_LOOKUP_INVOICE_METHOD, - Result: responsePayload, + Result: responsePayload, }, - ss) + ss) } diff --git a/handle_make_invoice_request.go b/handle_make_invoice_request.go index 68b04a6e..7e3d0733 100644 --- a/handle_make_invoice_request.go +++ b/handle_make_invoice_request.go @@ -12,7 +12,7 @@ import ( ) func (svc *Service) HandleMakeInvoiceEvent(ctx context.Context, request *Nip47Request, event *nostr.Event, app App, ss []byte) (result *nostr.Event, err error) { - + // TODO: move to a shared function nostrEvent := NostrEvent{App: app, NostrId: event.ID, Content: event.Content, State: "received"} err = svc.db.Create(&nostrEvent).Error @@ -38,9 +38,9 @@ func (svc *Service) HandleMakeInvoiceEvent(ctx context.Context, request *Nip47Re return svc.createResponse(event, Nip47Response{ ResultType: NIP_47_MAKE_INVOICE_METHOD, Error: &Nip47Error{ - Code: code, - Message: message, - }}, ss) + Code: code, + Message: message, + }}, ss) } // TODO: move to a shared generic function @@ -81,8 +81,6 @@ func (svc *Service) HandleMakeInvoiceEvent(ctx context.Context, request *Nip47Re "expiry": makeInvoiceParams.Expiry, }).Info("Making invoice") - - invoice, paymentHash, err := svc.lnClient.MakeInvoice(ctx, event.PubKey, makeInvoiceParams.Amount, makeInvoiceParams.Description, makeInvoiceParams.DescriptionHash, makeInvoiceParams.Expiry) if err != nil { svc.Logger.WithFields(logrus.Fields{ @@ -106,7 +104,7 @@ func (svc *Service) HandleMakeInvoiceEvent(ctx context.Context, request *Nip47Re } responsePayload := &Nip47MakeInvoiceResponse{ - Invoice: invoice, + Invoice: invoice, PaymentHash: paymentHash, } @@ -114,7 +112,7 @@ func (svc *Service) HandleMakeInvoiceEvent(ctx context.Context, request *Nip47Re svc.db.Save(&nostrEvent) return svc.createResponse(event, Nip47Response{ ResultType: NIP_47_MAKE_INVOICE_METHOD, - Result: responsePayload, + Result: responsePayload, }, - ss) + ss) } diff --git a/handle_payment_request.go b/handle_payment_request.go index 5323f282..516e28c5 100644 --- a/handle_payment_request.go +++ b/handle_payment_request.go @@ -66,9 +66,9 @@ func (svc *Service) HandlePayInvoiceEvent(ctx context.Context, request *Nip47Req return svc.createResponse(event, Nip47Response{ ResultType: NIP_47_PAY_INVOICE_METHOD, Error: &Nip47Error{ - Code: code, - Message: message, - }}, ss) + Code: code, + Message: message, + }}, ss) } payment := Payment{App: app, NostrEvent: nostrEvent, PaymentRequest: bolt11, Amount: uint(paymentRequest.MSatoshi / 1000)} diff --git a/lnd.go b/lnd.go index 243676b4..e21e4db6 100644 --- a/lnd.go +++ b/lnd.go @@ -69,7 +69,7 @@ func (svc *LNDService) GetInfo(ctx context.Context, senderPubkey string) (info * func (svc *LNDService) MakeInvoice(ctx context.Context, senderPubkey string, amount int64, description string, descriptionHash string, expiry int64) (invoice string, paymentHash string, err error) { var descriptionHashBytes []byte - + if descriptionHash != "" { descriptionHashBytes, err = hex.DecodeString(descriptionHash) @@ -84,7 +84,7 @@ func (svc *LNDService) MakeInvoice(ctx context.Context, senderPubkey string, amo return "", "", errors.New("Description hash must be 32 bytes hex") } } - + resp, err := svc.client.AddInvoice(ctx, &lnrpc.Invoice{ValueMsat: amount, Memo: description, DescriptionHash: descriptionHashBytes, Expiry: expiry}) if err != nil { return "", "", err @@ -103,12 +103,12 @@ func (svc *LNDService) LookupInvoice(ctx context.Context, senderPubkey string, p return "", false, errors.New("Payment hash must be 32 bytes hex") } - lndInvoice, err := svc.client.LookupInvoice(ctx, &lnrpc.PaymentHash{ RHash: paymentHashBytes }) + lndInvoice, err := svc.client.LookupInvoice(ctx, &lnrpc.PaymentHash{RHash: paymentHashBytes}) if err != nil { return "", false, err } - - return lndInvoice.PaymentRequest, lndInvoice.State == *lnrpc.Invoice_SETTLED.Enum(), nil; + + return lndInvoice.PaymentRequest, lndInvoice.State == *lnrpc.Invoice_SETTLED.Enum(), nil } func (svc *LNDService) SendPaymentSync(ctx context.Context, senderPubkey, payReq string) (preimage string, err error) { diff --git a/main.go b/main.go index 1904741f..151b56b2 100644 --- a/main.go +++ b/main.go @@ -174,7 +174,8 @@ func main() { //connect to the relay svc.Logger.Infof("Connecting to the relay: %s", cfg.Relay) - relay, err := nostr.RelayConnect(ctx, cfg.Relay) + + relay, err := nostr.RelayConnect(ctx, cfg.Relay, nostr.WithNoticeHandler(svc.noticeHandler)) if err != nil { svc.Logger.Fatal(err) } @@ -189,11 +190,14 @@ func main() { //TODO: we can start this loop for multiple relays for { svc.Logger.Info("Subscribing to events") - sub := relay.Subscribe(ctx, svc.createFilters()) + sub, err := relay.Subscribe(ctx, svc.createFilters()) + if err != nil { + svc.Logger.Fatal(err) + } err = svc.StartSubscription(ctx, sub) if err != nil { //err being non-nil means that we have an error on the websocket error channel. In this case we just try to reconnect. - svc.Logger.WithError(err).Error("Got an error from the relay. Reconnecting...") + svc.Logger.WithError(err).Error("Got an error from the relay while listening to subscription. Reconnecting...") relay, err = nostr.RelayConnect(ctx, cfg.Relay) if err != nil { svc.Logger.Fatal(err) @@ -220,3 +224,7 @@ func (svc *Service) createFilters() nostr.Filters { } return []nostr.Filter{filter} } + +func (svc *Service) noticeHandler(notice string) { + svc.Logger.Infof("Received a notice %s", notice) +} diff --git a/service.go b/service.go index 1d081b04..abe5286a 100644 --- a/service.go +++ b/service.go @@ -24,10 +24,10 @@ type Service struct { } var supportedMethods = map[string]bool{ - NIP_47_PAY_INVOICE_METHOD: true, - NIP_47_GET_BALANCE_METHOD: true, - NIP_47_GET_INFO_METHOD: true, - NIP_47_MAKE_INVOICE_METHOD: true, + NIP_47_PAY_INVOICE_METHOD: true, + NIP_47_GET_BALANCE_METHOD: true, + NIP_47_GET_INFO_METHOD: true, + NIP_47_MAKE_INVOICE_METHOD: true, NIP_47_LOOKUP_INVOICE_METHOD: true, } @@ -54,28 +54,38 @@ func (svc *Service) GetUser(c echo.Context) (user *User, err error) { func (svc *Service) StartSubscription(ctx context.Context, sub *nostr.Subscription) error { for { + if sub.Relay.ConnectionError != nil { + return sub.Relay.ConnectionError + } select { - case notice := <-sub.Relay.Notices: - svc.Logger.Infof("Received a notice %s", notice) - case conErr := <-sub.Relay.ConnectionError: - return conErr case <-ctx.Done(): svc.Logger.Info("Exiting subscription.") return nil case <-sub.EndOfStoredEvents: - svc.Logger.Info("Received EOS") + if !svc.ReceivedEOS { + svc.Logger.Info("Received EOS") + } svc.ReceivedEOS = true case event := <-sub.Events: go func() { resp, err := svc.HandleEvent(ctx, event) if err != nil { svc.Logger.WithFields(logrus.Fields{ - "eventId": event.ID, - "eventKind": event.Kind, + "eventId": event.ID, + "eventKind": event.Kind, }).Errorf("Failed to process event: %v", err) } if resp != nil { - status := sub.Relay.Publish(ctx, *resp) + status, err := sub.Relay.Publish(ctx, *resp) + if err != nil { + svc.Logger.WithFields(logrus.Fields{ + "eventId": event.ID, + "status": status, + "replyEventId": resp.ID, + }).Errorf("Failed to publish reply: %v", err) + return + } + nostrEvent := NostrEvent{} result := svc.db.Where("nostr_id = ?", event.ID).First(&nostrEvent) if result.Error != nil { @@ -87,7 +97,7 @@ func (svc *Service) StartSubscription(ctx context.Context, sub *nostr.Subscripti return } nostrEvent.ReplyId = resp.ID - // https://github.com/nbd-wtf/go-nostr/blob/master/relay.go#L321 + if status == nostr.PublishStatusSucceeded { nostrEvent.State = NOSTR_EVENT_STATE_PUBLISH_CONFIRMED nostrEvent.RepliedAt = time.Now() @@ -204,9 +214,9 @@ func (svc *Service) HandleEvent(ctx context.Context, event *nostr.Event) (result return svc.createResponse(event, Nip47Response{ ResultType: nip47Request.Method, Error: &Nip47Error{ - Code: NIP_47_ERROR_NOT_IMPLEMENTED, - Message: fmt.Sprintf("Unknown method: %s", nip47Request.Method), - }}, ss) + Code: NIP_47_ERROR_NOT_IMPLEMENTED, + Message: fmt.Sprintf("Unknown method: %s", nip47Request.Method), + }}, ss) } } @@ -221,7 +231,7 @@ func (svc *Service) createResponse(initialEvent *nostr.Event, content interface{ } resp := &nostr.Event{ PubKey: svc.cfg.IdentityPubkey, - CreatedAt: time.Now(), + CreatedAt: nostr.Now(), Kind: NIP_47_RESPONSE_KIND, Tags: nostr.Tags{[]string{"p", initialEvent.PubKey}, []string{"e", initialEvent.ID}}, Content: msg, @@ -295,15 +305,15 @@ func (svc *Service) PublishNip47Info(ctx context.Context, relay *nostr.Relay) er ev := &nostr.Event{} ev.Kind = NIP_47_INFO_EVENT_KIND ev.Content = NIP_47_CAPABILITIES - ev.CreatedAt = time.Now() + ev.CreatedAt = nostr.Now() ev.PubKey = svc.cfg.IdentityPubkey err := ev.Sign(svc.cfg.NostrSecretKey) if err != nil { return err } - status := relay.Publish(ctx, *ev) - if status != nostr.PublishStatusSucceeded { - return fmt.Errorf("Nostr publish not successful: %s", status) + status, err := relay.Publish(ctx, *ev) + if err != nil || status != nostr.PublishStatusSucceeded { + return fmt.Errorf("Nostr publish not successful: %s error: %s", status, err) } return nil }