From 1d510fca45d85cb1981fa276bd28bb44ab9c90f2 Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Wed, 9 Feb 2022 11:09:27 +0100 Subject: [PATCH] cert --- go.mod | 3 +- go.sum | 4 ++ internal/satdress/satdress.go | 129 ++++++++++++++++++++++++++++++++++ internal/telegram/handler.go | 16 +++++ internal/telegram/invoice.go | 31 ++++++++ 5 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 internal/satdress/satdress.go diff --git a/go.mod b/go.mod index 84420c1..508421f 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,8 @@ require ( github.com/sirupsen/logrus v1.6.0 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/tidwall/buntdb v1.2.7 - github.com/tidwall/gjson v1.10.2 + github.com/tidwall/gjson v1.12.1 + github.com/tidwall/sjson v1.2.4 // indirect golang.org/x/text v0.3.5 golang.org/x/time v0.0.0-20191024005414-555d28b269f0 gopkg.in/lightningtipbot/telebot.v2 v2.4.2-0.20211217193303-c005cce171ac diff --git a/go.sum b/go.sum index 2ae2730..002d843 100644 --- a/go.sum +++ b/go.sum @@ -508,6 +508,8 @@ github.com/tidwall/gjson v1.6.1 h1:LRbvNuNuvAiISWg6gxLEFuCe72UKy5hDqhxW/8183ws= github.com/tidwall/gjson v1.6.1/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0= github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo= github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.12.1 h1:ikuZsLdhr8Ws0IdROXUS1Gi4v9Z4pGqpX/CvJkxvfpo= +github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/grect v0.1.3 h1:z9YwQAMUxVSBde3b7Sl8Da37rffgNfZ6Fq6h9t6KdXE= github.com/tidwall/grect v0.1.3/go.mod h1:8GMjwh3gPZVpLBI/jDz9uslCe0dpxRpWDdtN0lWAS/E= github.com/tidwall/lotsa v1.0.2 h1:dNVBH5MErdaQ/xd9s769R31/n2dXavsQ0Yf4TMEHHw8= @@ -523,6 +525,8 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/rtred v0.1.2 h1:exmoQtOLvDoO8ud++6LwVsAMTu0KPzLTUrMln8u1yu8= github.com/tidwall/rtred v0.1.2/go.mod h1:hd69WNXQ5RP9vHd7dqekAz+RIdtfBogmglkZSRxCHFQ= +github.com/tidwall/sjson v1.2.4 h1:cuiLzLnaMeBhRmEv00Lpk3tkYrcxpmbU81tAY4Dw0tc= +github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM= github.com/tidwall/tinyqueue v0.1.1 h1:SpNEvEggbpyN5DIReaJ2/1ndroY8iyEGxPYxoSaymYE= github.com/tidwall/tinyqueue v0.1.1/go.mod h1:O/QNHwrnjqr6IHItYrzoHAKYhBkLI67Q096fQP5zMYw= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= diff --git a/internal/satdress/satdress.go b/internal/satdress/satdress.go new file mode 100644 index 0000000..9af2749 --- /dev/null +++ b/internal/satdress/satdress.go @@ -0,0 +1,129 @@ +package satdress + +import ( + "bytes" + "crypto/tls" + "crypto/x509" + "encoding/base64" + "encoding/hex" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "strings" + "time" + + "github.com/tidwall/gjson" + "github.com/tidwall/sjson" +) + +// from github.com/fiatjaf/makeinvoice + +var TorProxyURL = "socks5://127.0.0.1:9050" +var Client = &http.Client{ + Timeout: 10 * time.Second, +} + +type LNDParams struct { + Cert string + Host string + Macaroon string +} + +func (l LNDParams) getCert() string { return l.Cert } +func (l LNDParams) isTor() bool { return strings.Index(l.Host, ".onion") != -1 } + +type BackendParams interface { + getCert() string + isTor() bool +} + +type Params struct { + Backend BackendParams + Msatoshi int64 + Description string + DescriptionHash []byte + + Label string // only used for c-lightning +} + +func GetInvoice(params Params) (string, error) { + + defer func(prevTransport http.RoundTripper) { + Client.Transport = prevTransport + }(Client.Transport) + + specialTransport := &http.Transport{} + + // use a cert or skip TLS verification? + if params.Backend.getCert() != "" { + caCertPool := x509.NewCertPool() + caCertPool.AppendCertsFromPEM([]byte(params.Backend.getCert())) + specialTransport.TLSClientConfig = &tls.Config{RootCAs: caCertPool} + } else { + specialTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + } + + // use a tor proxy? + if params.Backend.isTor() { + torURL, _ := url.Parse(TorProxyURL) + specialTransport.Proxy = http.ProxyURL(torURL) + } + + Client.Transport = specialTransport + + // description hash? + var _, b64h string + if params.DescriptionHash != nil { + _ = hex.EncodeToString(params.DescriptionHash) + b64h = base64.StdEncoding.EncodeToString(params.DescriptionHash) + } + + switch backend := params.Backend.(type) { + case LNDParams: + body, _ := sjson.Set("{}", "value_msat", params.Msatoshi) + + if params.DescriptionHash == nil { + body, _ = sjson.Set(body, "memo", params.Description) + } else { + body, _ = sjson.Set(body, "description_hash", b64h) + } + + req, err := http.NewRequest("POST", + backend.Host+"/v1/invoices", + bytes.NewBufferString(body), + ) + if err != nil { + return "", err + } + + // macaroon must be hex, so if it is on base64 we adjust that + 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 { + return "", err + } + defer resp.Body.Close() + if resp.StatusCode >= 300 { + body, _ := ioutil.ReadAll(resp.Body) + text := string(body) + if len(text) > 300 { + text = text[:300] + } + return "", fmt.Errorf("call to lnd failed (%d): %s", resp.StatusCode, text) + } + + b, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + return gjson.ParseBytes(b).Get("payment_request").String(), nil + } + return "", errors.New("missing backend params") +} diff --git a/internal/telegram/handler.go b/internal/telegram/handler.go index 549d338..392f7bd 100644 --- a/internal/telegram/handler.go +++ b/internal/telegram/handler.go @@ -168,6 +168,22 @@ func (bot TipBot) getHandler() []Handler { }, }, }, + { + Endpoints: []interface{}{"/inv"}, + Handler: bot.invHandler, + Interceptor: &Interceptor{ + Type: MessageInterceptor, + Before: []intercept.Func{ + bot.localizerInterceptor, + bot.logMessageInterceptor, + bot.requireUserInterceptor, + bot.lockInterceptor, + }, + OnDefer: []intercept.Func{ + bot.unlockInterceptor, + }, + }, + }, { Endpoints: []interface{}{"/shops"}, Handler: bot.shopsHandler, diff --git a/internal/telegram/invoice.go b/internal/telegram/invoice.go index 81915ba..6cfcd8b 100644 --- a/internal/telegram/invoice.go +++ b/internal/telegram/invoice.go @@ -8,6 +8,7 @@ import ( "time" "github.com/LightningTipBot/LightningTipBot/internal/errors" + "github.com/LightningTipBot/LightningTipBot/internal/satdress" "github.com/LightningTipBot/LightningTipBot/internal" @@ -200,3 +201,33 @@ func (bot *TipBot) lnurlReceiveEvent(invoiceEvent *InvoiceEvent) { } } } + +// TODO -- move somewhere else +func (bot *TipBot) invHandler(ctx context.Context, m *tb.Message) (context.Context, error) { + // check and print all commands + bot.anyTextHandler(ctx, m) + user := LoadUser(ctx) + if user.Wallet == nil { + return ctx, errors.Create(errors.UserNoWalletError) + } + + // get invoice from user node + pr, err := satdress.GetInvoice( + satdress.Params{ + Backend: satdress.LNDParams{ + Cert: "2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d494943496a4343416369674177494241674952414f68774131694b486b4d704b3654734a797836794b4177436759494b6f5a497a6a3045417749774d4445660a4d4230474131554543684d576247356b494746316447396e5a57356c636d46305a575167593256796444454e4d4173474131554541784d455a4746325a5441650a467730794d5445794d4463794d6a51314d544e61467730794d7a41794d4445794d6a51314d544e614d444178487a416442674e5642416f54466d78755a4342680a645852765a3256755a584a686447566b49474e6c636e51784454414c42674e5642414d5442475268646d55775754415442676371686b6a4f50514942426767710a686b6a4f50514d4242774e4341415350514146462f586838655666496d43414f7a6a456d57596d2f736470632b616a535a50654245333342305369787a3433350a30427976344e317033396d54527a4f783848647332777562326e6d505958636d2b6263506f3448434d49472f4d41344741315564447745422f775145417749430a7044415442674e56485355454444414b4267677242674546425163444154415042674e5648524d4241663845425441444151482f4d42304741315564446751570a424254734732594c32666a6744467954366c2b474f777671762b38634d44426f42674e5648524545595442666767526b59585a6c67676c7362324e68624768760a6333534342475268646d574344584276624746794c5734794c575268646d57434248567561586943436e56756158687759574e725a58534342324a315a6d4e760a626d36484248384141414748454141414141414141414141414141414141414141414748424b775741415977436759494b6f5a497a6a304541774944534141770a52514968414f6437436c716e4a3258735571716b5953756e4937777147736e4b596d57334668353045765877775a44394169424e4c6e575a4342416a343664780a726f5a392f435563595a78754756432f6d666b2b38325a2b5073777977413d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a", + Host: "https://127.0.0.1:8082", + Macaroon: "AgEDbG5kAlgDChBdAmYXLaSkDZ+jUNXkXedBEgEwGhYKB2FkZHJlc3MSBHJlYWQSBXdyaXRlGhcKCGludm9pY2VzEgRyZWFkEgV3cml0ZRoPCgdvbmNoYWluEgRyZWFkAAAGIBevooGKO6xo8c0Q2fj14DYYx95b+jah0rfMj+JJ6pf3", + }, + Msatoshi: 1000, + }, + ) + if err != nil { + log.Errorln(err.Error()) + return ctx, err + } + + log.Infof(pr) + + return ctx, nil +}