├── .github └── workflows │ ├── push.yml │ └── tag.yml ├── .gitignore ├── .gitmodules ├── Dockerfile.tmpl ├── LICENSE ├── README.md ├── apps ├── apps.7.md └── apps.json ├── bin ├── about ├── bos-config ├── circuitbreaker-config ├── igniter-config └── lndmanage-config ├── create-manifest.sh ├── generate-dockerfiles.sh ├── go.mod ├── install-apps.sh ├── lsh_exec.sh ├── motd ├── package.json ├── requirements.txt └── start.sh /.github/workflows/push.yml: -------------------------------------------------------------------------------- 1 | name: Build images on push 2 | 3 | permissions: 4 | packages: write 5 | 6 | on: 7 | push: 8 | branches: 9 | - main 10 | 11 | jobs: 12 | build: 13 | name: Build image 14 | runs-on: ubuntu-20.04 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | architecture: 19 | - "arm64" 20 | - "amd64" 21 | base: 22 | - "buster" 23 | # - "bullseye" 24 | 25 | steps: 26 | - name: Checkout project 27 | uses: actions/checkout@v2 28 | with: 29 | submodules: recursive 30 | 31 | - name: Set env variables 32 | run: | 33 | echo "BRANCH=$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//-/g')" >> $GITHUB_ENV 34 | echo "IMAGE_NAME=${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV 35 | 36 | - name: Login to GitHub Container Registry 37 | uses: docker/login-action@v1 38 | with: 39 | registry: ghcr.io 40 | username: ${{ github.repository_owner }} 41 | password: ${{ secrets.GITHUB_TOKEN }} 42 | 43 | - name: Set up QEMU 44 | uses: docker/setup-qemu-action@v1 45 | 46 | - name: Setup Docker buildx action 47 | uses: docker/setup-buildx-action@v1 48 | 49 | - name: Run Docker buildx 50 | run: | 51 | ./generate-dockerfiles.sh 52 | docker buildx build --platform linux/${{ matrix.architecture }} \ 53 | --tag ghcr.io/${{ github.repository_owner }}/${IMAGE_NAME}:${BRANCH}-${{ matrix.base }}-slim-${{ matrix.architecture }} --output "type=registry" \ 54 | --build-arg arch=${{ matrix.architecture }} \ 55 | --build-arg version=${BRANCH} \ 56 | --file Dockerfile.${{ matrix.base }} \ 57 | ./ 58 | 59 | create-manifest: 60 | name: Create two-architecture manifest 61 | runs-on: ubuntu-20.04 62 | needs: build 63 | strategy: 64 | matrix: 65 | base: 66 | - "buster" 67 | # - "bullseye" 68 | 69 | steps: 70 | - name: Checkout project 71 | uses: actions/checkout@v2 72 | 73 | - name: Set env variables 74 | run: | 75 | echo "BRANCH=$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//-/g')" >> $GITHUB_ENV 76 | echo "IMAGE_NAME=${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV 77 | 78 | - name: Login to GitHub Container Registry 79 | uses: docker/login-action@v1 80 | with: 81 | registry: ghcr.io 82 | username: ${{ github.repository_owner }} 83 | password: ${{ secrets.GITHUB_TOKEN }} 84 | 85 | - name: Create final manifest 86 | run: ./create-manifest.sh "ghcr.io/${{ github.repository_owner }}/${IMAGE_NAME}" "${BRANCH}" "${{ matrix.base }}-slim" 87 | -------------------------------------------------------------------------------- /.github/workflows/tag.yml: -------------------------------------------------------------------------------- 1 | name: Build images on tag 2 | 3 | permissions: 4 | packages: write 5 | 6 | on: 7 | push: 8 | tags: 9 | - v[0-9]+.[0-9]+.[0-9]+ 10 | - v[0-9]+.[0-9]+.[0-9]+-* 11 | 12 | jobs: 13 | build: 14 | name: Build image 15 | runs-on: ubuntu-20.04 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | architecture: 20 | - "arm64" 21 | - "amd64" 22 | base: 23 | - "buster" 24 | - "bullseye" 25 | 26 | steps: 27 | - name: Checkout project 28 | uses: actions/checkout@v2 29 | with: 30 | submodules: recursive 31 | 32 | - name: Set env variables 33 | run: | 34 | echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV 35 | echo "IMAGE_NAME=${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV 36 | 37 | - name: Login to GitHub Container Registry 38 | uses: docker/login-action@v1 39 | with: 40 | registry: ghcr.io 41 | username: ${{ github.repository_owner }} 42 | password: ${{ secrets.GITHUB_TOKEN }} 43 | 44 | - name: Set up QEMU 45 | uses: docker/setup-qemu-action@v1 46 | 47 | - name: Setup Docker buildx action 48 | uses: docker/setup-buildx-action@v1 49 | 50 | - name: Run Docker buildx 51 | run: | 52 | ./generate-dockerfiles.sh 53 | docker buildx build --platform linux/${{ matrix.architecture }} \ 54 | --tag ghcr.io/${{ github.repository_owner }}/${IMAGE_NAME}:${TAG}-${{ matrix.base }}-slim-${{ matrix.architecture }} --output "type=registry" \ 55 | --build-arg arch=${{ matrix.architecture }} \ 56 | --build-arg version=${TAG} \ 57 | --file Dockerfile.${{ matrix.base }} \ 58 | ./ 59 | 60 | create-manifest: 61 | name: Create two-architecture manifest 62 | runs-on: ubuntu-20.04 63 | needs: build 64 | strategy: 65 | matrix: 66 | base: 67 | - "buster" 68 | - "bullseye" 69 | 70 | steps: 71 | - name: Checkout project 72 | uses: actions/checkout@v2 73 | 74 | - name: Set env variables 75 | run: | 76 | echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV 77 | echo "IMAGE_NAME=${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV 78 | 79 | - name: Login to GitHub Container Registry 80 | uses: docker/login-action@v1 81 | with: 82 | registry: ghcr.io 83 | username: ${{ github.repository_owner }} 84 | password: ${{ secrets.GITHUB_TOKEN }} 85 | 86 | - name: Create final manifest 87 | run: ./create-manifest.sh "ghcr.io/${{ github.repository_owner }}/${IMAGE_NAME}" "${TAG}" "${{ matrix.base }}-slim" 88 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Dockerfile 2 | Dockerfile.buster 3 | Dockerfile.bullseye 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "apps/csview"] 2 | path = apps/csview 3 | url = https://github.com/wfxr/csview.git 4 | [submodule "apps/dog"] 5 | path = apps/dog 6 | url = https://github.com/ogham/dog.git 7 | [submodule "apps/gping"] 8 | path = apps/gping 9 | url = https://github.com/orf/gping.git 10 | [submodule "apps/oha"] 11 | path = apps/oha 12 | url = https://github.com/hatoo/oha.git 13 | [submodule "apps/charge-lnd"] 14 | path = apps/charge-lnd 15 | url = https://github.com/accumulator/charge-lnd.git 16 | [submodule "apps/rebalance-lnd"] 17 | path = apps/rebalance-lnd 18 | url = https://github.com/C-Otto/rebalance-lnd.git 19 | [submodule "apps/suez"] 20 | path = apps/suez 21 | url = https://github.com/prusnak/suez.git 22 | [submodule "apps/lntop"] 23 | path = apps/lntop 24 | url = https://github.com/edouardparis/lntop.git 25 | [submodule "apps/igniter"] 26 | path = apps/igniter 27 | url = https://github.com/RooSoft/igniter.git 28 | [submodule "apps/perfectly-balanced"] 29 | path = apps/perfectly-balanced 30 | url = https://github.com/cuaritas/perfectly-balanced.git 31 | [submodule "apps/sc-im"] 32 | path = apps/sc-im 33 | url = https://github.com/andmarti1424/sc-im.git 34 | [submodule "apps/ttyd"] 35 | path = apps/ttyd 36 | url = https://github.com/tsl0922/ttyd.git 37 | [submodule "apps/libwebsockets"] 38 | path = apps/libwebsockets 39 | url = https://libwebsockets.org/repo/libwebsockets 40 | [submodule "apps/circuitbreaker"] 41 | path = apps/circuitbreaker 42 | url = https://github.com/lightningequipment/circuitbreaker.git 43 | [submodule "apps/whatsat"] 44 | path = apps/whatsat 45 | url = https://github.com/joostjager/whatsat.git 46 | [submodule "apps/weechat"] 47 | path = apps/weechat 48 | url = https://github.com/weechat/weechat.git 49 | [submodule "apps/lndmanage"] 50 | path = apps/lndmanage 51 | url = https://github.com/bitromortac/lndmanage.git 52 | -------------------------------------------------------------------------------- /Dockerfile.tmpl: -------------------------------------------------------------------------------- 1 | ARG bitcoin_version=22.0 2 | ARG lnd_version=v0.14.2-beta 3 | 4 | ARG balanceofsatoshis_tag=v11.55.0 5 | 6 | ARG node_version=16.14.0 7 | 8 | ############### 9 | FROM debian:${DEBIAN_VERSION}-slim as builder 10 | ARG arch 11 | 12 | RUN apt-get update \ 13 | && apt-get install -y asciidoctor bison build-essential cmake curl gnupg libaspell-dev libcurl4-gnutls-dev libgcrypt20-dev libjson-c-dev libncursesw5-dev libgnutls28-dev libwebsockets-dev pkg-config python3-dev zlib1g-dev \ 14 | && apt clean all 15 | 16 | WORKDIR /build 17 | COPY . /build 18 | 19 | ARG bitcoin_version 20 | RUN if [ "$arch" = "arm64" ]; then export btc_arch=aarch64; else export btc_arch=x86_64; fi \ 21 | && curl -sSLO https://bitcoincore.org/bin/bitcoin-core-${bitcoin_version}/bitcoin-${bitcoin_version}-${btc_arch}-linux-gnu.tar.gz \ 22 | && curl -sSLO https://bitcoincore.org/bin/bitcoin-core-${bitcoin_version}/SHA256SUMS \ 23 | && sha256sum --ignore-missing --check SHA256SUMS \ 24 | && tar xzf bitcoin-${bitcoin_version}-${btc_arch}-linux-gnu.tar.gz \ 25 | && mv bitcoin-${bitcoin_version} /bitcoin 26 | 27 | ARG lnd_version 28 | RUN curl -sSLO https://github.com/lightningnetwork/lnd/releases/download/${lnd_version}/lnd-linux-${arch}-${lnd_version}.tar.gz \ 29 | && curl -sSLO https://github.com/lightningnetwork/lnd/releases/download/${lnd_version}/manifest-guggero-${lnd_version}.sig \ 30 | && curl -sSLO https://github.com/lightningnetwork/lnd/releases/download/${lnd_version}/manifest-${lnd_version}.txt \ 31 | && curl https://raw.githubusercontent.com/lightningnetwork/lnd/master/scripts/keys/guggero.asc | gpg --import \ 32 | && gpg --verify manifest-guggero-${lnd_version}.sig manifest-${lnd_version}.txt \ 33 | && tar xzf lnd-linux-${arch}-${lnd_version}.tar.gz \ 34 | && mv lnd-linux-${arch}-${lnd_version} /lnd 35 | 36 | RUN cd /build/apps/libwebsockets && mkdir build && cd build && cmake .. -DLWS_WITH_LIBUV=ON && make && make install 37 | 38 | RUN cd /build/apps/sc-im/src && make 39 | 40 | RUN cd /build/apps/ttyd && mkdir build && cd build && cmake .. && make 41 | 42 | RUN cd /build/apps/weechat \ 43 | && mkdir build \ 44 | && cd build \ 45 | && cmake .. -DENABLE_PHP=OFF -DENABLE_PERL=OFF -DENABLE_RUBY=OFF -DENABLE_TCL=OFF -DENABLE_LUA=OFF -DENABLE_GUILE=OFF \ 46 | && make \ 47 | && make install \ 48 | && asciidoctor -b manpage /build/apps/weechat/doc/en/weechat.1.en.adoc 49 | 50 | ############### 51 | FROM python:3 as python-builder 52 | 53 | RUN apt-get update \ 54 | && apt-get install -y build-essential gzip pandoc \ 55 | && apt clean all 56 | 57 | RUN pip install jinja2-cli 58 | 59 | RUN curl -sSL https://install.python-poetry.org | python - 60 | 61 | WORKDIR /build 62 | COPY . /build 63 | 64 | RUN cd /build/apps/lndmanage && python -m venv .venv 65 | ENV PATH="/build/apps/lndmanage/.venv/bin:$PATH" 66 | RUN cd /build/apps/lndmanage && pip install wheel && pip install -r requirements.txt 67 | 68 | RUN cd /build/apps/suez && /root/.local/bin/poetry export -f requirements.txt --output requirements.txt --without-hashes 69 | 70 | RUN jinja2 /build/apps/apps.7.md /build/apps/apps.json | pandoc -s -t man | gzip > /build/apps/apps.7.gz 71 | 72 | RUN mkdir -p /opt \ 73 | && mv \ 74 | /build/apps/charge-lnd/ \ 75 | /build/apps/igniter/ \ 76 | /build/apps/lndmanage/ \ 77 | /build/apps/perfectly-balanced/ \ 78 | /build/apps/rebalance-lnd/ \ 79 | /build/apps/suez/ \ 80 | /opt 81 | 82 | ############### 83 | FROM golang:1.17-${DEBIAN_VERSION} AS golang-builder 84 | ARG arch 85 | 86 | RUN apt-get update \ 87 | && apt-get install -y build-essential \ 88 | && apt clean all 89 | 90 | WORKDIR /build 91 | COPY . /build 92 | 93 | ENV GOARCH=${arch} 94 | ENV GOOS=linux 95 | 96 | RUN cd /build/apps/circuitbreaker && mkdir bin && go build -o bin/circuitbreaker 97 | 98 | RUN cd /build/apps/lntop && mkdir bin && go build -o bin/lntop cmd/lntop/main.go 99 | 100 | RUN cd /build/apps/whatsat && mkdir bin && go build -o bin/whatsat 101 | 102 | ############### 103 | FROM rust:slim-${DEBIAN_VERSION} AS rust-builder 104 | 105 | RUN apt-get update \ 106 | && apt-get install -y gzip libssl-dev pandoc pkg-config \ 107 | && apt clean all 108 | 109 | WORKDIR /build 110 | COPY . /build 111 | 112 | ENV CARGO_TARGET_DIR=/build/target 113 | 114 | RUN cd /build/apps/csview && cargo build --release 115 | 116 | RUN cd /build/apps/dog && cargo build --release 117 | RUN pandoc /build/apps/dog/man/dog.1.md -s -t man | gzip > /build/apps/dog/man/dog.1.gz 118 | 119 | RUN cd /build/apps/gping && cargo build --release 120 | 121 | RUN cd /build/apps/oha && cargo build --release 122 | 123 | ############### 124 | FROM python:3.8-slim-${DEBIAN_VERSION} 125 | 126 | ARG node_version 127 | 128 | ARG balanceofsatoshis_tag 129 | 130 | ARG arch 131 | 132 | RUN echo "deb http://deb.debian.org/debian ${DEBIAN_VERSION}-backports main" | tee -a /etc/apt/sources.list \ 133 | && apt update \ 134 | && apt upgrade -y \ 135 | && apt install -y --no-install-recommends \ 136 | bc \ 137 | ca-certificates \ 138 | curl \ 139 | figlet \ 140 | git \ 141 | iputils-ping \ 142 | jq \ 143 | less \ 144 | libaspell15 \ 145 | libc6 \ 146 | libcap2 \ 147 | libpython3.7 \ 148 | libssl1.1 \ 149 | libuv1 \ 150 | links \ 151 | man \ 152 | mc \ 153 | micro \ 154 | nano \ 155 | procps \ 156 | python3-pip \ 157 | screen \ 158 | sysstat \ 159 | telnet \ 160 | tini \ 161 | tmux \ 162 | vim \ 163 | xz-utils \ 164 | zlib1g \ 165 | && apt clean all \ 166 | && rm -rf /var/lib/apt/lists/* \ 167 | && if [ "$arch" = "amd64" ]; then export node_arch=x64; else export node_arch=arm64; fi \ 168 | && curl -sSLO "https://nodejs.org/dist/v$node_version/node-v$node_version-linux-$node_arch.tar.xz" \ 169 | && tar -xf "node-v$node_version-linux-$node_arch.tar.xz" && rm -f "/node-v$node_version-linux-$node_arch.tar.xz" \ 170 | && cd "/node-v$node_version-linux-$node_arch" && cp -r bin lib share /usr/local \ 171 | && cd / && rm -rf "node-v$node_version-linux-$node_arch" \ 172 | && pip3 install --upgrade pip \ 173 | && pip3 install btc2fiat \ 174 | && npm i -g balanceofsatoshis@${balanceofsatoshis_tag} \ 175 | && npm cache clean --force 176 | 177 | COPY --from=python-builder /opt/ /opt/ 178 | 179 | ENV PATH="/opt/lndmanage/.venv/bin:$PATH" LD_LIBRARY_PATH=/usr/local/lib/ 180 | 181 | RUN chmod +x /opt/igniter/igniter.sh /opt/perfectly-balanced/perfectlybalanced.sh \ 182 | && cd /opt/charge-lnd \ 183 | && \ 184 | && cd /opt/lndmanage \ 185 | && \ 186 | && cd /opt/rebalance-lnd \ 187 | && \ 188 | && cd /opt/suez \ 189 | && 190 | 191 | COPY \ 192 | --from=builder \ 193 | /bitcoin/bin/bitcoin-cli \ 194 | /lnd/lncli \ 195 | /build/apps/sc-im/src/sc-im \ 196 | /build/apps/sc-im/src/scopen \ 197 | /build/apps/ttyd/build/ttyd \ 198 | /build/apps/weechat/build/src/gui/curses/normal/weechat \ 199 | /usr/local/bin/ 200 | COPY \ 201 | --from=builder \ 202 | /usr/local/lib/libwebsockets.so \ 203 | /usr/local/lib/libwebsockets.so.19 \ 204 | /usr/local/lib/libwebsockets-evlib_uv.so \ 205 | /usr/local/lib/ 206 | COPY \ 207 | --from=builder \ 208 | /usr/local/lib/weechat/plugins/ \ 209 | /usr/local/lib/weechat/plugins/ 210 | 211 | COPY \ 212 | --from=golang-builder \ 213 | /build/apps/circuitbreaker/bin/circuitbreaker \ 214 | /build/apps/lntop/bin/lntop \ 215 | /build/apps/whatsat/bin/whatsat \ 216 | /usr/local/bin/ 217 | 218 | COPY \ 219 | --from=builder \ 220 | /bitcoin/share/man/man1/bitcoin-cli.1 \ 221 | /build/apps/sc-im/src/sc-im.1 \ 222 | /build/apps/weechat/doc/en/weechat.1 \ 223 | /usr/local/share/man/man1/ 224 | COPY --from=python-builder /build/apps/apps.7.gz /usr/share/man/man7/ 225 | COPY --from=golang-builder /build/apps/circuitbreaker/circuitbreaker-example.yaml /opt/circuitbreaker/ 226 | COPY --from=rust-builder /build/apps/dog/man/dog.1.gz /usr/local/share/man/man1/ 227 | 228 | COPY \ 229 | --from=rust-builder \ 230 | /build/target/release/csview \ 231 | /build/target/release/dog \ 232 | /build/target/release/gping \ 233 | /build/target/release/oha \ 234 | /usr/local/bin/ 235 | 236 | COPY motd /etc/motd 237 | COPY start.sh lsh_exec.sh / 238 | RUN chmod +x /start.sh \ 239 | && groupadd -r lnshell --gid=1000 \ 240 | && useradd -r -g lnshell --uid=1000 --create-home --shell /bin/bash lnshell 241 | 242 | USER lnshell 243 | WORKDIR /home/lnshell 244 | 245 | COPY --chown=lnshell:lnshell install-apps.sh bin/* /home/lnshell/.local/bin/ 246 | COPY --chown=lnshell:lnshell apps/apps.json /home/lnshell/.local/share/ 247 | 248 | ARG version 249 | RUN /bin/bash /home/lnshell/.local/bin/install-apps.sh \ 250 | && chmod +x /home/lnshell/.local/bin/* \ 251 | && echo "export PATH=/home/lnshell/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" >> /home/lnshell/.bashrc \ 252 | && echo "cat /etc/motd" >> /home/lnshell/.bashrc \ 253 | && echo "${version}" > /home/lnshell/.lnshell-version 254 | 255 | EXPOSE 7681 256 | 257 | ENV USERNAME=umbrel APP_PASSWORD= 258 | 259 | CMD [ "/start.sh" ] 260 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021-2022 Ioan Bizău 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lightning Shell 2 | 3 | Please see [lightningshell.app](https://lightningshell.app) for more information about **Lightning Shell**. 4 | 5 | ## Running 6 | 7 | **The recommended way to run *Lightning Shell* is from your personal server's dashboard.** 8 | 9 | Keep reading if you want to build it yourself. This is **not** recommended for the average user. Follow these instructions only if you *really* know what you are doing! 10 | 11 | ## Building 12 | 13 | 1. Edit `Dockerfile.tmpl` as needed. 14 | 1. Run `./generate-dockerfiles.sh` to generate Dockerfiles based on **Debian Buster** and **Debian Bullseye**. 15 | 1. Build the image using something like this: `docker buildx build --platform=linux/arm64 --build-arg arch=arm64 --build-arg version=dev --file Dockerfile.bullseye .` 16 | * make sure you build using the desired platform (`arm64` or `amd64`) and base image (`.buster` or `.bullseye`) 17 | * pass something like `--tag X/Y:Z --output "type=registry"` in order to publish the image to your container registry so you can pull it on your personal server 18 | -------------------------------------------------------------------------------- /apps/apps.7.md: -------------------------------------------------------------------------------- 1 | % apps(7) 2 | % Ioan Bizău 3 | % 2022-02-06 4 | 5 | # NAME 6 | 7 | apps - A list of apps available in the Lightning Shell 8 | 9 | # DESCRIPTION 10 | 11 | {% for cat in categories %} 12 | ## {{ cat.name }} tools 13 | {% for app in apps %} 14 | {% if app.category == cat.id %} 15 | * {{ app.name }} - {{ app.url }} 16 | 17 | {{ app.description }} 18 | {% endif %} 19 | {% endfor %} 20 | {% endfor %} -------------------------------------------------------------------------------- /apps/apps.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": [ 3 | { 4 | "id": "bitcoin", 5 | "name": "General Bitcoin node management" 6 | }, 7 | { 8 | "id": "ln", 9 | "name": "General Lightning node management" 10 | }, 11 | { 12 | "id": "ln-fees", 13 | "name": "Lightning node fee management" 14 | }, 15 | { 16 | "id": "ln-rebalance", 17 | "name": "Lightning node rebalancing" 18 | }, 19 | { 20 | "id": "market", 21 | "name": "Market analysis" 22 | }, 23 | { 24 | "id": "data", 25 | "name": "Data processing" 26 | }, 27 | { 28 | "id": "net", 29 | "name": "Networking" 30 | }, 31 | { 32 | "id": "social", 33 | "name": "Social" 34 | } 35 | ], 36 | "apps": [ 37 | { 38 | "name": "bitcoin-cli", 39 | "category": "bitcoin", 40 | "description": "Bitcoin Core CLI", 41 | "url": "https://bitcoincore.org", 42 | "run": "/usr/local/bin/bitcoin-cli -rpcconnect=${BITCOIN_IP} -rpcport=${BITCOIN_RPC_PORT} -rpcuser=${BITCOIN_RPC_USER} -rpcpassword=${BITCOIN_RPC_PASS} $@" 43 | }, 44 | { 45 | "name": "bos", 46 | "category": "ln", 47 | "description": "Balance of Satoshis - Commands for working with LND balances", 48 | "url": "https://github.com/alexbosworth/balanceofsatoshis", 49 | "run": "bos-config && /usr/local/bin/bos $@ --node=mainnode" 50 | }, 51 | { 52 | "name": "btc2fiat", 53 | "category": "market", 54 | "description": "Bitcoin price expressed in fiat currency. As simple as that.", 55 | "url": "https://github.com/ibz/btc2fiat", 56 | "run": "/usr/local/bin/btc2fiat $@" 57 | }, 58 | { 59 | "name": "charge-lnd", 60 | "category": "ln-fees", 61 | "description": "A simple policy based fee manager for LND", 62 | "url": "https://github.com/accumulator/charge-lnd", 63 | "run": "/opt/charge-lnd/charge_lnd/charge_lnd.py --grpc=${LND_IP}:${LND_GRPC_PORT} --lnddir=/lnd $@" 64 | }, 65 | { 66 | "name": "circuitbreaker", 67 | "category": "ln", 68 | "description": "Firewall for your LND", 69 | "url": "https://github.com/lightningequipment/circuitbreaker", 70 | "run": "circuitbreaker-config && /usr/local/bin/circuitbreaker $@" 71 | }, 72 | { 73 | "name": "csview", 74 | "category": "data", 75 | "description": "A high performance CSV viewer", 76 | "url": "https://github.com/wfxr/csview", 77 | "run": "/usr/local/bin/csview $@" 78 | }, 79 | { 80 | "name": "dog", 81 | "category": "net", 82 | "description": "A command-line DNS client", 83 | "url": "https://github.com/ogham/dog", 84 | "run": "/usr/local/bin/dog $@" 85 | }, 86 | { 87 | "name": "gping", 88 | "category": "net", 89 | "description": "Ping, but with a graph", 90 | "url": "https://github.com/orf/gping", 91 | "run": "/usr/local/bin/gping $@" 92 | }, 93 | { 94 | "name": "igniter", 95 | "category": "ln-rebalance", 96 | "description": "Circular rebalancing by sending a payment back to yourself using a specific route", 97 | "url": "https://github.com/RooSoft/igniter", 98 | "run": "igniter-config && /opt/igniter/igniter.sh $@" 99 | }, 100 | { 101 | "name": "lncli", 102 | "category": "ln", 103 | "description": "LND's command line interface", 104 | "url": "https://github.com/lightningnetwork/lnd", 105 | "run": "/usr/local/bin/lncli --rpcserver=${LND_IP}:${LND_GRPC_PORT} --lnddir=/lnd $@" 106 | }, 107 | { 108 | "name": "lndmanage", 109 | "category": "ln", 110 | "description": "Channel management tool", 111 | "url": "https://github.com/bitromortac/lndmanage", 112 | "run": "lndmanage-config && /usr/local/bin/lndmanage $@" 113 | }, 114 | { 115 | "name": "lntop", 116 | "category": "lntop", 117 | "description": "LN terminal dashboard", 118 | "url": "https://github.com/edouardparis/lntop", 119 | "run": "LND_ADDRESS=\"//${LND_IP}:${LND_GRPC_PORT}\" CERT_PATH=/lnd/tls.cert MACAROON_PATH=/lnd/data/chain/bitcoin/${BITCOIN_NETWORK:-mainnet}/readonly.macaroon /usr/local/bin/lntop $@" 120 | }, 121 | { 122 | "name": "oha", 123 | "category": "net", 124 | "description": "HTTP load generator", 125 | "url": "https://github.com/hatoo/oha", 126 | "run": "/usr/local/bin/oha $@" 127 | }, 128 | { 129 | "name": "perfectly-balanced", 130 | "category": "ln-rebalance", 131 | "description": "Script to make your LND node perfectly balanced as everything in life should be", 132 | "url": "https://github.com/cuaritas/perfectly-balanced", 133 | "run": "if [ $# -eq 0 ]; then LND_DIR=/lnd REBALANCE_LND_FILEPATH=/opt/rebalance-lnd/rebalance.py /opt/perfectly-balanced/perfectlybalanced.sh list; else LND_DIR=/lnd REBALANCE_LND_FILEPATH=/opt/rebalance-lnd/rebalance.py /opt/perfectly-balanced/perfectlybalanced.sh $@; fi" 134 | }, 135 | { 136 | "name": "rebalance-lnd", 137 | "category": "ln-rebalance", 138 | "description": "A script that can be used to balance lightning channels of a LND node", 139 | "url": "https://github.com/C-Otto/rebalance-lnd", 140 | "run": "/opt/rebalance-lnd/rebalance.py --grpc=${LND_IP}:${LND_GRPC_PORT} --lnddir=/lnd $@" 141 | }, 142 | { 143 | "name": "sc-im", 144 | "category": "data", 145 | "description": "Spreadsheet program for your terminal", 146 | "url": "https://github.com/andmarti1424/sc-im", 147 | "run": "/usr/local/bin/sc-im $@" 148 | }, 149 | { 150 | "name": "suez", 151 | "category": "ln-fees", 152 | "description": "Tool for pretty printing and optimizing Lightning Network channels", 153 | "url": "https://github.com/prusnak/suez", 154 | "run": "/opt/suez/suez --client-args=--rpcserver=${LND_IP}:${LND_GRPC_PORT} --client-args=--lnddir=/lnd $@" 155 | }, 156 | { 157 | "name": "weechat", 158 | "category": "social", 159 | "description": "The extensible chat client", 160 | "url": "https://weechat.org/", 161 | "run": "/usr/local/bin/weechat $@" 162 | }, 163 | { 164 | "name": "whatsat", 165 | "category": "social", 166 | "description": "End-to-end encrypted, onion-routed, censorship-resistant, peer-to-peer instant messaging over LN", 167 | "url": "https://github.com/joostjager/whatsat", 168 | "run": "/usr/local/bin/whatsat --rpcserver ${LND_IP}:${LND_GRPC_PORT} --lnddir /lnd --tlscertpath /lnd/tls.cert --macaroonpath /lnd/data/chain/bitcoin/${BITCOIN_NETWORK:-mainnet}/admin.macaroon $@" 169 | } 170 | ]} -------------------------------------------------------------------------------- /bin/about: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | version=`cat /home/lnshell/.lnshell-version` 4 | 5 | echo 6 | cat << LIGHTNING 7 | ██╗ ██╗ ██████╗ ██╗ ██╗████████╗███╗ ██╗██╗███╗ ██╗ ██████╗ 8 | ██║ ██║██╔════╝ ██║ ██║╚══██╔══╝████╗ ██║██║████╗ ██║██╔════╝ 9 | ██║ ██║██║ ███╗███████║ ██║ ██╔██╗ ██║██║██╔██╗ ██║██║ ███╗ 10 | ██║ ██║██║ ██║██╔══██║ ██║ ██║╚██╗██║██║██║╚██╗██║██║ ██║ 11 | ███████╗██║╚██████╔╝██║ ██║ ██║ ██║ ╚████║██║██║ ╚████║╚██████╔╝ 12 | ╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═══╝╚═╝╚═╝ ╚═══╝ ╚═════╝ 13 | LIGHTNING 14 | cat << SHELL 15 | ███████╗██╗ ██╗███████╗██╗ ██╗ 16 | ██╔════╝██║ ██║██╔════╝██║ ██║ 17 | ███████╗███████║█████╗ ██║ ██║ 18 | ╚════██║██╔══██║██╔══╝ ██║ ██║ 19 | ███████║██║ ██║███████╗███████╗███████╗ 20 | ╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝ 21 | SHELL 22 | echo 23 | echo "Lightning Shell ${version} by @ibz / https://ibz.me" 24 | echo 25 | echo "Report issues at https://github.com/ibz/lightning-shell/issues" 26 | echo "Pull Requests are also very welcome!" 27 | echo 28 | echo "Support me by sending sats or opening channels to 0264240e8bbbf6d2e052b92dbfef45487c1e7bc7d50c18db632eedfd8f4291fb84" 29 | echo "Also see my other app https://usocial.me" 30 | echo "Thank you!" 31 | echo 32 | -------------------------------------------------------------------------------- /bin/bos-config: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p /home/lnshell/.bos/mainnode 4 | 5 | if [ ! -f /home/lnshell/.bos/mainnode/credentials.json ]; then 6 | cat << EOF >> /home/lnshell/.bos/mainnode/credentials.json 7 | { 8 | "cert": "$(base64 -w0 /lnd/tls.cert)", 9 | "macaroon": "$(base64 -w0 /lnd/data/chain/bitcoin/${BITCOIN_NETWORK:-mainnet}/admin.macaroon)", 10 | "socket": "${LND_IP}:${LND_GRPC_PORT}" 11 | } 12 | EOF 13 | fi 14 | -------------------------------------------------------------------------------- /bin/circuitbreaker-config: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -f /data/circuitbreaker.yaml ]; then 4 | echo "Adding sample circuitbreaker.yaml to the /data directory, which is persisted between updates." 5 | cp /opt/circuitbreaker/circuitbreaker-example.yaml /data/circuitbreaker.yaml 6 | fi 7 | 8 | if [ ! -f ~/.circuitbreaker/circuitbreaker.yaml ]; then 9 | echo "Linking /data/circuitbreaker.yaml to ~/.circuitbreaker/circuitbreaker.yaml. Editing either of them will have the same effect." 10 | mkdir -p ~/.circuitbreaker 11 | ln -s /data/circuitbreaker.yaml ~/.circuitbreaker/circuitbreaker.yaml 12 | fi 13 | -------------------------------------------------------------------------------- /bin/igniter-config: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -f /data/igniter.conf ]; then 4 | echo "Adding sample igniter.conf to the /data directory, which is persisted between updates." 5 | cp /opt/igniter/igniter.conf /data 6 | fi 7 | 8 | if [ ! -f ~/igniter.conf ]; then 9 | echo "Linking /data/igniter.conf to ~/igniter.conf. Editing either of them will have the same effect." 10 | ln -s /data/igniter.conf ~/ 11 | fi 12 | -------------------------------------------------------------------------------- /bin/lndmanage-config: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir -p /home/lnshell/.lndmanage 4 | 5 | if [ ! -f /home/lnshell/.lndmanage/config.ini ]; then 6 | cat << EOF >> /home/lnshell/.lndmanage/config.ini 7 | [network] 8 | lnd_grpc_host = ${LND_IP}:${LND_GRPC_PORT} 9 | tls_cert_file = /lnd/tls.cert 10 | admin_macaroon_file = /lnd/data/chain/bitcoin/${BITCOIN_NETWORK:-mainnet}/admin.macaroon 11 | EOF 12 | fi 13 | -------------------------------------------------------------------------------- /create-manifest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | IMAGE_NAME=${1} 4 | VERSION=${2} 5 | BASE_IMAGE=${3} 6 | VERSION_PREFIX="${VERSION}-${BASE_IMAGE}" 7 | FINAL_NAME="${IMAGE_NAME}:${VERSION_PREFIX}" 8 | # Manifest name is "${IMAGE_NAME}:${VERSION}" if $4 is true, $FINAL_NAME otherwise 9 | if [[ "${4}" == "true" ]]; then 10 | MANIFEST_NAME="${IMAGE_NAME}:${VERSION}" 11 | else 12 | MANIFEST_NAME="${FINAL_NAME}" 13 | fi 14 | declare -a architectures=("amd64" "arm64") 15 | 16 | for architecture in "${architectures[@]}"; do 17 | echo "Pulling ${VERSION} for ${architecture}..." 18 | docker pull "${FINAL_NAME}-${architecture}" 19 | done 20 | 21 | echo "Creating manifest list..." 22 | for architecture in "${architectures[@]}"; do 23 | echo " ${FINAL_NAME}-${architecture}" 24 | done | xargs docker manifest create "${MANIFEST_NAME}" 25 | 26 | for architecture in "${architectures[@]}"; do 27 | echo "Annotating manifest for ${architecture}..." 28 | docker manifest annotate "${MANIFEST_NAME}" "${FINAL_NAME}-${architecture}" --arch ${architecture} --os linux 29 | done 30 | 31 | echo "Pushing manifest list..." 32 | docker manifest push --purge ${MANIFEST_NAME} 33 | 34 | # If $4 isn't true and $BASE_IMAGE is bullseye, rerun this script with $4 set to true 35 | if [[ "${4}" != "true" && "${BASE_IMAGE}" == "bullseye-slim" ]]; then 36 | ./create-manifest.sh "${IMAGE_NAME}" "${VERSION}" "${BASE_IMAGE}" "true" 37 | fi 38 | -------------------------------------------------------------------------------- /generate-dockerfiles.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | declare -a DEBIAN_VERSIONS=(buster bullseye) 4 | 5 | for debian_version in "${DEBIAN_VERSIONS[@]}"; do 6 | cat < Dockerfile.${debian_version} 7 | # This file was automatically generated by generate-dockerfiles.sh 8 | # Do not edit this file directly. 9 | # Instead, edit Dockerfile.tmpl or generate-dockerfiles.sh, then run ./generate-dockerfiles.sh 10 | EOF 11 | cat Dockerfile.tmpl >> Dockerfile.${debian_version} 12 | sed -i "s/\${DEBIAN_VERSION}/${debian_version}/g" Dockerfile.${debian_version} 13 | done 14 | 15 | # For Buster, we need python3-grpcio and python3-setuptools for Python dependencies and libjson-c3 for ttyd 16 | sed -i "s//python3-grpcio python3-setuptools libjson-c3/g" Dockerfile.buster 17 | # For Bullseye, we need libjson-c5 instead of libjson-c3 18 | sed -i "s//libjson-c5/" Dockerfile.bullseye 19 | 20 | # For Buster we need a special filter to prevent pip from installing grpc, because it would compile it from scratch and that would take too long 21 | sed -i "s//cat requirements.txt | grep -v grpcio > requirements-nogrpcio.txt \&\& pip3 install -r requirements-nogrpcio.txt/g" Dockerfile.buster 22 | # On Bullseye, pip is able to find a prebuilt wheel, so we don't need this filter 23 | sed -i "s//pip3 install -r requirements.txt/g" Dockerfile.bullseye 24 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module lightning-shell 2 | go 1.17 3 | require github.com/lightningequipment/circuitbreaker v0.3.0 4 | require github.com/edouardparis/lntop v0.3.0 5 | -------------------------------------------------------------------------------- /install-apps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while IFS= read -r line; do 4 | FILENAME=/home/lnshell/.local/bin/`echo $line | cut -d " " -f1` 5 | echo "#!/bin/bash" > $FILENAME 6 | echo $line | cut -d " " -f2- >> $FILENAME 7 | chmod +x $FILENAME 8 | done <<< `jq -r '.apps[] | "\(.name) \(.run)"' /home/lnshell/.local/share/apps.json` 9 | -------------------------------------------------------------------------------- /lsh_exec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | script_name=`basename $0` 4 | 5 | if [[ "$script_name" == *"_ni"* ]]; then # non-interactive 6 | extra_param= 7 | else 8 | extra_param="-it" 9 | fi 10 | 11 | lsh=$(docker ps | grep lightning-shell | awk '{print $1}') 12 | docker exec -e PATH=/home/lnshell/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin $extra_param $lsh $@ 13 | -------------------------------------------------------------------------------- /motd: -------------------------------------------------------------------------------- 1 | Welcome to the Lightning Shell! Read more at https://lightningshell.app 2 | 3 | Recently added apps: "circuitbreaker" (firewall for your LND), "lndmanage" (channel management tool), "whatsat" (instant messaging over LN), "weechat" (chat client). See more in-depth changes at https://lightningshell.app/history/ 4 | 5 | Use the /data directory to store files that you don't want to lose (configuration files, custom scripts, etc.)! 6 | 7 | Run "man apps" to read about all available apps. Some apps have their own manual page as well, see for example "man bitcoin-cli". 8 | Run "about" for more details about Lightning Shell. 9 | 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "balanceofsatoshis": "v11.44.0", 4 | "ttyd": "1.0.0" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | btc2fiat 2 | charge-lnd 3 | lndmanage 4 | rebalance-lnd 5 | suez 6 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | if [ -x /data/on_start.sh ]; then 4 | /data/on_start.sh 5 | fi 6 | 7 | if [ ! -x /data/lsh_exec.sh ]; then 8 | cp /lsh_exec.sh /data/lsh_exec.sh 9 | chown lnshell:lnshell /data/lsh_exec.sh 10 | chmod +x /data/lsh_exec.sh 11 | fi 12 | 13 | if [ ! -x /data/lsh_exec_ni.sh ]; then 14 | cp /lsh_exec.sh /data/lsh_exec_ni.sh 15 | chown lnshell:lnshell /data/lsh_exec_ni.sh 16 | chmod +x /data/lsh_exec_ni.sh 17 | fi 18 | 19 | /usr/bin/tini /usr/local/bin/ttyd -- --credential ${USERNAME}:${APP_PASSWORD} bash 20 | --------------------------------------------------------------------------------