Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert to fulcrum #1

Merged
merged 15 commits into from
Sep 24, 2024
107 changes: 89 additions & 18 deletions .github/workflows/on-push.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,104 @@
name: Build and publish Docker image on push

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

on: push

env:
DOCKER_CLI_EXPERIMENTAL: enabled
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}

jobs:
build:
name: Build Docker image
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write

steps:
- name: Set BRANCH
run: echo "BRANCH=$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//-/g')" >> $GITHUB_ENV

- name: Login to Docker Hub
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin

- name: Checkout repository
uses: actions/checkout@v4

- name: Checkout project
uses: actions/checkout@v2

# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/[email protected]
with:
cosign-release: 'v2.4.0'

- name: Set up QEMU
uses: docker/setup-qemu-action@v1
uses: docker/setup-qemu-action@v3

# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Setup Docker buildx action
uses: docker/setup-buildx-action@v1
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=schedule
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=ref,event=branch
type=ref,event=pr
type=sha

- name: Run Docker buildx
run: |
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag ${{ secrets.DOCKER_HUB_USER }}/umbrel-electrs:$BRANCH \
--push .
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
# repository is public to avoid leaking data. If you would like to publish
# transparency data even for private images, pass --force to cosign below.
# https://github.com/sigstore/cosign
- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
TAGS: ${{ steps.meta.outputs.tags }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
101 changes: 81 additions & 20 deletions .github/workflows/on-tag.yml
Original file line number Diff line number Diff line change
@@ -1,36 +1,97 @@
name: Build and publish Docker image on tag

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

on:
push:
tags:
- 'v*.*.*'
# Publish semver tags as releases.
tags: [ 'v*.*.*' ]

env:
DOCKER_CLI_EXPERIMENTAL: enabled
# Use docker.io for Docker Hub if empty
REGISTRY: ghcr.io
# github.repository as <account>/<repo>
IMAGE_NAME: ${{ github.repository }}

jobs:
build:
name: Build Docker image
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
# This is used to complete the identity challenge
# with sigstore/fulcio when running outside of PRs.
id-token: write

steps:
- name: Set VERSION
run: echo "VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: Checkout repository
uses: actions/checkout@v4

- name: Login to Docker Hub
run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
# Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer
- name: Install cosign
if: github.event_name != 'pull_request'
uses: sigstore/[email protected]
with:
cosign-release: 'v2.4.0'

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Checkout project
uses: actions/checkout@v2
# Set up BuildKit Docker container builder to be able to build
# multi-platform images and export cache
# https://github.com/docker/setup-buildx-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Set up QEMU
uses: docker/setup-qemu-action@v1
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

# Extract metadata (tags, labels) for Docker
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}

- name: Setup Docker buildx action
uses: docker/setup-buildx-action@v1
# Build and push Docker image with Buildx (don't push on PR)
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Run Docker buildx
run: |
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag ${{ secrets.DOCKER_HUB_USER }}/umbrel-electrs:$VERSION \
--push .
# Sign the resulting Docker image digest except on PRs.
# This will only write to the public Rekor transparency log when the Docker
# repository is public to avoid leaking data. If you would like to publish
# transparency data even for private images, pass --force to cosign below.
# https://github.com/sigstore/cosign
- name: Sign the published Docker image
if: ${{ github.event_name != 'pull_request' }}
env:
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
TAGS: ${{ steps.meta.outputs.tags }}
DIGEST: ${{ steps.build-and-push.outputs.digest }}
# This step uses the identity token to provision an ephemeral certificate
# against the sigstore community Fulcio instance.
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build Stage
FROM node:16-buster-slim AS umbrel-electrs-builder
FROM node:16-buster-slim AS umbrel-fulcrum-builder

# Install tools
# RUN apt-get update \
Expand All @@ -22,10 +22,10 @@ COPY . .
RUN npm run build:frontend

# Final image
FROM node:16-buster-slim AS umbrel-electrs
FROM node:16-buster-slim AS umbrel-fulcrum

# Copy built code from build stage to '/app' directory
COPY --from=umbrel-electrs-builder /app /app
COPY --from=umbrel-fulcrum-builder /app /app

# Change directory to '/app'
WORKDIR /app
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<a href="https://umbrel.com">
<img src="https://i.imgur.com/5u1Eweg.jpg" alt="Logo">
</a>
<h1 align="center">Electrs for Umbrel</h1>
<h1 align="center">Fulcrum for Umbrel</h1>
<p align="center">
Run an Electrum server on your Umbrel personal server. An official app by Umbrel. Powered by Electrs.
Run an Electrum server on your Umbrel personal server. An official app by Umbrel. Powered by Fulcrum.
<br />
<a href="https://umbrel.com"><strong>umbrel.com »</strong></a>
<br />
Expand Down Expand Up @@ -32,12 +32,12 @@ This app can be installed in one click via the Umbrel App Store.

We welcome and appreciate new contributions!

If you're a developer looking to help but not sure where to begin, look for [these issues](https://github.com/getumbrel/umbrel-electrs/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) that have specifically been marked as being friendly to new contributors.
If you're a developer looking to help but not sure where to begin, look for [these issues](https://github.com/getumbrel/umbrel-fulcrum/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) that have specifically been marked as being friendly to new contributors.

