mirror of
https://github.com/believethehype/nostdress.git
synced 2026-07-16 03:38:10 -07:00
Cleanup, Threading, minor fixes
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/fiatjaf/go-lnurl"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/nbd-wtf/go-nostr"
|
||||
decodepay "github.com/nbd-wtf/ln-decodepay"
|
||||
)
|
||||
|
||||
var allowNostr bool = false
|
||||
@@ -34,6 +35,19 @@ type LNURLPayParamsCustom struct {
|
||||
Metadata lnurl.Metadata `json:"-"`
|
||||
}
|
||||
|
||||
type LNURLPayValuesCustom struct {
|
||||
lnurl.LNURLResponse
|
||||
SuccessAction *lnurl.SuccessAction `json:"successAction"`
|
||||
Routes interface{} `json:"routes"` // ignored
|
||||
PR string `json:"pr"`
|
||||
Disposable *bool `json:"disposable,omitempty"`
|
||||
|
||||
ParsedInvoice decodepay.Bolt11 `json:"-"`
|
||||
PayerDataJSON string `json:"-"`
|
||||
nip57Receipt nostr.Event `json:"nip57Receipt"`
|
||||
nip57ReceiptRelays []string `json:"nip57ReceiptRelays"`
|
||||
}
|
||||
|
||||
func handleLNURL(w http.ResponseWriter, r *http.Request) {
|
||||
var err error
|
||||
var response interface{}
|
||||
@@ -160,7 +174,8 @@ func handleLNURL(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
//we outsource the second part in a function, we should do this for the first one too.
|
||||
response, err = serveLNURLpSecond(w, params, username, msat, comment, payerData, zapEvent)
|
||||
var payvalues = response.(*lnurl.LNURLPayValues)
|
||||
var payvaluescustom = response.(LNURLPayValuesCustom)
|
||||
//var payvalues = response.(*lnurl.LNURLPayValues)
|
||||
if err != nil {
|
||||
if response != nil {
|
||||
// there is a valid error response
|
||||
@@ -168,29 +183,36 @@ func handleLNURL(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
return
|
||||
}
|
||||
err = json.NewEncoder(w).Encode(response)
|
||||
|
||||
json.NewEncoder(w).Encode(lnurl.LNURLPayValues{
|
||||
LNURLResponse: payvaluescustom.LNURLResponse,
|
||||
PR: payvaluescustom.PR,
|
||||
Routes: payvaluescustom.Routes,
|
||||
SuccessAction: payvaluescustom.SuccessAction,
|
||||
})
|
||||
|
||||
//err = json.NewEncoder(w).Encode(payvalues)
|
||||
if err != nil {
|
||||
json.NewEncoder(w).Encode(response)
|
||||
return
|
||||
}
|
||||
|
||||
if allowNostr {
|
||||
WaitForInvoicePaid(payvalues, params)
|
||||
go WaitForInvoicePaid(payvaluescustom, params)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func serveLNURLpSecond(w http.ResponseWriter, params *Params, username string, amount_msat int, comment string, payerData lnurl.PayerDataValues, zapEvent nostr.Event) (*lnurl.LNURLPayValues, error) {
|
||||
func serveLNURLpSecond(w http.ResponseWriter, params *Params, username string, amount_msat int, comment string, payerData lnurl.PayerDataValues, zapEvent nostr.Event) (LNURLPayValuesCustom, error) {
|
||||
log.Debug().Any("Serving invoice for user %s", username)
|
||||
if amount_msat < minSendable || amount_msat > maxSendable {
|
||||
// amount is not ok
|
||||
return &lnurl.LNURLPayValues{
|
||||
return LNURLPayValuesCustom{
|
||||
LNURLResponse: lnurl.LNURLResponse{
|
||||
Status: "Error",
|
||||
Reason: fmt.Sprintf("Amount out of bounds (min: %d sat, max: %d sat).", minSendable/1000, maxSendable/1000)},
|
||||
}, fmt.Errorf("amount out of bounds")
|
||||
}
|
||||
var resp *lnurl.LNURLPayValues
|
||||
|
||||
// NIP57 ZAPs
|
||||
// for nip57 use the nostr event as the descriptionHash
|
||||
@@ -202,7 +224,7 @@ func serveLNURLpSecond(w http.ResponseWriter, params *Params, username string, a
|
||||
zapEventSerializedStr = fmt.Sprintf("%s", zapEventSerialized)
|
||||
if err != nil {
|
||||
//log.Println(err)
|
||||
return &lnurl.LNURLPayValues{
|
||||
return LNURLPayValuesCustom{
|
||||
LNURLResponse: lnurl.LNURLResponse{
|
||||
Status: "Error",
|
||||
Reason: "Couldn't serialize zap event."},
|
||||
@@ -228,15 +250,16 @@ func serveLNURLpSecond(w http.ResponseWriter, params *Params, username string, a
|
||||
params.zapEventSerializedStr = ""
|
||||
}
|
||||
|
||||
var response LNURLPayValuesCustom
|
||||
invoice, err := makeInvoice(params, amount_msat, nil)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Couldn't create invoice: %v", err.Error())
|
||||
resp = &lnurl.LNURLPayValues{
|
||||
response = LNURLPayValuesCustom{
|
||||
LNURLResponse: lnurl.LNURLResponse{
|
||||
Status: "Error",
|
||||
Reason: "Couldn't create invoice."},
|
||||
}
|
||||
return resp, err
|
||||
return response, err
|
||||
}
|
||||
// nip57 - we need to store the newly created invoice in the zap receipt
|
||||
if zapEvent.Sig != "" {
|
||||
@@ -258,11 +281,13 @@ func serveLNURLpSecond(w http.ResponseWriter, params *Params, username string, a
|
||||
nip57Receipt.Sign(pk)
|
||||
}
|
||||
|
||||
return &lnurl.LNURLPayValues{
|
||||
LNURLResponse: lnurl.LNURLResponse{Status: "OK"},
|
||||
PR: invoice,
|
||||
Routes: make([]struct{}, 0),
|
||||
SuccessAction: &lnurl.SuccessAction{Message: "Payment Received!", Tag: "message"},
|
||||
return LNURLPayValuesCustom{
|
||||
LNURLResponse: lnurl.LNURLResponse{Status: "OK"},
|
||||
PR: invoice,
|
||||
Routes: make([]struct{}, 0),
|
||||
SuccessAction: &lnurl.SuccessAction{Message: "Payment Received!", Tag: "message"},
|
||||
nip57Receipt: nip57Receipt,
|
||||
nip57ReceiptRelays: nip57ReceiptRelays,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
+35
-34
@@ -14,7 +14,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fiatjaf/go-lnurl"
|
||||
decodepay "github.com/nbd-wtf/ln-decodepay"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
@@ -45,7 +44,7 @@ type CommandoParams struct {
|
||||
}
|
||||
|
||||
func (l CommandoParams) getCert() string { return "" }
|
||||
func (l CommandoParams) isTor() bool { return strings.Index(l.Host, ".onion") != -1 }
|
||||
func (l CommandoParams) isTor() bool { return strings.Contains(l.Host, ".onion") }
|
||||
|
||||
type SparkoParams struct {
|
||||
Cert string
|
||||
@@ -54,7 +53,7 @@ type SparkoParams struct {
|
||||
}
|
||||
|
||||
func (l SparkoParams) getCert() string { return l.Cert }
|
||||
func (l SparkoParams) isTor() bool { return strings.Index(l.Host, ".onion") != -1 }
|
||||
func (l SparkoParams) isTor() bool { return strings.Contains(l.Host, ".onion") }
|
||||
|
||||
type LNDParams struct {
|
||||
Cert string
|
||||
@@ -63,7 +62,7 @@ type LNDParams struct {
|
||||
}
|
||||
|
||||
func (l LNDParams) getCert() string { return l.Cert }
|
||||
func (l LNDParams) isTor() bool { return strings.Index(l.Host, ".onion") != -1 }
|
||||
func (l LNDParams) isTor() bool { return strings.Contains(l.Host, ".onion") }
|
||||
|
||||
type LNBitsParams struct {
|
||||
Cert string
|
||||
@@ -72,7 +71,7 @@ type LNBitsParams struct {
|
||||
}
|
||||
|
||||
func (l LNBitsParams) getCert() string { return l.Cert }
|
||||
func (l LNBitsParams) isTor() bool { return strings.Index(l.Host, ".onion") != -1 }
|
||||
func (l LNBitsParams) isTor() bool { return strings.Contains(l.Host, ".onion") }
|
||||
|
||||
type LNPayParams struct {
|
||||
PublicAccessKey string
|
||||
@@ -89,7 +88,7 @@ type EclairParams struct {
|
||||
}
|
||||
|
||||
func (l EclairParams) getCert() string { return l.Cert }
|
||||
func (l EclairParams) isTor() bool { return strings.Index(l.Host, ".onion") != -1 }
|
||||
func (l EclairParams) isTor() bool { return strings.Contains(l.Host, ".onion") }
|
||||
|
||||
type StrikeParams struct {
|
||||
Key string
|
||||
@@ -105,7 +104,7 @@ type BackendParams interface {
|
||||
isTor() bool
|
||||
}
|
||||
|
||||
func WaitForInvoicePaid(payvalues *lnurl.LNURLPayValues, params *Params) {
|
||||
func WaitForInvoicePaid(payvalues LNURLPayValuesCustom, params *Params) {
|
||||
//Check for a minute if invoice is paid
|
||||
//Do we have an easier way to do this? How does it work for other backends than lnbits.
|
||||
go func() {
|
||||
@@ -182,9 +181,11 @@ func WaitForInvoicePaid(payvalues *lnurl.LNURLPayValues, params *Params) {
|
||||
case <-ticker.C:
|
||||
|
||||
bolt11, _ := decodepay.Decodepay(payvalues.PR)
|
||||
var isPaid bool = false
|
||||
|
||||
switch backend := mip.Backend.(type) {
|
||||
case SparkoParams:
|
||||
//TODO
|
||||
case LNDParams:
|
||||
req, err := http.NewRequest("GET",
|
||||
backend.Host+"/v1/invoice/"+bolt11.PaymentHash,
|
||||
@@ -196,7 +197,6 @@ func WaitForInvoicePaid(payvalues *lnurl.LNURLPayValues, params *Params) {
|
||||
if b, err := base64.StdEncoding.DecodeString(backend.Macaroon); err == nil {
|
||||
backend.Macaroon = hex.EncodeToString(b)
|
||||
}
|
||||
|
||||
req.Header.Set("Grpc-Metadata-macaroon", backend.Macaroon)
|
||||
resp, err := Client.Do(req)
|
||||
if err != nil {
|
||||
@@ -204,14 +204,6 @@ func WaitForInvoicePaid(payvalues *lnurl.LNURLPayValues, params *Params) {
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode >= 300 {
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
text := string(body)
|
||||
if len(text) > 300 {
|
||||
text = text[:300]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
@@ -219,11 +211,8 @@ func WaitForInvoicePaid(payvalues *lnurl.LNURLPayValues, params *Params) {
|
||||
return
|
||||
}
|
||||
|
||||
if gjson.ParseBytes(b).Get("settled").String() == "true" && bolt11.DescriptionHash == Nip57DescriptionHash(zapEventSerializedStr) {
|
||||
log.Debug().Str("ZAP", "Published on Nostr").Msg("zapped")
|
||||
publishNostrEvent(nip57Receipt, nip57ReceiptRelays)
|
||||
close(quit)
|
||||
return
|
||||
if gjson.ParseBytes(b).Get("settled").String() == "true" {
|
||||
isPaid = true
|
||||
}
|
||||
|
||||
case LNBitsParams:
|
||||
@@ -240,25 +229,37 @@ func WaitForInvoicePaid(payvalues *lnurl.LNURLPayValues, params *Params) {
|
||||
}
|
||||
var jsonMap map[string]interface{}
|
||||
json.Unmarshal([]byte(string(responseData)), &jsonMap)
|
||||
//If invoice is paid and DescriptionHash matches Nip57 DescriptionHash, publish Zap Nostr Event
|
||||
if jsonMap["paid"].(bool) && bolt11.DescriptionHash == Nip57DescriptionHash(zapEventSerializedStr) {
|
||||
|
||||
if jsonMap["paid"].(bool) {
|
||||
isPaid = true
|
||||
}
|
||||
|
||||
case LNPayParams:
|
||||
//TODO
|
||||
case EclairParams:
|
||||
//TODO
|
||||
case CommandoParams:
|
||||
//TODO
|
||||
|
||||
}
|
||||
//Timeout waiting for payment after maxiterations
|
||||
if maxiterations == 0 {
|
||||
log.Debug().Str("NIP57", bolt11.PaymentHash).Msg("Timed out")
|
||||
close(quit)
|
||||
}
|
||||
|
||||
//If invoice is paid and DescriptionHash matches Nip57 DescriptionHash, publish Zap Nostr Event. This is rather a sanity check.
|
||||
if isPaid {
|
||||
var descriptionTag = *payvalues.nip57Receipt.Tags.GetFirst([]string{"description"})
|
||||
if bolt11.DescriptionHash == Nip57DescriptionHash(descriptionTag.Value()) {
|
||||
log.Debug().Str("ZAP", "Published on Nostr").Msg("zapped")
|
||||
publishNostrEvent(nip57Receipt, nip57ReceiptRelays)
|
||||
publishNostrEvent(payvalues.nip57Receipt, payvalues.nip57ReceiptRelays)
|
||||
close(quit)
|
||||
return
|
||||
}
|
||||
|
||||
case LNPayParams:
|
||||
case EclairParams:
|
||||
case CommandoParams:
|
||||
|
||||
maxiterations--
|
||||
}
|
||||
|
||||
if maxiterations == 0 {
|
||||
log.Debug().Str("ZAP", bolt11.PaymentHash).Msg("Timed out")
|
||||
close(quit)
|
||||
}
|
||||
maxiterations--
|
||||
case <-quit:
|
||||
ticker.Stop()
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user