2019-01-07 00:35:26 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"github.com/bumi/lntip/ln"
|
|
|
|
"github.com/labstack/echo"
|
|
|
|
"github.com/labstack/echo/middleware"
|
2019-08-25 15:49:24 +00:00
|
|
|
"github.com/didip/tollbooth"
|
|
|
|
"github.com/didip/tollbooth/limiter"
|
2019-01-07 00:35:26 +00:00
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
)
|
|
|
|
|
2019-08-25 15:49:24 +00:00
|
|
|
// move to file
|
|
|
|
func LimitMiddleware(lmt *limiter.Limiter) echo.MiddlewareFunc {
|
|
|
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
|
|
|
return echo.HandlerFunc(func(c echo.Context) error {
|
|
|
|
httpError := tollbooth.LimitByRequest(lmt, c.Response(), c.Request())
|
|
|
|
if httpError != nil {
|
|
|
|
return c.String(httpError.StatusCode, httpError.Message)
|
|
|
|
}
|
|
|
|
return next(c)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-07 00:35:26 +00:00
|
|
|
var stdOutLogger = log.New(os.Stdout, "", log.LstdFlags)
|
|
|
|
|
2019-01-07 20:29:08 +00:00
|
|
|
type Invoice struct {
|
2019-02-20 00:31:03 +00:00
|
|
|
Value int64 `json:"value"`
|
|
|
|
Memo string `json:"memo"`
|
2019-01-07 20:29:08 +00:00
|
|
|
}
|
|
|
|
|
2019-01-07 00:35:26 +00:00
|
|
|
func main() {
|
|
|
|
address := flag.String("address", "localhost:10009", "The host and port of the ln gRPC server")
|
2019-01-07 22:51:41 +00:00
|
|
|
certFile := flag.String("cert", "~/.lnd/tls.cert", "Path to the lnd tls.cert file")
|
|
|
|
macaroonFile := flag.String("macaroon", "~/.lnd/data/chain/bitcoin/mainnet/invoice.macaroon", "Path to the lnd macaroon file")
|
2019-01-07 20:29:08 +00:00
|
|
|
bind := flag.String("bind", ":1323", "Host and port to bind on")
|
2019-02-20 00:31:03 +00:00
|
|
|
staticPath := flag.String("static-path", "", "Path to a static assets directory. Blank to disable serving static files")
|
|
|
|
disableCors := flag.Bool("disable-cors", false, "Disable CORS headers")
|
2019-08-25 15:49:24 +00:00
|
|
|
requestLimit := flag.Float64("request-limit", 10, "Request limit per second")
|
2019-01-07 00:35:26 +00:00
|
|
|
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
e := echo.New()
|
2019-02-20 00:31:03 +00:00
|
|
|
if *staticPath != "" {
|
|
|
|
e.Static("/static", *staticPath)
|
|
|
|
}
|
|
|
|
if !*disableCors {
|
|
|
|
e.Use(middleware.CORS())
|
|
|
|
}
|
2019-01-07 00:35:26 +00:00
|
|
|
e.Use(middleware.Recover())
|
|
|
|
|
2019-08-25 15:49:24 +00:00
|
|
|
if *requestLimit > 0 {
|
|
|
|
limiter := tollbooth.NewLimiter(*requestLimit, nil)
|
|
|
|
e.Use(LimitMiddleware(limiter))
|
|
|
|
}
|
|
|
|
|
2019-02-20 00:31:03 +00:00
|
|
|
stdOutLogger.Printf("Connection to %s using macaroon %s and cert %s", *address, *macaroonFile, *certFile)
|
2019-01-07 20:29:08 +00:00
|
|
|
lndOptions := ln.LNDoptions{
|
2019-01-07 00:35:26 +00:00
|
|
|
Address: *address,
|
|
|
|
CertFile: *certFile,
|
|
|
|
MacaroonFile: *macaroonFile,
|
|
|
|
}
|
|
|
|
lnClient, err := ln.NewLNDclient(lndOptions)
|
|
|
|
if err != nil {
|
2019-02-20 00:31:03 +00:00
|
|
|
stdOutLogger.Print("Error initializing LND client:")
|
2019-01-07 00:35:26 +00:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
2019-02-20 00:31:03 +00:00
|
|
|
// endpoint URLs compatible to the LND REST API
|
2019-02-19 19:55:07 +00:00
|
|
|
e.POST("/v1/invoices", func(c echo.Context) error {
|
2019-01-07 20:29:08 +00:00
|
|
|
i := new(Invoice)
|
|
|
|
if err := c.Bind(i); err != nil {
|
2019-02-21 01:13:31 +00:00
|
|
|
stdOutLogger.Printf("Bad request: %s", err)
|
|
|
|
return c.JSON(http.StatusBadRequest, "Bad request")
|
2019-01-07 20:29:08 +00:00
|
|
|
}
|
|
|
|
|
2019-02-19 19:55:07 +00:00
|
|
|
invoice, err := lnClient.AddInvoice(i.Value, i.Memo)
|
2019-01-07 00:35:26 +00:00
|
|
|
if err != nil {
|
2019-02-21 01:13:31 +00:00
|
|
|
stdOutLogger.Printf("Error creating invoice: %s", err)
|
|
|
|
return c.JSON(http.StatusInternalServerError, "Error adding invoice")
|
2019-01-07 00:35:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return c.JSON(http.StatusOK, invoice)
|
|
|
|
})
|
|
|
|
|
2019-02-19 19:55:07 +00:00
|
|
|
e.GET("/v1/invoice/:invoiceId", func(c echo.Context) error {
|
2019-01-07 00:35:26 +00:00
|
|
|
invoiceId := c.Param("invoiceId")
|
2019-02-21 01:13:31 +00:00
|
|
|
invoice, err := lnClient.GetInvoice(invoiceId)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
stdOutLogger.Printf("Error looking up invoice: %s", err)
|
|
|
|
return c.JSON(http.StatusInternalServerError, "Error fetching invoice")
|
|
|
|
}
|
|
|
|
|
2019-01-07 00:35:26 +00:00
|
|
|
return c.JSON(http.StatusOK, invoice)
|
|
|
|
})
|
|
|
|
|
2019-08-25 15:49:24 +00:00
|
|
|
// debug test endpoint
|
|
|
|
e.GET("/ping", func(c echo.Context) error {
|
|
|
|
return c.JSON(http.StatusOK, "pong")
|
|
|
|
})
|
|
|
|
|
2019-01-07 20:29:08 +00:00
|
|
|
e.Logger.Fatal(e.Start(*bind))
|
2019-01-07 00:35:26 +00:00
|
|
|
}
|