mirror of
https://github.com/bumi/lntip
synced 2026-02-19 15:37:50 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b7ab33efe | |||
| 36d4dec5fd | |||
| 0fd121d130 | |||
| 9ae6153d47 | |||
| 3b7ac31615 | |||
| 22bc75d564 | |||
|
|
2bcd2fd96f | ||
| 9ec4db5144 | |||
| 4a4614d8fb | |||
|
|
00b33e3bd9 | ||
|
|
109fa20593 | ||
| 24cdca056f | |||
|
|
03117dc326 | ||
|
|
1fe4dd3dd6 | ||
|
|
5dd2c2cdb5 | ||
|
|
3200622b97 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1 +1 @@
|
|||||||
custom: https://ln.michaelbumann.com?lightning=lnurlp:ln.michaelbumann.com/.well-known/lnurlp/sats
|
custom: https://ln.michaelbumann.com?lightning=lnurlp:ln.michaelbumann.com/lnurlp/github
|
||||||
|
|||||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2021 Michael Bumann
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
11
README.md
11
README.md
@@ -114,10 +114,21 @@ One click deployment with Heroku:
|
|||||||
|
|
||||||
You will need your LND address, the LND tls certificate (HEX) and the macaroon (HEX).
|
You will need your LND address, the LND tls certificate (HEX) and the macaroon (HEX).
|
||||||
|
|
||||||
|
When getting the HEX of the TLS certificate, use `xxd -plain tls.cert | tr -d '\n'`. The TLS cert is located in the lnd directory:
|
||||||
|
* ~/umbrel/lnd/tls.cert on Umbrel
|
||||||
|
* /mnt/hdd/lnd/tls.cert on Raspiblitz
|
||||||
|
* Can also be located in ~/.lnd
|
||||||
|
|
||||||
[](https://heroku.com/deploy?template=https://github.com/bumi/lnme)
|
[](https://heroku.com/deploy?template=https://github.com/bumi/lnme)
|
||||||
|
|
||||||
Here is a [Video Demo of the Heroku deployment](https://www.youtube.com/watch?v=hSFXhnLp_Rc)
|
Here is a [Video Demo of the Heroku deployment](https://www.youtube.com/watch?v=hSFXhnLp_Rc)
|
||||||
|
|
||||||
|
In order to run Tor on Heroku, the Heroku deployment includes a non-official buildpack: https://github.com/iamashks/heroku-buildpack-tor-proxy
|
||||||
|
This buildpack can be disabled and removed if not needed or desired, through the Settings tab on the Heroku dashboard, or by editing app.json and removing the buildpack.
|
||||||
|
|
||||||
|
Lastly, using the Heroku deployment, you can link the app to your own domain by following the directions here: https://help.heroku.com/MTG1BIA7/how-do-i-connect-a-domain-to-my-heroku-app
|
||||||
|
|
||||||
|
|
||||||
### Deployment Notes
|
### Deployment Notes
|
||||||
|
|
||||||
To run LnMe as systemd service have a look at the [systemd service example config](https://github.com/bumi/lnme/blob/master/examples/lnme.service)
|
To run LnMe as systemd service have a look at the [systemd service example config](https://github.com/bumi/lnme/blob/master/examples/lnme.service)
|
||||||
|
|||||||
3
app.json
3
app.json
@@ -21,6 +21,9 @@
|
|||||||
"buildpacks": [
|
"buildpacks": [
|
||||||
{
|
{
|
||||||
"url": "https://github.com/heroku/heroku-buildpack-go"
|
"url": "https://github.com/heroku/heroku-buildpack-go"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/iamashks/heroku-buildpack-tor-proxy.git"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
32
lnme.go
32
lnme.go
@@ -24,6 +24,8 @@ import (
|
|||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const DEFAULT_LISTEN = ":1323"
|
||||||
|
|
||||||
// Middleware for request limited to prevent too many requests
|
// Middleware for request limited to prevent too many requests
|
||||||
// TODO: move to file
|
// TODO: move to file
|
||||||
func LimitMiddleware(lmt *limiter.Limiter) echo.MiddlewareFunc {
|
func LimitMiddleware(lmt *limiter.Limiter) echo.MiddlewareFunc {
|
||||||
@@ -142,7 +144,7 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if !cfg.Bool("disable-ln-address") {
|
if !cfg.Bool("disable-ln-address") {
|
||||||
e.GET("/.well-known/lnurlp/:name", func(c echo.Context) error {
|
lnurlHandler := func(c echo.Context) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
lightningAddress := name + "@" + c.Request().Host
|
lightningAddress := name + "@" + c.Request().Host
|
||||||
lnurlMetadata := "[[\"text/identifier\", \"" + lightningAddress + "\"], [\"text/plain\", \"Sats for " + lightningAddress + "\"]]"
|
lnurlMetadata := "[[\"text/identifier\", \"" + lightningAddress + "\"], [\"text/plain\", \"Sats for " + lightningAddress + "\"]]"
|
||||||
@@ -162,11 +164,16 @@ func main() {
|
|||||||
stdOutLogger.Printf("New LightningAddress request amount: %s", amount)
|
stdOutLogger.Printf("New LightningAddress request amount: %s", amount)
|
||||||
msats, err := strconv.ParseInt(amount, 10, 64)
|
msats, err := strconv.ParseInt(amount, 10, 64)
|
||||||
if err != nil || msats < 1000 {
|
if err != nil || msats < 1000 {
|
||||||
|
stdOutLogger.Printf("Invalid amount: %s", amount)
|
||||||
return c.JSON(http.StatusOK, lnurl.LNURLErrorResponse{Status: "ERROR", Reason: "Invalid Amount"})
|
return c.JSON(http.StatusOK, lnurl.LNURLErrorResponse{Status: "ERROR", Reason: "Invalid Amount"})
|
||||||
}
|
}
|
||||||
sats := msats / 1000 // we need sats
|
sats := msats / 1000 // we need sats
|
||||||
metadataHash := sha256.Sum256([]byte(lnurlMetadata))
|
metadataHash := sha256.Sum256([]byte(lnurlMetadata))
|
||||||
invoice, err := lnClient.AddInvoice(sats, lightningAddress, metadataHash[:])
|
invoice, err := lnClient.AddInvoice(sats, lightningAddress, metadataHash[:])
|
||||||
|
if err != nil {
|
||||||
|
stdOutLogger.Printf("Error creating invoice: %s", err)
|
||||||
|
return c.JSON(http.StatusOK, lnurl.LNURLErrorResponse{Status: "ERROR", Reason: "Server Error"})
|
||||||
|
}
|
||||||
lnurlPayResponse2 := lnurl.LNURLPayResponse2{
|
lnurlPayResponse2 := lnurl.LNURLPayResponse2{
|
||||||
LNURLResponse: lnurl.LNURLResponse{Status: "OK"},
|
LNURLResponse: lnurl.LNURLResponse{Status: "OK"},
|
||||||
PR: invoice.PaymentRequest,
|
PR: invoice.PaymentRequest,
|
||||||
@@ -176,7 +183,9 @@ func main() {
|
|||||||
}
|
}
|
||||||
return c.JSON(http.StatusOK, lnurlPayResponse2)
|
return c.JSON(http.StatusOK, lnurlPayResponse2)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
e.GET("/.well-known/lnurlp/:name", lnurlHandler)
|
||||||
|
e.GET("/lnurlp/:name", lnurlHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug test endpoint
|
// Debug test endpoint
|
||||||
@@ -185,10 +194,24 @@ func main() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
port := cfg.String("port")
|
port := cfg.String("port")
|
||||||
|
// Special case for PORT instead of LNME_PORT due to cloud-providers
|
||||||
if os.Getenv("PORT") != "" {
|
if os.Getenv("PORT") != "" {
|
||||||
port = os.Getenv("PORT")
|
port = os.Getenv("PORT")
|
||||||
}
|
}
|
||||||
e.Logger.Fatal(e.Start(":" + port))
|
listen := cfg.String("listen")
|
||||||
|
if listen != "" && port != "" {
|
||||||
|
log.Fatalf("Port and listen options are mutually exclusive, please just use listen.")
|
||||||
|
}
|
||||||
|
if listen == "" {
|
||||||
|
if port != "" {
|
||||||
|
stdOutLogger.Printf("Please use listen instead of deprecated port setting.")
|
||||||
|
listen = fmt.Sprintf(":%s", port)
|
||||||
|
} else {
|
||||||
|
listen = DEFAULT_LISTEN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e.Logger.Fatal(e.Start(listen))
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadConfig() *koanf.Koanf {
|
func LoadConfig() *koanf.Koanf {
|
||||||
@@ -203,7 +226,8 @@ func LoadConfig() *koanf.Koanf {
|
|||||||
f.Bool("disable-cors", false, "Disable CORS headers.")
|
f.Bool("disable-cors", false, "Disable CORS headers.")
|
||||||
f.Float64("request-limit", 5, "Request limit per second.")
|
f.Float64("request-limit", 5, "Request limit per second.")
|
||||||
f.String("static-path", "", "Path to a static assets directory.")
|
f.String("static-path", "", "Path to a static assets directory.")
|
||||||
f.String("port", "1323", "Port to bind on.")
|
f.String("port", "", "Port to bind on (deprecated - use listen).")
|
||||||
|
f.String("listen", "", fmt.Sprintf("Address to bind on. (default \"%s\")", DEFAULT_LISTEN))
|
||||||
var configPath string
|
var configPath string
|
||||||
f.StringVar(&configPath, "config", "config.toml", "Path to a .toml config file.")
|
f.StringVar(&configPath, "config", "config.toml", "Path to a .toml config file.")
|
||||||
f.Parse(os.Args[1:])
|
f.Parse(os.Args[1:])
|
||||||
|
|||||||
Reference in New Issue
Block a user