forked from fiatjaf/bridgeaddr
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsocket.go
118 lines (101 loc) · 3.13 KB
/
socket.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
import (
"context"
"fmt"
"os"
"strings"
b64 "encoding/base64"
"encoding/hex"
"github.com/gorilla/websocket"
nostr "github.com/nbd-wtf/go-nostr"
"net"
"net/http"
)
type LNDResponse struct {
Result Invoice `json:"result"`
}
type Invoice struct {
Memo string `json:"memo"`
State string `json:"state"`
SettleDate int64 `json:"settle_date,string"`
CreationDate int64 `json:"creation_date,string"`
PaymentRequest string `json:"payment_request"`
PreImage string `json:"r_preimage"`
}
func WaitForZap(r_hash, domain string, zapReq nostr.Event) {
log.Info().Str("r_hash", r_hash).Msg("Waiting for Zap!")
var macaroon string
if v, err := net.LookupTXT("_macaroon." + domain); err == nil && len(v) > 0 {
macaroon = v[0]
}
var host string
if v, err := net.LookupTXT("_host." + domain); err == nil && len(v) > 0 {
host = v[0]
}
privateKey := os.Getenv("NOSTR_KEY")
publicKey, err := nostr.GetPublicKey(privateKey)
if err != nil {
log.Fatal().Err(err).Msg("failed to get public key")
}
r_hash_bytes, err := hex.DecodeString(r_hash)
if err != nil {
log.Fatal().Err(err).Msg("failed to decode r_hash")
}
uEnc := b64.URLEncoding.EncodeToString(r_hash_bytes)
formatted := fmt.Sprintf("%s/v2/invoices/subscribe/%s?method=GET", strings.Replace(host, "https", "wss", 1), uEnc)
authHeader := http.Header{
"Grpc-Metadata-Macaroon": []string{macaroon},
}
conn, _, err := websocket.DefaultDialer.Dial(formatted, authHeader)
if err != nil {
log.Fatal().Err(err).Msg("failed to dial")
}
log.Info().Msg("Waiting for responses on websocket")
for {
var response LNDResponse
err := conn.ReadJSON(&response)
if err != nil {
log.Info().Err(err).Msg("Failed to read JSON")
break
}
fmt.Println(response)
go func() {
if response.Result.State == "SETTLED" {
zapNote := makeZapNote(privateKey, publicKey, response.Result, zapReq)
fmt.Println(zapNote)
relays := zapReq.Tags.GetAll([]string{"relays"})[0]
for _, url := range relays[1:] {
log.Info().Str("relay", url).Msg("Connecting to relay")
relay, err := nostr.RelayConnect(context.Background(), url)
if err != nil {
log.Info().Err(err).Msg("Failed to connect to relay")
return
}
if _, err := relay.Publish(context.Background(), zapNote); err != nil {
log.Info().Err(err).Msg("Failed to publish event to relay")
return
}
log.Info().Str("relay", url).Str("ID", zapNote.GetID()).Msg("Published to relay")
}
}
}()
}
}
func makeZapNote(privateKey, publicKey string, invoice Invoice, zapReq nostr.Event) nostr.Event {
preimageBytes, _ := b64.StdEncoding.DecodeString("mz6helziX/IoMjo0ElR/LEziVvKSagGxTYOHVi5Aezs=")
preimageHex := hex.EncodeToString(preimageBytes)
event := nostr.Event{
PubKey: publicKey,
CreatedAt: nostr.Timestamp(invoice.SettleDate),
Kind: nostr.KindZap,
Tags: nostr.Tags{
*zapReq.Tags.GetFirst([]string{"p"}),
*zapReq.Tags.GetFirst([]string{"e"}),
nostr.Tag{"bolt11", invoice.PaymentRequest},
nostr.Tag{"description", zapReq.String()},
nostr.Tag{"preimage", preimageHex},
},
}
event.Sign(privateKey)
return event
}