1
1
mirror of https://github.com/bumi/lntip synced 2026-02-17 14:37:50 +00:00

40 Commits
1.0.0 ... 1.4.0

Author SHA1 Message Date
6b7ab33efe Update FUNDING.yml 2021-10-25 11:24:02 +02:00
36d4dec5fd Merge pull request #22 from bumi/lnurl-logging
Better error logging for the LNURL endpoint
2021-10-25 11:00:55 +02:00
0fd121d130 Merge pull request #23 from bumi/feature/nicer-lnurlp-urls
Nicer LNURLp URLs
2021-10-25 10:59:43 +02:00
9ae6153d47 Nicer LNURLp URLs
this also registers a shorter lnurlp that can be used additionally to the lightning address
2021-10-24 11:44:05 +02:00
3b7ac31615 Better error logging for the LNURL endpoint
This checks for errors when creating the invoice and logs the error and returns an LNURL error response.
Before it would return a blank pr.
2021-10-24 11:32:00 +02:00
22bc75d564 Merge pull request #20 from GlenCooper/patch-1
Fix typo in README.md
2021-10-15 12:46:08 +02:00
Glen Cooper
2bcd2fd96f Fix typo in README.md
Settigns -> Settings
2021-10-15 02:56:50 +00:00
9ec4db5144 Create LICENSE 2021-10-14 23:43:18 +02:00
4a4614d8fb Merge pull request #18 from crc32/patch-2
Add Tor support for Heroku
2021-10-13 20:50:34 +02:00
Colin Crossman
00b33e3bd9 Update README.md with additional Heroku info
Add a statement about the non-standard Tor buildpack, along with instructions to remove. Also add a pointer to the Heroku page describing the method to link the app to a personal domain.
2021-10-13 12:26:07 -06:00
Colin Crossman
109fa20593 Merge branch 'bumi:master' into patch-2 2021-10-13 12:16:32 -06:00
24cdca056f Merge pull request #19 from crc32/master
Update README.md for clarity
2021-10-13 13:24:12 +02:00
Colin Crossman
03117dc326 Update README.md for clarity
It was unclear how to get the HEX of the TLS cert. Initially I had been trying to use openssl to export the hex of the signature, which was wrong. I finally realized that the xxd command was intended to be applied on the entire tls.cert file, and that worked. So I added this to clarify that aspect.
2021-10-12 20:27:11 -06:00
Colin Crossman
1fe4dd3dd6 Update app.json for Tor on Heroku
Add heroku buildpack for Tor integration
2021-10-12 18:06:20 -06:00
Colin Crossman
5dd2c2cdb5 Update app.json
For Heroku, add the Tor buildpack to allow for Tor connections.
2021-10-08 22:33:55 -06:00
Gregor Pogačnik
3200622b97 Possibility to specify listening IP (#17) 2021-09-30 18:07:43 +02:00
561610a7b9 Create FUNDING.yml 2021-09-15 23:59:13 +02:00
6569ac0ded Merge pull request #10 from bumi/tor-support
Add support to connect to TOR nodes
2021-09-08 01:57:06 +02:00
2a4b943887 Merge branch 'master' into tor-support
* master:
  Provide LNURL metadata hash as description_hash in the lightning pr
  Update .lndonate
  Update .lndonate
  Create .lndonate
  Update README.md
  Update README.md
  Update README.md
2021-09-03 13:37:48 +02:00
4fb8fa9a73 Provide LNURL metadata hash as description_hash in the lightning pr 2021-09-03 01:39:06 +02:00
492ffb2d3f Update .lndonate 2021-09-02 17:20:20 +02:00
148dfcba22 Update .lndonate 2021-09-02 17:19:38 +02:00
1292e5498f Create .lndonate 2021-09-02 17:17:42 +02:00
9756507514 Update README.md 2021-08-30 10:04:59 +02:00
ced2d68630 Update README.md 2021-08-30 10:03:02 +02:00
d36f7a49f5 Update README.md 2021-08-30 10:01:40 +02:00
1fff67684a Igrnore tor data-dir 2021-08-30 10:00:23 +02:00
8ff22327c9 Update README.md 2021-08-30 09:59:17 +02:00
7efef4a2b6 Merge branch 'master' into tor-support 2021-08-30 09:52:37 +02:00
031daed750 Update README.md 2021-08-29 09:00:23 +02:00
7283544b40 Merge pull request #11 from bumi/lightning-address
Add Lightning Address support
2021-08-29 08:55:42 +02:00
20e2d8b7e9 readme 2021-08-28 22:46:50 +02:00
1515765c3f Fix LNURL metadata 2021-08-28 22:28:03 +02:00
d403c19aab Merge branch 'master' into lightning-address
* master:
  Update README.md
  Update README.md
  Update README.md
2021-08-28 22:14:16 +02:00
6e4af5610f Add Lightning Address support
This handles the LNURL-pay flow to enable Lightning Address support.
It accepts any lightning address name on your domain.

e.g. yourname@yourdomain.com
2021-08-28 22:11:24 +02:00
19210cc3ce Update README.md 2021-08-28 00:42:04 +02:00
71f6c862fa Update README.md 2021-08-28 00:05:07 +02:00
91c62ed7ed Add Tor readme 2021-08-27 15:55:51 +02:00
fec31b2bd1 Add support to connect to TOR nodes
This requires tor to be installed/running on the system
2021-08-27 14:35:09 +02:00
6355ce2cc5 Update README.md 2021-08-27 11:52:17 +02:00
11 changed files with 250 additions and 24 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
custom: https://ln.michaelbumann.com?lightning=lnurlp:ln.michaelbumann.com/lnurlp/github

2
.gitignore vendored
View File

@@ -1,2 +1,4 @@
vendor
config.toml
data-dir*

1
.lndonate Normal file
View File

@@ -0,0 +1 @@
lnurlp://ln.michaelbumann.com/.well-known/lnurlp/bumi

21
LICENSE Normal file
View 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.

View File

@@ -1,26 +1,30 @@
# LnMe - your friendly ⚡ payment page
LnMe is a personal Bitcoin Lightning payment website and payment widget.
LnMe is a personal Bitcoin Lightning payment page/widget and self-hosted [Lightning Address](https://lightningaddress.com/) server.
![demo](./lnme-demo.gif)
It is a small service written in Go that connects to a [lnd node](https://github.com/lightningnetwork/lnd/blob/master/docs/INSTALL.md) and exposes a simple HTTP JSON API to create and monitor invoices.
It comes with a configurable personal payment website and offers a JavaScript widget to integrate in existing websites.
**See it in action: [ln.michaelbumann.com](https://ln.michaelbumann.com/) - my lightning address: bumi@ln.michaelbumann.com**
If [webln](https://github.com/wbobeirne/webln) is available the widget automatically use webln to request the payment;
otherwise an overlay will be shown with the payment request and a QR code.
LnMe focusses on simplicity and ease of deployment. It connects to an existing lightning node (currently LND is supported).
## Motivation
LnMe is one [simple executable](https://github.com/bumi/lnme/releases) file that can be deployed anywhere with no dependencies. (on your own node or for example with [one click on Heroku](#heroku))
I wanted a simple way for people to send Lightning payments using my own lightning node.
BTCPay Server is too big and hard to run for that and I do not need most of its features.
## Features
- [x] Embeded payment page - customizable (see demo)
- [x] [Lightning Address](https://lightningaddress.com/) support
- [x] WebLN integration - if [WebLN](https://webln.dev/) is not available a QRcode and the invoice will be shown
- [x] [JavaScript widget](#javascript-widget-integration) for existing websites
- [x] [Invoice API](https://github.com/bumi/lnme/wiki/API) - simple REST API to create LN invoices from existing JS code
- [ ] [LNURL-pay](https://github.com/fiatjaf/lnurl-rfc/blob/luds/06.md) support
## Installation
LnMe connects to your [LND node](https://github.com/lightningnetwork/lnd/blob/master/docs/INSTALL.md), so a running LND node is required.
LnMe can easily run next to LND on the same system.
LnMe can easily run next to LND on the same system or any other hosting provider.
There are no other dependencies. Simply download the binary and run it!
1. Download the latest [release](https://github.com/bumi/lnme/releases)
2. Run `lnme`
@@ -55,6 +59,7 @@ Instead of the path to the macaroon and cert files you can also provide the hex
* `static-path`: Path to a folder that you want to serve with LnMe (e.g. /home/bitcoin/lnme/website). Use this if you want to customize your ⚡website. default: disabled
* `disable-website`: Disable the default LnMe website. Disable the website if you only want to embed the LnMe widget on your existing website.
* `disable-cors`: Disable CORS headers. (default: false)
* `disable-ln-address`: Disable [Lightning Address](https://lightningaddress.com/) handling.
* `port`: Port to listen on. (default: 1323)
* `request-limit`: Limit the allowed requests per second. (default: 5)
@@ -84,17 +89,47 @@ All environment variables must be prefixed by `LNME_` use `_` instead of `-`
$ LNME_LND_ADDRESS=127.0.0.1:10005 lnme
### LND Permissions
### Deployment
LnMe needs the following LND permissions:
It is the easiest to run LnMe on the same node as LND. But you can run it anywhere as long as your LND node is accessible.
* Read/Write permission for invoices
* Write permission for onchain address (if you want to use the onchain option)
#### Heroku
Use the LND [macaroon bakery](http://macaroon-bakery.freedomnode.com/) to create a new macaroon for LnMe.
To get the HEX versions of the files use `xxd -plain` e.g. `xxd -plain invoice.macaroon | tr -d '\n'`
### TOR
LnMe can connect to your lightning node through [Tor](https://www.torproject.org/). You need to have Tor installed on your system and then simply provide your LND `.onion` address (don't forget to specify the port).
## Deployment
It is the easiest to run LnMe on the same node as LND. But you can run it anywhere as long as your LND node is accessible. Simply run the binary and make sure the PORT is accessible.
### Heroku
One click deployment with Heroku:
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
[![Deploy on Heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/bumi/lnme)
#### Notes
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
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)
@@ -109,6 +144,18 @@ lnme.michaelbumann.com {
`$ caddy --config /etc/caddy/Caddyfile`
## Feature Usage
### Lightning Address
The Lightning Address is an Internet Identifier that allows anyone to send you Bitcoin over the Lightning Network.
Lightning Address builds on [LNURL-pay](https://github.com/fiatjaf/lnurl-rfc/blob/luds/06.md) LnMe handles the necessary requests for you.
For more information check out the website: [lightningaddress.com](https://lightningaddress.com/)
Your Lightning Address: `{anything}@{your domain}`
### Customize your ⚡ website
LnMe comes with a default website but you can easily configure and build your own using the the LnMe JavaScript widget or JSON API.
@@ -168,6 +215,11 @@ lnme.watchPayment().then(invoice => {
```
## Motivation
I wanted a simple way for people to send Lightning payments using my own lightning node.
BTCPay Server is too big and hard to run for that and I do not need most of its features.
## Development
Use `go run` to ron the service locally:

View File

@@ -21,6 +21,9 @@
"buildpacks": [
{
"url": "https://github.com/heroku/heroku-buildpack-go"
},
{
"url": "https://github.com/iamashks/heroku-buildpack-tor-proxy.git"
}
]
}

1
go.mod
View File

@@ -7,6 +7,7 @@ go 1.15
replace go.etcd.io/etcd => go.etcd.io/etcd v0.5.0-alpha.5.0.20201125193152-8a03d2e9614b
require (
github.com/GeertJohan/go.rice v1.0.2
github.com/cretz/bine v0.2.0
github.com/didip/tollbooth/v6 v6.1.1
github.com/knadh/koanf v1.2.1
github.com/labstack/echo/v4 v4.5.0

7
go.sum
View File

@@ -135,6 +135,8 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbp
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/creack/pty v1.1.7 h1:6pwm8kMQKCmgUg0ZHTm5+/YvRK0s3THD/28+T6/kk4A=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/cretz/bine v0.2.0 h1:8GiDRGlTgz+o8H9DSnsl+5MeBK4HsExxgl6WgzOCuZo=
github.com/cretz/bine v0.2.0/go.mod h1:WU4o9QR9wWp8AVKtTM1XD5vUHkEqnf2vVSo6dBqbetI=
github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY=
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -568,6 +570,8 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rB
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -599,6 +603,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -636,6 +642,7 @@ golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426080607-c94f62235c83 h1:kHSDPqCtsHZOg0nVylfTo20DDhE9gG4Y0jn7hKQ0QAM=
golang.org/x/sys v0.0.0-20210426080607-c94f62235c83/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=

View File

@@ -7,12 +7,15 @@ import (
"fmt"
"io/ioutil"
"log"
"net"
"os"
"strings"
"github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/macaroons"
"gopkg.in/macaroon.v2"
"github.com/cretz/bine/tor"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
@@ -43,13 +46,14 @@ type LNDclient struct {
}
// AddInvoice generates an invoice with the given price and memo.
func (c LNDclient) AddInvoice(value int64, memo string) (Invoice, error) {
func (c LNDclient) AddInvoice(value int64, memo string, descriptionHash []byte) (Invoice, error) {
result := Invoice{}
stdOutLogger.Printf("Adding invoice: memo=%s value=%v ", memo, value)
stdOutLogger.Printf("Adding invoice: memo=%s value=%v", memo, value)
invoice := lnrpc.Invoice{
Memo: memo,
Value: value,
Memo: memo,
DescriptionHash: descriptionHash,
Value: value,
}
res, err := c.lndClient.AddInvoice(c.ctx, &invoice)
if err != nil {
@@ -132,6 +136,21 @@ func NewLNDclient(lndOptions LNDoptions) (LNDclient, error) {
grpc.WithTransportCredentials(creds),
}
if strings.Contains(lndOptions.Address, ".onion") {
// Start Tor
t, err := tor.Start(nil, nil)
if err != nil {
return result, err
}
torDialer, err := t.Dialer(context.Background(), nil)
if err != nil {
return result, err
}
opts = append(opts, grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) {
return torDialer.DialContext(ctx, "tcp", addr)
}))
}
var macaroonData []byte
if lndOptions.MacaroonHex != "" {
macBytes, err := hex.DecodeString(lndOptions.MacaroonHex)

73
lnme.go
View File

@@ -1,14 +1,18 @@
package main
import (
"crypto/sha256"
"flag"
"fmt"
"log"
"net/http"
"os"
"strconv"
"strings"
rice "github.com/GeertJohan/go.rice"
"github.com/bumi/lnme/ln"
"github.com/bumi/lnme/lnurl"
"github.com/didip/tollbooth/v6"
"github.com/didip/tollbooth/v6/limiter"
"github.com/knadh/koanf"
@@ -20,6 +24,8 @@ import (
"github.com/labstack/echo/v4/middleware"
)
const DEFAULT_LISTEN = ":1323"
// Middleware for request limited to prevent too many requests
// TODO: move to file
func LimitMiddleware(lmt *limiter.Limiter) echo.MiddlewareFunc {
@@ -105,7 +111,7 @@ func main() {
return c.JSON(http.StatusBadRequest, "Bad request")
}
invoice, err := lnClient.AddInvoice(i.Value, i.Memo)
invoice, err := lnClient.AddInvoice(i.Value, i.Memo, nil)
if err != nil {
stdOutLogger.Printf("Error creating invoice: %s", err)
return c.JSON(http.StatusInternalServerError, "Error adding invoice")
@@ -137,16 +143,75 @@ func main() {
return c.JSON(http.StatusOK, invoice)
})
if !cfg.Bool("disable-ln-address") {
lnurlHandler := func(c echo.Context) error {
name := c.Param("name")
lightningAddress := name + "@" + c.Request().Host
lnurlMetadata := "[[\"text/identifier\", \"" + lightningAddress + "\"], [\"text/plain\", \"Sats for " + lightningAddress + "\"]]"
if amount := c.QueryParam("amount"); amount == "" {
lnurlPayResponse1 := lnurl.LNURLPayResponse1{
LNURLResponse: lnurl.LNURLResponse{Status: "OK"},
Callback: fmt.Sprintf("%s://%s%s", c.Scheme(), c.Request().Host, c.Request().URL.Path),
MinSendable: 1000,
MaxSendable: 100000000,
EncodedMetadata: lnurlMetadata,
CommentAllowed: 0,
Tag: "payRequest",
}
return c.JSON(http.StatusOK, lnurlPayResponse1)
} else {
stdOutLogger.Printf("New LightningAddress request amount: %s", amount)
msats, err := strconv.ParseInt(amount, 10, 64)
if err != nil || msats < 1000 {
stdOutLogger.Printf("Invalid amount: %s", amount)
return c.JSON(http.StatusOK, lnurl.LNURLErrorResponse{Status: "ERROR", Reason: "Invalid Amount"})
}
sats := msats / 1000 // we need sats
metadataHash := sha256.Sum256([]byte(lnurlMetadata))
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{
LNURLResponse: lnurl.LNURLResponse{Status: "OK"},
PR: invoice.PaymentRequest,
Routes: make([][]lnurl.RouteInfo, 0),
Disposable: false,
SuccessAction: &lnurl.SuccessAction{Tag: "message", Message: "Thanks, payment received!"},
}
return c.JSON(http.StatusOK, lnurlPayResponse2)
}
}
e.GET("/.well-known/lnurlp/:name", lnurlHandler)
e.GET("/lnurlp/:name", lnurlHandler)
}
// Debug test endpoint
e.GET("/ping", func(c echo.Context) error {
return c.JSON(http.StatusOK, "pong")
})
port := cfg.String("port")
// Special case for PORT instead of LNME_PORT due to cloud-providers
if 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 {
@@ -157,10 +222,12 @@ func LoadConfig() *koanf.Koanf {
f.String("lnd-macaroon-path", "~/.lnd/data/chain/bitcoin/mainnet/invoice.macaroon", "Path to the LND macaroon file.")
f.String("lnd-cert-path", "~/.lnd/tls.cert", "Path to the LND tls.cert file.")
f.Bool("disable-website", false, "Disable default embedded website.")
f.Bool("disable-ln-address", false, "Disable Lightning Address handling")
f.Bool("disable-cors", false, "Disable CORS headers.")
f.Float64("request-limit", 5, "Request limit per second.")
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
f.StringVar(&configPath, "config", "config.toml", "Path to a .toml config file.")
f.Parse(os.Args[1:])

52
lnurl/types.go Normal file
View File

@@ -0,0 +1,52 @@
// THANKS: https://github.com/fiatjaf/go-lnurl/blob/d50a8e916232580895822178fe36e0f5cf400554/base.go
// only using the LNURL types here
package lnurl
import "net/url"
type LNURLResponse struct {
Status string `json:"status,omitempty"`
Reason string `json:"reason,omitempty"`
}
type LNURLPayResponse1 struct {
LNURLResponse
Callback string `json:"callback"`
CallbackURL *url.URL `json:"-"`
Tag string `json:"tag"`
MaxSendable int64 `json:"maxSendable"`
MinSendable int64 `json:"minSendable"`
EncodedMetadata string `json:"metadata"`
Metadata Metadata `json:"-"`
CommentAllowed int64 `json:"commentAllowed"`
}
type LNURLPayResponse2 struct {
LNURLResponse
SuccessAction *SuccessAction `json:"successAction"`
Routes [][]RouteInfo `json:"routes"`
PR string `json:"pr"`
Disposable bool `json:"disposable,omitempty"`
}
type RouteInfo struct {
NodeId string `json:"nodeId"`
ChannelUpdate string `json:"channelUpdate"`
}
type SuccessAction struct {
Tag string `json:"tag"`
Description string `json:"description,omitempty"`
URL string `json:"url,omitempty"`
Message string `json:"message,omitempty"`
Ciphertext string `json:"ciphertext,omitempty"`
IV string `json:"iv,omitempty"`
}
type LNURLErrorResponse struct {
Status string `json:"status,omitempty"`
Reason string `json:"reason,omitempty"`
URL *url.URL `json:"-"`
}
type Metadata [][]string