diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..45ce9d45 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.git +.github +build +node_modules diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml new file mode 100644 index 00000000..5ee85b5b --- /dev/null +++ b/.github/workflows/push.yml @@ -0,0 +1,47 @@ + +name: Create and publish a Docker image + +on: + push: + branches: ['umbrel-works'] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + attestations: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Log in to the Container registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + + - name: Build and push Docker image + id: push + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..935ab8ed --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM node:18 + +WORKDIR /app + +COPY package*.json /app + +RUN npm i + +COPY . /app + +CMD [ "npm", "start" ] diff --git a/Umbrel/docker-compose.yml b/Umbrel/docker-compose.yml new file mode 100644 index 00000000..7c569e5c --- /dev/null +++ b/Umbrel/docker-compose.yml @@ -0,0 +1,22 @@ +version: "3.7" +services: + app_proxy: + environment: + APP_HOST: lightning-pub + APP_PORT: 1776 + + server: + image: ghcr.io/shocknet/lightning.pub:umbrel-works + volumes: + - "${APP_DATA_DIR}/data:/data" + - "${APP_LIGHTNING_NODE_DATA_DIR}:/lnd:ro" + environment: + LN_BACKEND_TYPE: "LND" + LND_ADDRESS: $APP_LIGHTNING_NODE_IP:$APP_LIGHTNING_NODE_GRPC_PORT + LND_CERT_PATH: "/lnd/tls.cert" + LND_MACAROON_PATH: "/lnd/data/chain/bitcoin/${APP_BITCOIN_NETWORK}/admin.macaroon" + DATABASE_FILE: "/data/db.sqlite" + METRICS_DATABASE_FILE: "/data/metrics.sqlite" + PORT: 1776 + restart: on-failure + stop_grace_period: 1m diff --git a/Umbrel/umbrel-app.yml b/Umbrel/umbrel-app.yml new file mode 100644 index 00000000..5bb9ee2e --- /dev/null +++ b/Umbrel/umbrel-app.yml @@ -0,0 +1,36 @@ + manifestVersion: 1 +id: lightning-pub +category: finance +name: Lightning.Pub +version: "1.0.0" +tagline: lightning, nostr, accounts, lnurl, web +description: >- +"Pub" is a Nostr-native account system designed +to make running Lightning infrastructure for your friends/family/customers +easier than previously thought possible. + + Being Nostr-native eliminates the complexity of configuring your node like a server by using commodity Nostr relays. +These relays, unlike LNURL proxies, are trustless by nature of Nostr's own encryption spec (NIP44). + + Support for optional services are integrated into Pub for operators seeking backward compatibility with legacy LNURLs and Lightning Addresses. + + By solving the networking and programability hurdles, Pub provides Lightning with a 3rd Layer that enables node-runners and + Uncle Jims to more easily bring their personal network into Bitcoin's permissionless economy. In doing so, Pub runners + can keep the Lightning Network decentralized, with custodial scaling that is free of fiat rails, large banks, + and other forms of high-time-preference shitcoinery. +developer: shocknet +website: https://shock.network +dependencies: + - lightning +repo: https://github.com/shocknet/Lightning.Pub +support: https://github.com/shocknet/Lightning.Pub/discussions +port: 1776 +gallery: + - 1.jpg + - 2.jpg + - 3.jpg +path: "" +defaultUsername: "" +defaultPassword: "" +submitter: shocknet +submission: https://github.com/getumbrel/umbrel/pull/334 \ No newline at end of file diff --git a/src/auth.ts b/src/auth.ts index 8c380592..6d7bf07f 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -1,3 +1,5 @@ +import express from 'express'; +import path from 'path'; import { ServerOptions } from "../proto/autogenerated/ts/express_server"; import { AdminContext, MetricsContext } from "../proto/autogenerated/ts/types"; import Main from './services/main' diff --git a/static/backup.html b/static/backup.html new file mode 100644 index 00000000..9f09e81e --- /dev/null +++ b/static/backup.html @@ -0,0 +1,100 @@ + + + + + + + + + + + + Lightning.Pub + + + + +
+ Lightning Pub logo + Lightning Pub logo +
+ +
+
+ +

Backup

+

+ It looks like this is a + new node, it's important + establish backups. +