If you're looking for a bigger challenge, before opening a pull request please [create an issue](https://github.com/getumbrel/umbrel-electrs/issues/new/choose) or [join our community chat](https://t.me/getumbrel) to get feedback, discuss the best way to tackle the challenge, and to ensure that there's no duplication of work.
If you're looking for a bigger challenge, before opening a pull request please [create an issue](https://github.com/getumbrel/umbrel-fulcrum/issues/new/choose) or [join our community chat](https://t.me/getumbrel) to get feedback, discuss the best way to tackle the challenge, and to ensure that there's no duplication of work.

---

[![License](https://img.shields.io/github/license/getumbrel/umbrel-electrs?color=%235351FB)](https://github.com/getumbrel/umbrel-electrs/blob/master/LICENSE.md)
[![License](https://img.shields.io/github/license/getumbrel/umbrel-fulcrum?color=%235351FB)](https://github.com/getumbrel/umbrel-fulcrum/blob/master/LICENSE.md)

[umbrel.com](https://umbrel.com)
4 changes: 2 additions & 2 deletions apps/backend/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const errorHandleMiddleware = require("middlewares/errorHandling.js");
const logger = require("utils/logger.js");

const ping = require("routes/ping.js");
const electrs = require("routes/v1/electrs.js");
const fulcrum = require("routes/v1/fulcrum.js");
const app = express();

app.use(bodyParser.json());
Expand All @@ -30,7 +30,7 @@ app.use(morgan(logger.morganConfiguration));
app.use("/", express.static("../frontend/dist"));

app.use("/ping", ping);
app.use("/v1/electrs", electrs);
app.use("/v1/fulcrum", fulcrum);

app.use(errorHandleMiddleware);
app.use((req, res) => {
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "umbrel-electrs-backend",
"name": "umbrel-fulcrum-backend",
"version": "0.1.12",
"description": "Middleware for Umbrel Node",
"author": "Umbrel",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const express = require("express");
const router = express.Router();
const electrsService = require("services/electrs");
const fulcrumService = require("services/fulcrum");

const systemLogic = require("logic/system.js");
const safeHandler = require("utils/safeHandler");
Expand All @@ -17,7 +17,7 @@ router.get(
"/version",
safeHandler(async (req, res) => {
try {
const version = await electrsService.getVersion();
const version = await fulcrumService.getVersion();
return res.status(200).json(version);
} catch (e) {
console.error("version error: ", e);
Expand All @@ -30,7 +30,7 @@ router.get(
"/syncPercent",
safeHandler(async (req, res) => {
try {
const syncPercent = await electrsService.syncPercent();
const syncPercent = await fulcrumService.syncPercent();

return res.status(200).json(syncPercent);
} catch (e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
const ElectrumClient = require("@lily-technologies/electrum-client");
const bitcoindService = require("services/bitcoind");

const ELECTRS_HOST = process.env.ELECTRS_HOST || "0.0.0.0";
const rpcClient = new ElectrumClient(50001, ELECTRS_HOST, "tcp");
const FULCRUM_HOST = process.env.FULCRUM_HOST || "0.0.0.0";
const FULCRUM_PORT = parseInt(process.env.FULCRUM_PORT) || 50001;
const rpcClient = new ElectrumClient(FULCRUM_PORT, FULCRUM_HOST, "tcp");

async function getVersion() {
const initClient = await rpcClient.initElectrum({
client: "umbrel",
version: "1.4"
});

// versionInfo[0] comes in as electrs/0.9.4, so we parse
// versionInfo[0] comes in as fulcrum/0.9.4, so we parse
const version = initClient.versionInfo[0].substring(
initClient.versionInfo[0].indexOf("/") + 1
);
initClient.close()
return version;
}

// This is a little hacky way of determining if electrs is sync'd to bitcoind
// This is a little hacky way of determining if fulcrum is sync'd to bitcoind
// see https://github.com/romanz/electrs/pull/543#issuecomment-973078262
async function syncPercent() {
// first, check if bitcoind isn't still IBD
Expand All @@ -28,16 +30,17 @@ async function syncPercent() {
return 0;
}

// if not IBD, then check bitcoind height to electrs height
// if not IBD, then check bitcoind height to fulcrum height
const initClient = await rpcClient.initElectrum({
client: "umbrel",
version: "1.4"
});

const {
height: electrsHeight
height: fulcrumHeight
} = await initClient.blockchainHeaders_subscribe();
return (electrsHeight / bitcoindResponse.blocks) * 100;
initClient.close()
return (fulcrumHeight / bitcoindResponse.blocks) * 100;
}

module.exports = {
Expand Down
2 changes: 1 addition & 1 deletion apps/backend/utils/const.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable id-length */
module.exports = {
REQUEST_CORRELATION_NAMESPACE_KEY: "umbrel-electrs-request",
REQUEST_CORRELATION_NAMESPACE_KEY: "umbrel-fulcrum-request",
REQUEST_CORRELATION_ID_KEY: "reqId",

ELECTRUM_HIDDEN_SERVICE:
Expand Down
Loading