Compare commits
29 Commits
1.3.0
...
missing-op
| Author | SHA1 | Date | |
|---|---|---|---|
| c864602c1f | |||
|
|
cffdded688 | ||
| b100455e09 | |||
| 6f2b72caa7 | |||
|
|
51a8d1ca22 | ||
| d1be2e20aa | |||
| bf44f314dd | |||
| 5ffac5e077 | |||
| 399144acf5 | |||
| 6548504333 | |||
| 324d5b3b43 | |||
|
|
44befafc6d | ||
|
|
e3bf2c0537 | ||
|
|
2b095bbba3 | ||
| 6b7ab33efe | |||
| 36d4dec5fd | |||
| 0fd121d130 | |||
| 9ae6153d47 | |||
| 3b7ac31615 | |||
| 22bc75d564 | |||
|
|
2bcd2fd96f | ||
| 9ec4db5144 | |||
| 4a4614d8fb | |||
|
|
00b33e3bd9 | ||
|
|
109fa20593 | ||
| 24cdca056f | |||
|
|
03117dc326 | ||
|
|
1fe4dd3dd6 | ||
|
|
5dd2c2cdb5 |
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
|
||||||
|
|||||||
43
.github/workflows/on-push.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
name: Build on push
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build image
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout project
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set env variables
|
||||||
|
run: |
|
||||||
|
echo "BRANCH=$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//-/g')" >> $GITHUB_ENV
|
||||||
|
IMAGE_NAME="${GITHUB_REPOSITORY#*/}"
|
||||||
|
echo "IMAGE_NAME=${IMAGE_NAME//docker-/}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
id: qemu
|
||||||
|
|
||||||
|
- name: Setup Docker buildx action
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
id: buildx
|
||||||
|
|
||||||
|
- name: Run Docker buildx
|
||||||
|
run: |
|
||||||
|
docker buildx build \
|
||||||
|
--platform linux/amd64,linux/arm64 \
|
||||||
|
--tag ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME:$BRANCH \
|
||||||
|
--output "type=registry" ./
|
||||||
43
.github/workflows/on-tag.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
name: Build on tag
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- v[0-9]+.[0-9]+.[0-9]+
|
||||||
|
- v[0-9]+.[0-9]+.[0-9]+-*
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build image
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout project
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set env variables
|
||||||
|
run: |
|
||||||
|
echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
|
||||||
|
IMAGE_NAME="${GITHUB_REPOSITORY#*/}"
|
||||||
|
echo "IMAGE_NAME=${IMAGE_NAME//docker-/}" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Login to Docker Hub
|
||||||
|
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.repository_owner }} --password-stdin
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v1
|
||||||
|
id: qemu
|
||||||
|
|
||||||
|
- name: Setup Docker buildx action
|
||||||
|
uses: docker/setup-buildx-action@v1
|
||||||
|
id: buildx
|
||||||
|
|
||||||
|
- name: Run Docker buildx
|
||||||
|
run: |
|
||||||
|
docker buildx build \
|
||||||
|
--platform linux/amd64,linux/arm64 \
|
||||||
|
--tag ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME:$BRANCH \
|
||||||
|
--output "type=registry" ./
|
||||||
20
Dockerfile
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Go base image
|
||||||
|
FROM golang:1.17-alpine as builder
|
||||||
|
|
||||||
|
RUN go get github.com/GeertJohan/go.rice && go get github.com/GeertJohan/go.rice/rice
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN go install
|
||||||
|
|
||||||
|
RUN rice embed-go && go build
|
||||||
|
|
||||||
|
FROM alpine:3.14
|
||||||
|
|
||||||
|
COPY --from=builder /app/lnme /lnme
|
||||||
|
|
||||||
|
EXPOSE 1323
|
||||||
|
|
||||||
|
CMD ["/lnme"]
|
||||||
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.
|
||||||
33
README.md
@@ -1,4 +1,5 @@
|
|||||||
# LnMe - your friendly ⚡ payment page
|
<p align="center"><br/><br/><img src="https://raw.githubusercontent.com/bumi/lnme/master/icon/lnme-icon-rrect.svg" height="128" width="128" /><br/><br/></p>
|
||||||
|
<h1 align="center">LnMe - your friendly payment page</h1><br/><br/>
|
||||||
|
|
||||||
LnMe is a personal Bitcoin Lightning payment page/widget and self-hosted [Lightning Address](https://lightningaddress.com/) server.
|
LnMe is a personal Bitcoin Lightning payment page/widget and self-hosted [Lightning Address](https://lightningaddress.com/) server.
|
||||||
|
|
||||||
@@ -39,6 +40,12 @@ There are no other dependencies. Simply download the binary and run it!
|
|||||||
|
|
||||||
Note: You must have [go.rice installed](https://github.com/GeertJohan/go.rice#installation)
|
Note: You must have [go.rice installed](https://github.com/GeertJohan/go.rice#installation)
|
||||||
|
|
||||||
|
### Running in Docker
|
||||||
|
|
||||||
|
LnMe is now available in docker too.
|
||||||
|
You can start LnMe like this: `docker run -it --rm ghcr.io/bumi/lnme:master`
|
||||||
|
A list of existing tags is available [here](https://github.com/bumi/lnme/pkgs/container/lnme).
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
#### LND configuration
|
#### LND configuration
|
||||||
@@ -93,8 +100,8 @@ All environment variables must be prefixed by `LNME_` use `_` instead of `-`
|
|||||||
|
|
||||||
LnMe needs the following LND permissions:
|
LnMe needs the following LND permissions:
|
||||||
|
|
||||||
* Read/Write permission for invoices
|
* Read/Write permission for `invoices`
|
||||||
* Write permission for onchain address (if you want to use the onchain option)
|
* Write permission for `address` (if you want to use the onchain option)
|
||||||
|
|
||||||
Use the LND [macaroon bakery](http://macaroon-bakery.freedomnode.com/) to create a new macaroon for LnMe.
|
Use the LND [macaroon bakery](http://macaroon-bakery.freedomnode.com/) to create a new macaroon for LnMe.
|
||||||
|
|
||||||
@@ -109,15 +116,31 @@ LnMe can connect to your lightning node through [Tor](https://www.torproject.org
|
|||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
If you run LNMe on a different server you will need your LND address, the LND TLS certificate (HEX) and the macaroon (HEX). (see above)
|
||||||
|
|
||||||
|
When getting the HEX of the LND files use `xxd -plain YOUR_FILE.cert | tr -d '\n'`. For example for 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
|
||||||
|
|
||||||
|
You should find the macaroon files in the LND data dir (e.g. ~.lnd/data/chain/bitcoin/mainnet/) or see "LND Permissions" how to create a new one.
|
||||||
|
|
||||||
|
|
||||||
### Heroku
|
### Heroku
|
||||||
One click deployment with Heroku:
|
One click deployment with Heroku:
|
||||||
|
|
||||||
You will need your LND address, the LND tls certificate (HEX) and the macaroon (HEX).
|
|
||||||
|
|
||||||
[](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)
|
||||||
|
|||||||
9
app.json
@@ -16,11 +16,18 @@
|
|||||||
"LNME_LND_CERT": {
|
"LNME_LND_CERT": {
|
||||||
"description": "LND TLS cert as HEX",
|
"description": "LND TLS cert as HEX",
|
||||||
"value": ""
|
"value": ""
|
||||||
|
},
|
||||||
|
"LNME_TOR_EXE_PATH": {
|
||||||
|
"description": "Path to the tor executable",
|
||||||
|
"value": "/app/tor/bin/tor"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
20
files/assets/favicon.svg
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>lnme-icon-no-padding</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||||
|
<stop stop-color="#FFA500" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFE300" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||||
|
<stop stop-color="#FFE300" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFA500" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="lnme-icon-no-padding" transform="translate(0.000000, -0.460904)">
|
||||||
|
<polygon id="Path1" fill="url(#linearGradient-1)" points="439.147203 0 192.83828 475.102188 823.013089 475.102188 909.205258 386.884293 491.070577 386.884293 737.132519 0.460904"></polygon>
|
||||||
|
<polygon id="Path2" fill="url(#linearGradient-2)" points="115.14578 615.666174 528.131075 615.666174 327.461698 1024 793.918502 509.464888 174.115801 509.464888"></polygon>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
27
files/assets/icon.svg
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>lnme-icon-rect</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient x1="0%" y1="64.5790537%" x2="100%" y2="64.5790537%" id="linearGradient-1">
|
||||||
|
<stop stop-color="#3D3393" offset="0%"></stop>
|
||||||
|
<stop stop-color="#2B76B9" offset="24.6013508%"></stop>
|
||||||
|
<stop stop-color="#2CACD1" offset="67.981896%"></stop>
|
||||||
|
<stop stop-color="#35EB93" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||||
|
<stop stop-color="#FFA500" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFE300" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||||
|
<stop stop-color="#FFE300" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFA500" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="lnme-icon-rect">
|
||||||
|
<rect id="Background" fill="url(#linearGradient-1)" x="0" y="0" width="1024" height="1024"></rect>
|
||||||
|
<polygon id="Path1" fill="url(#linearGradient-2)" points="456 91.539096 254.655336 479.91029 769.790288 479.91029 840.247879 407.796774 498.444643 407.796774 698.541282 95.539096"></polygon>
|
||||||
|
<polygon id="Path2" fill="url(#linearGradient-3)" points="191.14578 594.813998 528.739662 594.813998 364.70294 928.605547 746.006985 508 239.350688 508"></polygon>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -1,3 +0,0 @@
|
|||||||
<svg width="128" height="128" style="enable-background:new 0 0 128 128;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<path d="M115.36,61.84L70.22,50.49L114.45,2.4c0.41-0.45,0.43-1.13,0.05-1.6c-0.39-0.48-1.07-0.59-1.59-0.27 L12.3,61.98c-0.41,0.25-0.64,0.72-0.57,1.2c0.06,0.48,0.4,0.87,0.87,1.01l45.07,13.25L13.38,125.6c-0.42,0.46-0.44,1.15-0.04,1.61 c0.24,0.29,0.58,0.44,0.94,0.44c0.22,0,0.45-0.06,0.65-0.19l100.78-63.41c0.42-0.26,0.64-0.75,0.56-1.22 C116.19,62.34,115.84,61.95,115.36,61.84z" style="fill:#FCC21B;"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 559 B |
@@ -6,9 +6,9 @@
|
|||||||
<meta property="og:site_name" content="">
|
<meta property="og:site_name" content="">
|
||||||
<meta property="og:description" content="">
|
<meta property="og:description" content="">
|
||||||
|
|
||||||
<meta property="og:image" content="/lnme/zap.svg">
|
<meta property="og:image" content="/lnme/icon.svg">
|
||||||
|
|
||||||
<title>⚡ Send me some Sats</title>
|
<title>Send me some Sats</title>
|
||||||
<style>
|
<style>
|
||||||
html {
|
html {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -111,6 +111,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/lnme/favicon.svg" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
|
|||||||
BIN
icon/lnme-icon-bnw.png
Normal file
|
After Width: | Height: | Size: 397 KiB |
27
icon/lnme-icon-bnw.svg
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>lnme-icon-bnw</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient x1="0%" y1="64.5790537%" x2="100%" y2="64.5790537%" id="linearGradient-1">
|
||||||
|
<stop stop-color="#3A3A3A" offset="0%"></stop>
|
||||||
|
<stop stop-color="#595959" offset="24.6013508%"></stop>
|
||||||
|
<stop stop-color="#7B7B7B" offset="67.981896%"></stop>
|
||||||
|
<stop stop-color="#8B8B8B" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||||
|
<stop stop-color="#B4B4B4" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFFFFF" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||||
|
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||||
|
<stop stop-color="#AEAEAE" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="lnme-icon-bnw">
|
||||||
|
<rect id="Background" fill="url(#linearGradient-1)" x="0" y="0" width="1024" height="1024" rx="128"></rect>
|
||||||
|
<polygon id="Path1" fill="url(#linearGradient-2)" points="456 91.539096 254.655336 479.91029 769.790288 479.91029 840.247879 407.796774 498.444643 407.796774 698.541282 95.539096"></polygon>
|
||||||
|
<polygon id="Path2" fill="url(#linearGradient-3)" points="191.15 594.813998 528.743882 594.813998 364.70716 928.605547 746.011205 508 239.354908 508"></polygon>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
BIN
icon/lnme-icon-bnw@2x.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
icon/lnme-icon-no-padding.png
Normal file
|
After Width: | Height: | Size: 115 KiB |
20
icon/lnme-icon-no-padding.svg
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>lnme-icon-no-padding</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||||
|
<stop stop-color="#FFA500" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFE300" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||||
|
<stop stop-color="#FFE300" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFA500" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="lnme-icon-no-padding" transform="translate(0.000000, -0.460904)">
|
||||||
|
<polygon id="Path1" fill="url(#linearGradient-1)" points="439.147203 0 192.83828 475.102188 823.013089 475.102188 909.205258 386.884293 491.070577 386.884293 737.132519 0.460904"></polygon>
|
||||||
|
<polygon id="Path2" fill="url(#linearGradient-2)" points="115.14578 615.666174 528.131075 615.666174 327.461698 1024 793.918502 509.464888 174.115801 509.464888"></polygon>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
BIN
icon/lnme-icon-no-padding@2x.png
Normal file
|
After Width: | Height: | Size: 358 KiB |
BIN
icon/lnme-icon-rect.png
Normal file
|
After Width: | Height: | Size: 760 KiB |
27
icon/lnme-icon-rect.svg
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>lnme-icon-rect</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient x1="0%" y1="64.5790537%" x2="100%" y2="64.5790537%" id="linearGradient-1">
|
||||||
|
<stop stop-color="#3D3393" offset="0%"></stop>
|
||||||
|
<stop stop-color="#2B76B9" offset="24.6013508%"></stop>
|
||||||
|
<stop stop-color="#2CACD1" offset="67.981896%"></stop>
|
||||||
|
<stop stop-color="#35EB93" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||||
|
<stop stop-color="#FFA500" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFE300" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||||
|
<stop stop-color="#FFE300" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFA500" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="lnme-icon-rect">
|
||||||
|
<rect id="Background" fill="url(#linearGradient-1)" x="0" y="0" width="1024" height="1024"></rect>
|
||||||
|
<polygon id="Path1" fill="url(#linearGradient-2)" points="456 91.539096 254.655336 479.91029 769.790288 479.91029 840.247879 407.796774 498.444643 407.796774 698.541282 95.539096"></polygon>
|
||||||
|
<polygon id="Path2" fill="url(#linearGradient-3)" points="191.14578 594.813998 528.739662 594.813998 364.70294 928.605547 746.006985 508 239.350688 508"></polygon>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
BIN
icon/lnme-icon-rect@2x.png
Normal file
|
After Width: | Height: | Size: 3.0 MiB |
BIN
icon/lnme-icon-rrect.png
Normal file
|
After Width: | Height: | Size: 765 KiB |
27
icon/lnme-icon-rrect.svg
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>lnme-icon-rrect</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient x1="0%" y1="64.5790537%" x2="100%" y2="64.5790537%" id="linearGradient-1">
|
||||||
|
<stop stop-color="#3D3393" offset="0%"></stop>
|
||||||
|
<stop stop-color="#2B76B9" offset="24.6013508%"></stop>
|
||||||
|
<stop stop-color="#2CACD1" offset="67.981896%"></stop>
|
||||||
|
<stop stop-color="#35EB93" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||||
|
<stop stop-color="#FFA500" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFE300" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||||
|
<stop stop-color="#FFE300" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFA500" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="lnme-icon-rrect">
|
||||||
|
<rect id="Background" fill="url(#linearGradient-1)" x="0" y="0" width="1024" height="1024" rx="128"></rect>
|
||||||
|
<polygon id="Path1" fill="url(#linearGradient-2)" points="456 91.539096 254.655336 479.91029 769.790288 479.91029 840.247879 407.796774 498.444643 407.796774 698.541282 95.539096"></polygon>
|
||||||
|
<polygon id="Path2" fill="url(#linearGradient-3)" points="191.14578 594.813998 528.739662 594.813998 364.70294 928.605547 746.006985 508 239.350688 508"></polygon>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.7 KiB |
BIN
icon/lnme-icon-rrect@2x.png
Normal file
|
After Width: | Height: | Size: 2.9 MiB |
BIN
icon/lnme-icon.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
icon/lnme-icon.sketch
Normal file
20
icon/lnme-icon.svg
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<title>lnme-icon</title>
|
||||||
|
<defs>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||||
|
<stop stop-color="#FFA500" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFE300" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||||
|
<stop stop-color="#FFE300" offset="0%"></stop>
|
||||||
|
<stop stop-color="#FFA500" offset="100%"></stop>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||||
|
<g id="lnme-icon">
|
||||||
|
<polygon id="Path1" fill="url(#linearGradient-1)" points="456 91.539096 254.655336 479.91029 769.790288 479.91029 840.247879 407.796774 498.444643 407.796774 698.541282 95.539096"></polygon>
|
||||||
|
<polygon id="Path2" fill="url(#linearGradient-2)" points="191.14578 594.813998 528.739662 594.813998 364.70294 928.605547 746.006985 508 239.350688 508"></polygon>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.2 KiB |
BIN
icon/lnme-icon@2x.png
Normal file
|
After Width: | Height: | Size: 283 KiB |
@@ -37,6 +37,7 @@ type LNDoptions struct {
|
|||||||
CertHex string
|
CertHex string
|
||||||
MacaroonFile string
|
MacaroonFile string
|
||||||
MacaroonHex string
|
MacaroonHex string
|
||||||
|
TorExePath string // used when connecting through tor to LND
|
||||||
}
|
}
|
||||||
|
|
||||||
type LNDclient struct {
|
type LNDclient struct {
|
||||||
@@ -138,7 +139,7 @@ func NewLNDclient(lndOptions LNDoptions) (LNDclient, error) {
|
|||||||
|
|
||||||
if strings.Contains(lndOptions.Address, ".onion") {
|
if strings.Contains(lndOptions.Address, ".onion") {
|
||||||
// Start Tor
|
// Start Tor
|
||||||
t, err := tor.Start(nil, nil)
|
t, err := tor.Start(nil, &tor.StartConf{ExePath: lndOptions.TorExePath})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|||||||
21
lnme.go
@@ -94,6 +94,7 @@ func main() {
|
|||||||
CertHex: cfg.String("lnd-cert"),
|
CertHex: cfg.String("lnd-cert"),
|
||||||
MacaroonFile: cfg.String("lnd-macaroon-path"),
|
MacaroonFile: cfg.String("lnd-macaroon-path"),
|
||||||
MacaroonHex: cfg.String("lnd-macaroon"),
|
MacaroonHex: cfg.String("lnd-macaroon"),
|
||||||
|
TorExePath: cfg.String("tor-exe-path"),
|
||||||
}
|
}
|
||||||
lnClient, err := ln.NewLNDclient(lndOptions)
|
lnClient, err := ln.NewLNDclient(lndOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -144,15 +145,19 @@ 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 {
|
||||||
|
host := c.Request().Host
|
||||||
|
if c.Request().Header.Get(echo.HeaderXForwardedFor) != "" {
|
||||||
|
host = c.Request().Header.Get(echo.HeaderXForwardedFor)
|
||||||
|
}
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
lightningAddress := name + "@" + c.Request().Host
|
lightningAddress := name + "@" + host
|
||||||
lnurlMetadata := "[[\"text/identifier\", \"" + lightningAddress + "\"], [\"text/plain\", \"Sats for " + lightningAddress + "\"]]"
|
lnurlMetadata := "[[\"text/identifier\", \"" + lightningAddress + "\"], [\"text/plain\", \"Sats for " + lightningAddress + "\"]]"
|
||||||
|
|
||||||
if amount := c.QueryParam("amount"); amount == "" {
|
if amount := c.QueryParam("amount"); amount == "" {
|
||||||
lnurlPayResponse1 := lnurl.LNURLPayResponse1{
|
lnurlPayResponse1 := lnurl.LNURLPayResponse1{
|
||||||
LNURLResponse: lnurl.LNURLResponse{Status: "OK"},
|
LNURLResponse: lnurl.LNURLResponse{Status: "OK"},
|
||||||
Callback: fmt.Sprintf("%s://%s%s", c.Scheme(), c.Request().Host, c.Request().URL.Path),
|
Callback: fmt.Sprintf("%s://%s%s", c.Scheme(), host, c.Request().URL.Path),
|
||||||
MinSendable: 1000,
|
MinSendable: 1000,
|
||||||
MaxSendable: 100000000,
|
MaxSendable: 100000000,
|
||||||
EncodedMetadata: lnurlMetadata,
|
EncodedMetadata: lnurlMetadata,
|
||||||
@@ -164,11 +169,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,
|
||||||
@@ -178,7 +188,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
|
||||||
@@ -221,6 +233,7 @@ func LoadConfig() *koanf.Koanf {
|
|||||||
f.String("static-path", "", "Path to a static assets directory.")
|
f.String("static-path", "", "Path to a static assets directory.")
|
||||||
f.String("port", "", "Port to bind on (deprecated - use listen).")
|
f.String("port", "", "Port to bind on (deprecated - use listen).")
|
||||||
f.String("listen", "", fmt.Sprintf("Address to bind on. (default \"%s\")", DEFAULT_LISTEN))
|
f.String("listen", "", fmt.Sprintf("Address to bind on. (default \"%s\")", DEFAULT_LISTEN))
|
||||||
|
f.String("tor-exe-path", "tor", "Path to the Tor executable. Used when connecting through Tor. (default: tor)")
|
||||||
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:])
|
||||||
|
|||||||