+
+ +
+ +
+
+
+ In addition to your seed phrase, you'll need a channel backup to +
+
+ recover funds should your node experience a hardware failure. +
+
+
+ It's important always to have the latest version of this backup, +
+
+ fortunately they're small enough to be cached on the Nostr relay. +
+
+
+ If you did not choose the developers relay, be sure your relay has + adequate storage policies to hold NIP78 events. +
+
+
+ +
+ +
+
+ +
+
+ + + + + + diff --git a/static/connect.html b/static/connect.html new file mode 100644 index 00000000..a7048a81 --- /dev/null +++ b/static/connect.html @@ -0,0 +1,77 @@ + + + + + + + + + + + Lightning.Pub + + + + +
+ Lightning Pub logo + Lightning Pub logo +
+ +
+
+ +

Connect

+

+ Who's the Nostr user that owns this node, can recover the backups, and + connect to manage it? +

+
+ +
+ +
+
+

+ strfry.shock.network
npub123abcdefghhhhhhhhhhhhhhh +

+
+

Note: Code contains a one-time pairing secret.

+
+ + +
+ + + + + + + + diff --git a/static/css/backup.css b/static/css/backup.css new file mode 100644 index 00000000..08f98a8b --- /dev/null +++ b/static/css/backup.css @@ -0,0 +1,18 @@ +.description { + font-size: 14px; + color: #a3a3a3; + text-decoration: none solid rgb(163, 163, 163); + text-align: center; + text-shadow: 0px 0px 2px rgba(0, 0, 0, 1); +} + +.warning-text { + font-size: 14px; + color: #c434e0; + font-style: italic; + text-decoration: none solid rgb(196, 52, 224); + text-align: center; + text-shadow: 0px 0px 2px rgba(0, 0, 0, 1); + margin-top: 16px; +} + diff --git a/static/css/liquidity.css b/static/css/liquidity.css new file mode 100644 index 00000000..495f1f93 --- /dev/null +++ b/static/css/liquidity.css @@ -0,0 +1,27 @@ +.question-box { + display: inline-block; + position: relative; + top: -8px; + left: -4px; +} + +.question-box .question-content { + display: none; + position: absolute; + min-width: 280px; + background-color: var(--background-color); + color: #a3a3a3; + padding: 12px; + border: 2px solid #c423e0; + border-radius: 4px; + font-size: 14px; + transform: translate(-50%, -50%); + padding-top: 28px; + z-index: 200; +} + +.question-content .close-button { + position: absolute; + top: 4px; + right: 0; +} diff --git a/static/css/seed.css b/static/css/seed.css new file mode 100644 index 00000000..9f7d4d19 --- /dev/null +++ b/static/css/seed.css @@ -0,0 +1,35 @@ +.seed-box-container { + display: grid; + grid-template-columns: auto auto auto auto auto auto; + justify-content: center; + row-gap: 4px; + column-gap: 12px; +} + +@media (max-width: 680px) { + .seed-box-container { + grid-template-columns: auto auto auto auto; + } +} + +.blur-filter { + filter: blur(5px); +} + +.seed-box { + display: flex; + align-items: center; + gap: 4px; +} + +.reveal-button { + font-size: 14px; + color: #c434e0; + font-style: italic; + text-decoration: none solid rgb(196, 52, 224); + text-align: center; + text-shadow: 0px 0px 2px rgba(0, 0, 0, 1); + background-color: transparent; + border: none; + margin-top: 16px; +} diff --git a/static/css/styles.css b/static/css/styles.css new file mode 100644 index 00000000..fae30a11 --- /dev/null +++ b/static/css/styles.css @@ -0,0 +1,244 @@ +:root { + --background-color: #16191c; + --color: #ffffff; + --color-marked: #ff7700; + --color-linked: #2aabe9; + --gradient: linear-gradient(60deg, #ff7700 0%, #c740c7 100%); + --font-size-h2: 36px; + --font-size-p: 16px; +} + +body { + margin-block-start: 15px; + font-family: Montserrat; + background-color: var(--background-color); + color: var(--color); + text-align: center; + overflow: scroll; +} + +header { + background-color: var(--background-color); + padding-inline: 2%; + display: flex; + flex-direction: row; + align-items: center; + gap: 1rem; +} + +main { + max-width: 500px; + width: 100%; + margin-inline: auto; +} + +* { + box-sizing: border-box; +} + +@media (min-width: 768px) { + body { + zoom: 1.4; + } +} + +@media (min-width: 2000px) { + body { + zoom: 1.6; + } +} + +@media screen and (max-width: 425px) { + header > img:nth-child(1) { + width: 30px; + height: auto; + } + + header > img:nth-child(2) { + width: auto; + height: 26px; + } +} + +input[type="text"] { + background-color: transparent; + padding: 7px 10px; + border: 1px solid #c740c7; + border-radius: 5px; + font-size: 14px; + color: #999999; + box-shadow: 0px 0px 2px rgba(0, 0, 0, 1); +} + +.icon-button { + background-color: transparent; + border: none; +} + +.push-button { + background-color: transparent; + padding: 10px 55px; + font-size: 20px; + color: var(--color); + text-align: center; + box-shadow: 0px 0px 2px rgba(0, 0, 0, 1); + background: linear-gradient(var(--background-color), var(--background-color)) + padding-box, + var(--gradient) border-box; + border-radius: 5px; + border: 2px solid transparent; +} + +h2 { + font-size: var(--font-size-h2); + font-weight: 400; +} + +p { + font-size: var(--font-size-p); +} + +a { + color: var(--color); + text-decoration: none; +} + +.text-gray { + color: #a3a3a3; + margin-block-end: 5px; +} + +.checkbox { + position: relative; +} + +/* Hide the default checkbox */ +.checkbox input[type="checkbox"] { + display: none; +} + +/* Create a new box */ +.checkbox label { + padding-left: 32px; + display: inline-block; + width: 100%; + font-size: 14px; + color: #a3a3a3; + text-decoration: none solid rgb(163, 163, 163); + text-shadow: 0px 0px 2px rgba(0, 0, 0, 1); + text-align: left; +} + +.checkbox .checkbox-shape { + width: 20px; + height: 20px; + background-color: transparent; + border: 1px solid #a3a3a3; + border-radius: 5px; + position: absolute; + top: 50%; + transform: translate(0, -50%); + z-index: -1; +} + +/* Display a checkmark when the checkbox is checked */ +.checkbox input[type="checkbox"]:checked + .checkbox-shape::before { + content: "✔"; + color: #a012c7; + font-size: 20px; + text-align: center; + line-height: 1; +} + +.line { + margin-block: 24px; + background: var(--gradient); + width: 100%; + height: 1px; + margin-inline: auto; +} + +.marked { + color: var(--color-marked); +} + +.linked { + color: var(--color-linked); +} + +.setup-footer > p { + line-height: 4px; +} + +.setup-header { + position: relative; +} + +.setup-header > .back-button { + position: absolute; + top: 0; + left: 0; +} + +.setup-header > h2 { + margin-block-start: 20px; +} + +.setup-header .header-title { + font-size: 16px; + text-align: center; + text-shadow: 0px 0px 2px rgba(0, 0, 0, 1); +} + +#qrcode { + display: flex; + margin: auto; + justify-content: center; + margin-block-start: 40px; + margin-block-end: 15px; +} + +.input-group { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; +} + +.input-group span { + font-size: 16px; + color: #ffffff; + font-weight: bold; + text-decoration: none solid rgb(255, 255, 255); + text-shadow: 0px 0px 2px rgba(0, 0, 0, 1); +} + +.input-group > input { + align-self: center; +} + +footer { + display: flex; + flex-direction: column; + align-items: center; + max-width: 500px; + width: 100%; + margin-inline: auto; + margin-top: 18px; +} + +footer .footer-text { + font-size: 12px; + color: #999999; + text-align: center; +} + +.checkbox-container { + display: flex; + justify-content: center; + margin-top: 12px; +} + +.hidden-button { + visibility: hidden; +} \ No newline at end of file diff --git a/static/img/LightningPub.png b/static/img/LightningPub.png new file mode 100644 index 00000000..1cbc35de Binary files /dev/null and b/static/img/LightningPub.png differ diff --git a/static/img/back.svg b/static/img/back.svg new file mode 100644 index 00000000..dd311c59 --- /dev/null +++ b/static/img/back.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/close.svg b/static/img/close.svg new file mode 100644 index 00000000..1ff717e6 --- /dev/null +++ b/static/img/close.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/pub_logo.png b/static/img/pub_logo.png new file mode 100644 index 00000000..36cc43b4 Binary files /dev/null and b/static/img/pub_logo.png differ diff --git a/static/img/question.svg b/static/img/question.svg new file mode 100644 index 00000000..aafbaff4 --- /dev/null +++ b/static/img/question.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/index.html b/static/index.html new file mode 100644 index 00000000..092684a5 --- /dev/null +++ b/static/index.html @@ -0,0 +1,90 @@ + + + + + + + + + + + Lightning.Pub + + + +
+ Lightning Pub logo + Lightning Pub logo +
+ +
+
+

Setup

+

+ Let's confirm some things before we start this Pub +

+
+ +
+ +
+
+ give this node a name that wallet users will see: + +
+ +
+ If you want to use a specific Nostr relay, enter it now: + +
+ +
+ +
+ +
+ + +
+
+ + + + diff --git a/static/js/backup.js b/static/js/backup.js new file mode 100644 index 00000000..9579648f --- /dev/null +++ b/static/js/backup.js @@ -0,0 +1,11 @@ +$(() => { + $("#backup").click(() => { + const checked = $("#backup").prop("checked"); + const nextButton = $("#next-button"); + if (checked) { + nextButton.removeClass("hidden-button"); + } else { + nextButton.addClass("hidden-button"); + } + }); +}); diff --git a/static/js/liquidity.js b/static/js/liquidity.js new file mode 100644 index 00000000..4418542a --- /dev/null +++ b/static/js/liquidity.js @@ -0,0 +1,9 @@ +$(() => { + $("#show-question").click(() => { + $("#question-content").show(); + }); + + $("#close-question").click(() => { + $("#question-content").hide(); + }); +}); diff --git a/static/js/script.js b/static/js/script.js new file mode 100644 index 00000000..2b980019 --- /dev/null +++ b/static/js/script.js @@ -0,0 +1,10 @@ +$(document).ready(function() { + var qrcode = new QRCode(document.getElementById("qrcode"), { + text: "strfry.shock.network npub123abcdefghhhhhhhhhhhhhhh", + width: 157, + height: 157, + colorDark : "#000000", + colorLight : "#ffffff", + // correctLevel : QRCode.CorrectLevel.H + }); +}); \ No newline at end of file diff --git a/static/js/seed.js b/static/js/seed.js new file mode 100644 index 00000000..2574aa40 --- /dev/null +++ b/static/js/seed.js @@ -0,0 +1,15 @@ +$(() => { + $("#reveal-button").click(() => { + $("#seed-box-container").removeClass("blur-filter"); + }); + + $('#copied').click(() => { + const checked = $("#copied").prop('checked'); + const nextButton = $("#next-button"); + if (checked) { + nextButton.removeClass("hidden-button"); + } else { + nextButton.addClass("hidden-button"); + } + }) +}); diff --git a/static/liquidity.html b/static/liquidity.html new file mode 100644 index 00000000..46bae1e5 --- /dev/null +++ b/static/liquidity.html @@ -0,0 +1,93 @@ + + + + + + + + + + + + Lightning.Pub + + + + +
+ Lightning Pub logo + Lightning Pub logo +
+ +
+
+ +

Liquidity

+

+ How do you want to manage Lightning connectivity? +

+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+ +
+
+ + + + + + diff --git a/static/seed.html b/static/seed.html new file mode 100644 index 00000000..97b07183 --- /dev/null +++ b/static/seed.html @@ -0,0 +1,181 @@ + + + + + + + + + + + + Lightning.Pub + + + + +
+ Lightning Pub logo + Lightning Pub logo +
+ +
+
+ +

Seed Phrase

+

+ Store your seed phrase somewhere safe, you'll need it if something + ever goes wrong with your nodes hard drive. +

+
+ +
+ +
+
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ 1 + albert +
+
+ + + +
+
+ +
+ +
+
+ +
+
+ + + + + + diff --git a/tsconfig.json b/tsconfig.json index d6a10f46..1bff3bae 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -68,4 +68,4 @@ "exclude": [ "./tests" ], -} \ No newline at end of file +}