Compare commits
5 Commits
99c48cb684
...
667128c341
Author | SHA1 | Date | |
---|---|---|---|
667128c341 | |||
e09b7a59b3 | |||
54f76b5160 | |||
7df699ee69 | |||
de4d4d4f09 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.env
|
||||
zaply
|
45
env/env.go
vendored
Normal file
45
env/env.go
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
package env
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/namsral/flag"
|
||||
)
|
||||
|
||||
var (
|
||||
Port int
|
||||
PublicUrl string
|
||||
PhoenixdURL string
|
||||
PhoenixdLimitedAccessToken string
|
||||
CommitLongSha string
|
||||
CommitShortSha string
|
||||
)
|
||||
|
||||
func Load(filenames ...string) error {
|
||||
if err := godotenv.Load(); err != nil {
|
||||
return err
|
||||
}
|
||||
flag.IntVar(&Port, "PORT", 4444, "Server port")
|
||||
flag.StringVar(&PublicUrl, "PUBLIC_URL", "", "Base URL")
|
||||
flag.StringVar(&PhoenixdURL, "PHOENIXD_URL", "", "Phoenixd URL")
|
||||
flag.StringVar(&PhoenixdLimitedAccessToken, "PHOENIXD_LIMITED_ACCESS_TOKEN", "", "Phoenixd limited access token")
|
||||
return nil
|
||||
}
|
||||
|
||||
func Parse() {
|
||||
flag.Parse()
|
||||
CommitLongSha = execCmd("git", "rev-parse", "HEAD")
|
||||
CommitShortSha = execCmd("git", "rev-parse", "--short", "HEAD")
|
||||
}
|
||||
|
||||
func execCmd(name string, args ...string) string {
|
||||
cmd := exec.Command(name, args...)
|
||||
stdout, err := cmd.Output()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return strings.TrimSpace(string(stdout))
|
||||
}
|
20
go.mod
Normal file
20
go.mod
Normal file
@ -0,0 +1,20 @@
|
||||
module github.com/ekzyis/zaply
|
||||
|
||||
go 1.23.4
|
||||
|
||||
require (
|
||||
github.com/btcsuite/btcutil v1.0.2 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/labstack/echo/v4 v4.13.3 // indirect
|
||||
github.com/labstack/gommon v0.4.2 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/namsral/flag v1.7.4-pre // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/time v0.8.0 // indirect
|
||||
)
|
64
go.sum
Normal file
64
go.sum
Normal file
@ -0,0 +1,64 @@
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts=
|
||||
github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
|
||||
github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/namsral/flag v1.7.4-pre h1:b2ScHhoCUkbsq0d2C15Mv+VU8bl8hAXV8arnWiOHNZs=
|
||||
github.com/namsral/flag v1.7.4-pre/go.mod h1:OXldTctbM6SWH1K899kPZcf65KxJiD7MsceFUpB5yDo=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
|
||||
golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
11
lightning/lightning.go
Normal file
11
lightning/lightning.go
Normal file
@ -0,0 +1,11 @@
|
||||
package lightning
|
||||
|
||||
type Bolt11 string
|
||||
|
||||
type Lightning interface {
|
||||
CreateInvoice(msats int64, description string) (Bolt11, error)
|
||||
}
|
||||
|
||||
type LightningImpl struct {
|
||||
ln *Lightning
|
||||
}
|
98
lightning/phoenixd/phoenixd.go
Normal file
98
lightning/phoenixd/phoenixd.go
Normal file
@ -0,0 +1,98 @@
|
||||
package phoenixd
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ekzyis/zaply/lightning"
|
||||
)
|
||||
|
||||
type Phoenixd struct {
|
||||
url *url.URL
|
||||
accessToken string
|
||||
limitedAccessToken string
|
||||
webhookUrl string
|
||||
}
|
||||
|
||||
func NewPhoenixd(opts ...func(*Phoenixd) *Phoenixd) *Phoenixd {
|
||||
ln := &Phoenixd{}
|
||||
for _, opt := range opts {
|
||||
opt(ln)
|
||||
}
|
||||
return ln
|
||||
}
|
||||
|
||||
func WithPhoenixdURL(u string) func(*Phoenixd) *Phoenixd {
|
||||
return func(p *Phoenixd) *Phoenixd {
|
||||
u, err := url.Parse(u)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
p.url = u
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
func WithPhoenixdLimitedAccessToken(limitedAccessToken string) func(*Phoenixd) *Phoenixd {
|
||||
return func(p *Phoenixd) *Phoenixd {
|
||||
p.limitedAccessToken = limitedAccessToken
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
func WithPhoenixdWebhookUrl(webhookUrl string) func(*Phoenixd) *Phoenixd {
|
||||
return func(p *Phoenixd) *Phoenixd {
|
||||
p.webhookUrl = webhookUrl
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Phoenixd) CreateInvoice(msats int64, description string) (lightning.Bolt11, error) {
|
||||
values := url.Values{}
|
||||
values.Add("amountSat", strconv.FormatInt(msats/1000, 10))
|
||||
values.Add("description", description)
|
||||
if p.webhookUrl != "" {
|
||||
values.Add("webhookUrl", p.webhookUrl)
|
||||
}
|
||||
|
||||
endpoint := p.url.JoinPath("createinvoice")
|
||||
|
||||
req, err := http.NewRequest("POST", endpoint.String(), strings.NewReader(values.Encode()))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
if p.limitedAccessToken != "" {
|
||||
req.SetBasicAuth("", p.limitedAccessToken)
|
||||
}
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("phoenixd %s: %s", resp.Status, string(body))
|
||||
}
|
||||
|
||||
var response struct {
|
||||
Serialized string `json:"serialized"`
|
||||
}
|
||||
if err := json.Unmarshal(body, &response); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return lightning.Bolt11(response.Serialized), nil
|
||||
}
|
110
lnurl/lnurl.go
Normal file
110
lnurl/lnurl.go
Normal file
@ -0,0 +1,110 @@
|
||||
package lnurl
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/btcsuite/btcutil/bech32"
|
||||
"github.com/ekzyis/zaply/env"
|
||||
"github.com/ekzyis/zaply/lightning"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
var (
|
||||
MIN_SENDABLE_AMOUNT = 1000 // 1 sat
|
||||
MAX_SENDABLE_AMOUNT = 100_000_000_000 // 100m sat
|
||||
MAX_COMMENT_LENGTH = 128
|
||||
)
|
||||
|
||||
func Router(e *echo.Echo, ln lightning.Lightning) {
|
||||
e.GET("/.well-known/lnurlp/:name", payRequest)
|
||||
e.GET("/.well-known/lnurlp/:name/pay", pay(ln))
|
||||
}
|
||||
|
||||
func payRequest(c echo.Context) error {
|
||||
callback, err := url.JoinPath(env.PublicUrl, "/.well-known/lnurlp/", c.Param("name"), "/pay")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.JSON(
|
||||
http.StatusOK,
|
||||
map[string]any{
|
||||
"callback": callback,
|
||||
"minSendable": MIN_SENDABLE_AMOUNT,
|
||||
"maxSendable": MAX_SENDABLE_AMOUNT,
|
||||
"metadata": lnurlMetadata(c),
|
||||
"tag": "payRequest",
|
||||
"commentAllowed": MAX_COMMENT_LENGTH,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func pay(ln lightning.Lightning) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
qAmount := c.QueryParam("amount")
|
||||
if qAmount == "" {
|
||||
return lnurlError(c, http.StatusBadRequest, errors.New("amount required"))
|
||||
}
|
||||
msats, err := strconv.ParseInt(qAmount, 10, 64)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return lnurlError(c, http.StatusBadRequest, errors.New("invalid amount"))
|
||||
}
|
||||
if msats < 1000 {
|
||||
return lnurlError(c, http.StatusBadRequest, errors.New("amount must be at least 1000 msats"))
|
||||
}
|
||||
|
||||
comment := c.QueryParam("comment")
|
||||
|
||||
pr, err := ln.CreateInvoice(msats, comment)
|
||||
if err != nil {
|
||||
c.Logger().Error(err)
|
||||
return lnurlError(c, http.StatusInternalServerError, errors.New("failed to create invoice"))
|
||||
}
|
||||
|
||||
return c.JSON(
|
||||
http.StatusOK,
|
||||
map[string]any{
|
||||
"pr": pr,
|
||||
"routes": []string{},
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func lnurlMetadata(c echo.Context) string {
|
||||
s := "["
|
||||
s += fmt.Sprintf("[\"text/plain\",\"Paying %s@%s\"]", c.Param("name"), c.Request().Host)
|
||||
s += fmt.Sprintf(",[\"text/identifier\",\"%s@%s\"]", c.Param("name"), c.Request().Host)
|
||||
s += "]"
|
||||
return s
|
||||
}
|
||||
|
||||
func lnurlError(c echo.Context, code int, err error) error {
|
||||
return c.JSON(code, map[string]any{"status": "ERROR", "error": err.Error()})
|
||||
}
|
||||
|
||||
func Encode(base string, parts ...string) string {
|
||||
u, err := url.JoinPath(base, parts...)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
bech32Url, err := bech32.ConvertBits([]byte(u), 8, 5, true)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
lnurl, err := bech32.Encode("lnurl", bech32Url)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
return strings.ToUpper(lnurl)
|
||||
}
|
25
main.go
Normal file
25
main.go
Normal file
@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/ekzyis/zaply/env"
|
||||
"github.com/ekzyis/zaply/lnurl"
|
||||
"github.com/ekzyis/zaply/server"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := env.Load(); err != nil {
|
||||
log.Fatalf("error loading env: %v", err)
|
||||
}
|
||||
env.Parse()
|
||||
|
||||
log.Printf("url: %s", env.PublicUrl)
|
||||
log.Printf("commit: %s", env.CommitShortSha)
|
||||
log.Printf("phoenixd: %s", env.PhoenixdURL)
|
||||
log.Printf("lnurl: %s", lnurl.Encode(fmt.Sprintf("%s/.well-known/lnurlp/%s", env.PublicUrl, "ekzyis")))
|
||||
|
||||
s := server.NewServer()
|
||||
s.Start(":4444")
|
||||
}
|
37
server/server.go
Normal file
37
server/server.go
Normal file
@ -0,0 +1,37 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"github.com/ekzyis/zaply/env"
|
||||
"github.com/ekzyis/zaply/lightning/phoenixd"
|
||||
"github.com/ekzyis/zaply/lnurl"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
*echo.Echo
|
||||
}
|
||||
|
||||
func NewServer() *Server {
|
||||
s := &Server{
|
||||
Echo: echo.New(),
|
||||
}
|
||||
|
||||
p := phoenixd.NewPhoenixd(
|
||||
phoenixd.WithPhoenixdURL(env.PhoenixdURL),
|
||||
phoenixd.WithPhoenixdLimitedAccessToken(env.PhoenixdLimitedAccessToken),
|
||||
)
|
||||
|
||||
s.Use(middleware.LoggerWithConfig(middleware.LoggerConfig{
|
||||
Format: "${time_custom} ${method} ${uri} ${status}\n",
|
||||
CustomTimeFormat: "2006-01-02 15:04:05.00000-0700",
|
||||
}))
|
||||
|
||||
lnurl.Router(s.Echo, p)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func (s *Server) Start(address string) {
|
||||
s.Logger.Fatal(s.Echo.Start(address))
|
||||
}
|
3
template.env
Normal file
3
template.env
Normal file
@ -0,0 +1,3 @@
|
||||
PUBLIC_URL=
|
||||
PHOENIXD_URL=
|
||||
PHOENIXD_LIMITED_ACCESS_TOKEN=
|
Loading…
x
Reference in New Issue
Block a user