';
diff --git a/app/sovran_systemsos_web/static/js/tiles.js b/app/sovran_systemsos_web/static/js/tiles.js
index 7d8b974..045ccd2 100644
--- a/app/sovran_systemsos_web/static/js/tiles.js
+++ b/app/sovran_systemsos_web/static/js/tiles.js
@@ -9,39 +9,8 @@ var _btcSyncPrev = {};
function _renderBip110Badge(bip110) {
if (!bip110) return '';
var state = bip110.state || 'unknown';
- var label, cls, title;
- switch (state) {
- case 'active':
- label = 'BIP\u2011110: Active \u2713';
- cls = 'tile-bip110-badge--active';
- title = 'BIP-110 is active on this node';
- break;
- case 'locked_in':
- label = 'BIP\u2011110: Locked In';
- cls = 'tile-bip110-badge--locked_in';
- title = 'BIP-110 is locked in and will activate shortly';
- break;
- case 'signaling':
- label = 'BIP\u2011110: Signaling';
- cls = 'tile-bip110-badge--signaling';
- title = 'Node is signaling readiness for BIP-110';
- break;
- case 'not_signaling':
- label = 'BIP\u2011110: Not Signaling';
- cls = 'tile-bip110-badge--not_signaling';
- title = 'Node supports BIP-110 but is not signaling this period';
- break;
- case 'unsupported':
- label = 'BIP\u2011110: Not Supported';
- cls = 'tile-bip110-badge--unsupported';
- title = 'This node build does not include BIP-110';
- break;
- default:
- label = 'BIP\u2011110: \u2014';
- cls = 'tile-bip110-badge--unknown';
- title = 'Status unavailable (node syncing or RPC not ready)';
- }
- return '
';
}
// ── Render: initial build ─────────────────────────────────────────
From 44737f5571a4a0670d0a3206185195d9c253bd49 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 4 Jun 2026 19:49:01 +0000
Subject: [PATCH 010/140] Fix docstring accuracy, extract _firstElementFromHtml
helper, address all code review feedback
---
app/sovran_systemsos_web/server.py | 6 +++---
app/sovran_systemsos_web/static/js/tiles.js | 20 +++++++++-----------
2 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/app/sovran_systemsos_web/server.py b/app/sovran_systemsos_web/server.py
index 2eea02f..a8e043d 100644
--- a/app/sovran_systemsos_web/server.py
+++ b/app/sovran_systemsos_web/server.py
@@ -2415,15 +2415,15 @@ def _get_bip110_status() -> dict:
Resolution order (authoritative → fallback → honest unknown):
1. ``getdeploymentinfo`` (authoritative) — scan the ``deployments`` dict for an
- entry whose key (case-insensitive) contains "bip110" or "110". The exact
+ entry whose key (case-insensitive) contains "bip110". The exact
deployment key name is **not** hard-coded because it may vary across Knots
releases; detection is intentionally generic so that a name change degrades
to "unknown" rather than producing a false result.
2. Subversion fallback — if getdeploymentinfo is unavailable or yields no
recognisable BIP-110 entry, inspect the ``subversion`` field from
- ``getnetworkinfo``. A case-insensitive match for "bip110" or "uasf" in the
- subversion string is treated as "signaling".
+ ``getnetworkinfo``. A case-insensitive match for "bip110" or "uasf-bip110"
+ in the subversion string is treated as "signaling".
3. Unknown — if the node is entirely unreachable or neither source is
conclusive, return state="unknown", signaling=False, source="none".
diff --git a/app/sovran_systemsos_web/static/js/tiles.js b/app/sovran_systemsos_web/static/js/tiles.js
index 045ccd2..e07bf04 100644
--- a/app/sovran_systemsos_web/static/js/tiles.js
+++ b/app/sovran_systemsos_web/static/js/tiles.js
@@ -13,6 +13,12 @@ function _renderBip110Badge(bip110) {
return '
' + escHtml(cfg.label) + '
';
}
+function _firstElementFromHtml(html) {
+ var tmp = document.createElement("div");
+ tmp.innerHTML = html;
+ return tmp.firstElementChild || null;
+}
+
// ── Render: initial build ─────────────────────────────────────────
function buildTiles(services, categoryLabels) {
@@ -281,21 +287,13 @@ function updateTiles(services) {
var badgeEl = tile.querySelector(".tile-bip110-badge");
if (badgeEl) {
// Replace existing badge in-place
- var tmp = document.createElement("div");
- tmp.innerHTML = badgeHtml;
- var newBadge = tmp.firstElementChild;
- if (newBadge) {
- badgeEl.replaceWith(newBadge);
- } else {
- badgeEl.remove();
- }
+ var newBadge = _firstElementFromHtml(badgeHtml);
+ if (newBadge) { badgeEl.replaceWith(newBadge); } else { badgeEl.remove(); }
} else if (badgeHtml) {
// Insert badge after version label (or after tile-name if no version)
var anchorEl = tile.querySelector(".tile-version") || tile.querySelector(".tile-name");
if (anchorEl) {
- var tmpDiv = document.createElement("div");
- tmpDiv.innerHTML = badgeHtml;
- var newBadgeEl = tmpDiv.firstElementChild;
+ var newBadgeEl = _firstElementFromHtml(badgeHtml);
if (newBadgeEl) anchorEl.insertAdjacentElement("afterend", newBadgeEl);
}
}
From 370786d1dc746f632b0d2b2022d581560ae4ec25 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 4 Jun 2026 20:07:44 +0000
Subject: [PATCH 011/140] Initial plan
From 732a7cd260de73bdfc44c5e2f8f724e76ee2559f Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 4 Jun 2026 20:11:58 +0000
Subject: [PATCH 012/140] Fix BIP110 detection for reduced_data deployments
---
app/sovran_systemsos_web/server.py | 64 +++++--
app/sovran_systemsos_web/static/js/helpers.js | 12 +-
app/tests/test_bip110_status.py | 166 ++++++++++++++++++
3 files changed, 221 insertions(+), 21 deletions(-)
create mode 100644 app/tests/test_bip110_status.py
diff --git a/app/sovran_systemsos_web/server.py b/app/sovran_systemsos_web/server.py
index a8e043d..6d4b8d7 100644
--- a/app/sovran_systemsos_web/server.py
+++ b/app/sovran_systemsos_web/server.py
@@ -2256,6 +2256,13 @@ _btcd_version_cache: tuple[float, str | None] = (0.0, None)
# Cache for ``bitcoin-cli getdeploymentinfo`` output (BIP-110 live status)
_btc_deployment_cache: tuple[float, dict | None] = (0.0, None)
+# Bitcoin Knots exposes BIP-110 as the `reduced_data` versionbits deployment
+# (RDTS, bit 4) in getdeploymentinfo. See Knots src/deploymentinfo.cpp,
+# src/kernel/chainparams.cpp, and doc/bips.md.
+BIP110_DEPLOYMENT_NAMES = {"reduced_data", "rdts", "bip110", "uasf-bip110"}
+BIP110_VERSIONBITS_BIT = 4
+BIP110_SUBVERSION_MARKERS = {"bip110", "uasf-bip110", "reduced_data", "rdts"}
+
# ── Generic service version detection (NixOS store path) ─────────
@@ -2414,16 +2421,16 @@ def _get_bip110_status() -> dict:
Resolution order (authoritative → fallback → honest unknown):
- 1. ``getdeploymentinfo`` (authoritative) — scan the ``deployments`` dict for an
- entry whose key (case-insensitive) contains "bip110". The exact
- deployment key name is **not** hard-coded because it may vary across Knots
- releases; detection is intentionally generic so that a name change degrades
- to "unknown" rather than producing a false result.
+ 1. ``getdeploymentinfo`` (authoritative) — scan ``deployments`` for BIP-110.
+ Bitcoin Knots currently exposes BIP-110 as ``reduced_data`` (RDTS, bit 4;
+ see Knots deploymentinfo.cpp / chainparams.cpp / doc/bips.md), so matching
+ first uses known deployment names, then falls back to versionbits bit 4.
2. Subversion fallback — if getdeploymentinfo is unavailable or yields no
recognisable BIP-110 entry, inspect the ``subversion`` field from
- ``getnetworkinfo``. A case-insensitive match for "bip110" or "uasf-bip110"
- in the subversion string is treated as "signaling".
+ ``getnetworkinfo``. A case-insensitive match for known BIP-110 markers
+ (including "bip110", "uasf-bip110", "reduced_data", "rdts") is treated as
+ "signaling".
3. Unknown — if the node is entirely unreachable or neither source is
conclusive, return state="unknown", signaling=False, source="none".
@@ -2435,14 +2442,37 @@ def _get_bip110_status() -> dict:
if deploy_info is not None:
deployments = deploy_info.get("deployments", {})
if isinstance(deployments, dict):
+ matched_entry: dict | None = None
+
+ # Primary match: known deployment names (case-insensitive contains)
for key, entry in deployments.items():
- # Generic scan: match key that contains "bip110" (case-insensitive).
- # Deliberately not matching bare "110" to avoid false positives on
- # unrelated deployments whose names happen to include that digit sequence.
- if "bip110" not in key.lower():
- continue
if not isinstance(entry, dict):
continue
+ key_lower = key.lower()
+ if not any(name in key_lower for name in BIP110_DEPLOYMENT_NAMES):
+ continue
+ matched_entry = entry
+ break
+
+ # Secondary match: versionbits bit (fallback only)
+ if matched_entry is None:
+ for _, entry in deployments.items():
+ if not isinstance(entry, dict):
+ continue
+ bip9 = entry.get("bip9", {}) or {}
+ bip8 = entry.get("bip8", {}) or {}
+ bit = bip9.get("bit")
+ if bit is None:
+ bit = bip8.get("bit")
+ if bit is None:
+ bit = entry.get("bit")
+ if bit != BIP110_VERSIONBITS_BIT:
+ continue
+ matched_entry = entry
+ break
+
+ if matched_entry is not None:
+ entry = matched_entry
# bip9 / bip8 status field
bip9 = entry.get("bip9", {}) or {}
@@ -2460,9 +2490,13 @@ def _get_bip110_status() -> dict:
if status == "locked_in":
return {"supported": True, "signaling": True, "state": "locked_in", "source": "getdeploymentinfo"}
if status in ("started", "defined"):
- # Check whether the node is currently signaling this period
+ # Check whether deployment is currently signaling in this period.
stats = bip9.get("statistics") or bip8.get("statistics") or {}
- signaling = bool(stats.get("signaling", False))
+ signaling = bool(
+ stats.get("signaling")
+ or stats.get("signalling")
+ or (isinstance(stats.get("count"), int) and stats.get("count", 0) > 0)
+ )
if signaling:
return {"supported": True, "signaling": True, "state": "signaling", "source": "getdeploymentinfo"}
return {"supported": True, "signaling": False, "state": "not_signaling", "source": "getdeploymentinfo"}
@@ -2476,7 +2510,7 @@ def _get_bip110_status() -> dict:
if net_info is not None:
subversion = net_info.get("subversion", "") or ""
sv_lower = subversion.lower()
- if "bip110" in sv_lower or "uasf-bip110" in sv_lower:
+ if any(marker in sv_lower for marker in BIP110_SUBVERSION_MARKERS):
return {"supported": True, "signaling": True, "state": "signaling", "source": "subversion"}
# Node is reachable via RPC but no BIP-110 marker found anywhere
return {"supported": False, "signaling": False, "state": "unsupported", "source": "subversion"}
diff --git a/app/sovran_systemsos_web/static/js/helpers.js b/app/sovran_systemsos_web/static/js/helpers.js
index d452fca..24f8caf 100644
--- a/app/sovran_systemsos_web/static/js/helpers.js
+++ b/app/sovran_systemsos_web/static/js/helpers.js
@@ -67,10 +67,10 @@ async function apiFetch(path, options) {
// Keys match the "state" values returned by /api/bitcoin/bip110.
var BIP110_BADGE_CONFIG = {
- active: { cls: 'tile-bip110-badge--active', label: 'BIP\u2011110: Active \u2713', title: 'BIP-110 is active on this node' },
- locked_in: { cls: 'tile-bip110-badge--locked_in', label: 'BIP\u2011110: Locked In', title: 'BIP-110 is locked in and will activate shortly' },
- signaling: { cls: 'tile-bip110-badge--signaling', label: 'BIP\u2011110: Signaling', title: 'Node is signaling readiness for BIP-110' },
- not_signaling: { cls: 'tile-bip110-badge--not_signaling',label: 'BIP\u2011110: Not Signaling', title: 'Node supports BIP-110 but is not signaling this period' },
- unsupported: { cls: 'tile-bip110-badge--unsupported', label: 'BIP\u2011110: Not Supported', title: 'This node build does not include BIP-110' },
- unknown: { cls: 'tile-bip110-badge--unknown', label: 'BIP\u2011110: \u2014', title: 'Status unavailable (node syncing or RPC not ready)' }
+ active: { cls: 'tile-bip110-badge--active', label: 'Active', title: 'BIP-110 is active on this node' },
+ locked_in: { cls: 'tile-bip110-badge--locked_in', label: 'Locked In', title: 'BIP-110 is locked in and will activate shortly' },
+ signaling: { cls: 'tile-bip110-badge--signaling', label: 'Signaling', title: 'Node is signaling readiness for BIP-110' },
+ not_signaling: { cls: 'tile-bip110-badge--not_signaling',label: 'Not Signaling', title: 'Node supports BIP-110 but is not signaling this period' },
+ unsupported: { cls: 'tile-bip110-badge--unsupported', label: 'Not Supported', title: 'This node build does not include BIP-110' },
+ unknown: { cls: 'tile-bip110-badge--unknown', label: '\u2014', title: 'Status unavailable (node syncing or RPC not ready)' }
};
diff --git a/app/tests/test_bip110_status.py b/app/tests/test_bip110_status.py
new file mode 100644
index 0000000..fafec4f
--- /dev/null
+++ b/app/tests/test_bip110_status.py
@@ -0,0 +1,166 @@
+import unittest
+from unittest.mock import patch
+from pathlib import Path
+import sys
+import types
+
+sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
+
+
+def _install_web_stubs():
+ if "fastapi" in sys.modules:
+ return
+
+ class _HTTPException(Exception):
+ def __init__(self, status_code=None, detail=None):
+ super().__init__(detail)
+ self.status_code = status_code
+ self.detail = detail
+
+ class _FastAPI:
+ def __init__(self, *args, **kwargs):
+ pass
+
+ def mount(self, *args, **kwargs):
+ return None
+
+ def add_middleware(self, *args, **kwargs):
+ return None
+
+ def __getattr__(self, _name):
+ def _decorator_factory(*args, **kwargs):
+ def _decorator(func):
+ return func
+
+ return _decorator
+
+ return _decorator_factory
+
+ class _BaseModel:
+ pass
+
+ class _StaticFiles:
+ def __init__(self, *args, **kwargs):
+ pass
+
+ class _Jinja2Templates:
+ def __init__(self, *args, **kwargs):
+ pass
+
+ class _BaseHTTPMiddleware:
+ pass
+
+ fastapi_module = types.ModuleType("fastapi")
+ fastapi_module.FastAPI = _FastAPI
+ fastapi_module.HTTPException = _HTTPException
+ sys.modules["fastapi"] = fastapi_module
+
+ responses_module = types.ModuleType("fastapi.responses")
+ responses_module.HTMLResponse = object
+ responses_module.JSONResponse = object
+ responses_module.RedirectResponse = object
+ sys.modules["fastapi.responses"] = responses_module
+
+ staticfiles_module = types.ModuleType("fastapi.staticfiles")
+ staticfiles_module.StaticFiles = _StaticFiles
+ sys.modules["fastapi.staticfiles"] = staticfiles_module
+
+ templating_module = types.ModuleType("fastapi.templating")
+ templating_module.Jinja2Templates = _Jinja2Templates
+ sys.modules["fastapi.templating"] = templating_module
+
+ requests_module = types.ModuleType("fastapi.requests")
+ requests_module.Request = object
+ sys.modules["fastapi.requests"] = requests_module
+
+ pydantic_module = types.ModuleType("pydantic")
+ pydantic_module.BaseModel = _BaseModel
+ sys.modules["pydantic"] = pydantic_module
+
+ starlette_base_module = types.ModuleType("starlette.middleware.base")
+ starlette_base_module.BaseHTTPMiddleware = _BaseHTTPMiddleware
+ sys.modules["starlette.middleware.base"] = starlette_base_module
+
+ starlette_middleware_module = types.ModuleType("starlette.middleware")
+ starlette_middleware_module.base = starlette_base_module
+ sys.modules["starlette.middleware"] = starlette_middleware_module
+
+ starlette_module = types.ModuleType("starlette")
+ starlette_module.middleware = starlette_middleware_module
+ sys.modules["starlette"] = starlette_module
+
+
+_install_web_stubs()
+from sovran_systemsos_web import server
+
+
+class Bip110StatusTests(unittest.TestCase):
+ def _status(self, deploy_info, net_info):
+ with patch.object(server, "_get_bitcoin_deployment_info", return_value=deploy_info), patch.object(
+ server, "_get_bitcoin_version_info", return_value=net_info
+ ):
+ return server._get_bip110_status()
+
+ def test_started_reduced_data_reports_signaling(self):
+ deploy_info = {
+ "deployments": {
+ "reduced_data": {
+ "type": "bip9",
+ "active": False,
+ "bip9": {
+ "bit": 4,
+ "status": "started",
+ "statistics": {"elapsed": 833, "count": 4, "threshold": 1109},
+ "signalling": "--#--",
+ },
+ }
+ }
+ }
+
+ result = self._status(deploy_info, {"subversion": "/Satoshi:29.0.0/"})
+ self.assertEqual(
+ result,
+ {"supported": True, "signaling": True, "state": "signaling", "source": "getdeploymentinfo"},
+ )
+
+ def test_active_reduced_data_reports_active(self):
+ deploy_info = {
+ "deployments": {"reduced_data": {"active": True, "bip9": {"bit": 4, "status": "active"}}}
+ }
+
+ result = self._status(deploy_info, {"subversion": "/Satoshi:29.0.0/"})
+ self.assertEqual(result["state"], "active")
+ self.assertTrue(result["supported"])
+ self.assertTrue(result["signaling"])
+ self.assertEqual(result["source"], "getdeploymentinfo")
+
+ def test_locked_in_reduced_data_reports_locked_in(self):
+ deploy_info = {
+ "deployments": {"reduced_data": {"active": False, "bip9": {"bit": 4, "status": "locked_in"}}}
+ }
+
+ result = self._status(deploy_info, {"subversion": "/Satoshi:29.0.0/"})
+ self.assertEqual(result["state"], "locked_in")
+ self.assertTrue(result["supported"])
+ self.assertTrue(result["signaling"])
+ self.assertEqual(result["source"], "getdeploymentinfo")
+
+ def test_no_bip110_deployment_and_plain_subversion_reports_unsupported(self):
+ deploy_info = {
+ "deployments": {
+ "taproot": {"type": "bip9", "active": True, "bip9": {"bit": 2, "status": "active"}},
+ }
+ }
+ result = self._status(deploy_info, {"subversion": "/Satoshi:27.0.0/"})
+ self.assertEqual(
+ result,
+ {"supported": False, "signaling": False, "state": "unsupported", "source": "subversion"},
+ )
+
+ def test_node_unreachable_reports_unknown(self):
+ result = self._status(None, None)
+ self.assertEqual(result, {"supported": False, "signaling": False, "state": "unknown", "source": "none"})
+
+
+if __name__ == "__main__":
+ unittest.main()
From 00b5bf5166c06f1ec32c1f0f8b798fa246bb8ef3 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Thu, 4 Jun 2026 20:15:35 +0000
Subject: [PATCH 013/140] Refine BIP110 matching and add regression coverage
---
app/sovran_systemsos_web/server.py | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/app/sovran_systemsos_web/server.py b/app/sovran_systemsos_web/server.py
index 6d4b8d7..4262ea8 100644
--- a/app/sovran_systemsos_web/server.py
+++ b/app/sovran_systemsos_web/server.py
@@ -2437,6 +2437,16 @@ def _get_bip110_status() -> dict:
"""
_unknown: dict = {"supported": False, "signaling": False, "state": "unknown", "source": "none"}
+ def _deployment_bit(entry: dict) -> int | None:
+ bip9 = entry.get("bip9", {}) or {}
+ bip8 = entry.get("bip8", {}) or {}
+ bit = bip9.get("bit")
+ if bit is None:
+ bit = bip8.get("bit")
+ if bit is None:
+ bit = entry.get("bit")
+ return bit
+
# ── 1. getdeploymentinfo (authoritative) ──────────────────────────
deploy_info = _get_bitcoin_deployment_info()
if deploy_info is not None:
@@ -2444,12 +2454,12 @@ def _get_bip110_status() -> dict:
if isinstance(deployments, dict):
matched_entry: dict | None = None
- # Primary match: known deployment names (case-insensitive contains)
+ # Primary match: known deployment names (case-insensitive exact match)
for key, entry in deployments.items():
if not isinstance(entry, dict):
continue
key_lower = key.lower()
- if not any(name in key_lower for name in BIP110_DEPLOYMENT_NAMES):
+ if key_lower not in BIP110_DEPLOYMENT_NAMES:
continue
matched_entry = entry
break
@@ -2459,14 +2469,7 @@ def _get_bip110_status() -> dict:
for _, entry in deployments.items():
if not isinstance(entry, dict):
continue
- bip9 = entry.get("bip9", {}) or {}
- bip8 = entry.get("bip8", {}) or {}
- bit = bip9.get("bit")
- if bit is None:
- bit = bip8.get("bit")
- if bit is None:
- bit = entry.get("bit")
- if bit != BIP110_VERSIONBITS_BIT:
+ if _deployment_bit(entry) != BIP110_VERSIONBITS_BIT:
continue
matched_entry = entry
break
@@ -2492,10 +2495,13 @@ def _get_bip110_status() -> dict:
if status in ("started", "defined"):
# Check whether deployment is currently signaling in this period.
stats = bip9.get("statistics") or bip8.get("statistics") or {}
+ # Some Knots outputs expose only ``count`` (not explicit signaling bool),
+ # so treat count>0 as a conservative signaling indicator for this period.
+ count = stats.get("count")
signaling = bool(
stats.get("signaling")
or stats.get("signalling")
- or (isinstance(stats.get("count"), int) and stats.get("count", 0) > 0)
+ or (isinstance(count, int) and count > 0)
)
if signaling:
return {"supported": True, "signaling": True, "state": "signaling", "source": "getdeploymentinfo"}
From 7f185b03550611b7159b909b8b9b0af73d8cdd6b Mon Sep 17 00:00:00 2001
From: naturallaw77
Date: Thu, 4 Jun 2026 16:06:58 -0500
Subject: [PATCH 014/140] moved to new bitcoin-knots with bip110
---
modules/bitcoinecosystem.nix | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/bitcoinecosystem.nix b/modules/bitcoinecosystem.nix
index ffe27f8..e5e9168 100755
--- a/modules/bitcoinecosystem.nix
+++ b/modules/bitcoinecosystem.nix
@@ -4,7 +4,7 @@ lib.mkIf config.sovran_systemsOS.services.bitcoin {
services.bitcoind = {
enable = true;
- package = config.nix-bitcoin.pkgs.bitcoind-knots;
+ package = pkgs.bitcoind-knots;
dataDir = "/run/media/Second_Drive/BTCEcoandBackup/Bitcoin_Node";
txindex = true;
tor.proxy = true;
From d9811d2375754cae521720fc55f55cd9209ca17f Mon Sep 17 00:00:00 2001
From: naturallaw77
Date: Fri, 5 Jun 2026 10:04:13 -0500
Subject: [PATCH 015/140] updated stable branch
---
flake.nix | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flake.nix b/flake.nix
index 1b6b366..0015b85 100755
--- a/flake.nix
+++ b/flake.nix
@@ -6,7 +6,7 @@
nix-bitcoin.url = "github:fort-nix/nix-bitcoin/release";
nixvim.url = "github:nix-community/nixvim";
btc-clients.url = "github:emmanuelrosa/btc-clients-nix";
- nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-24.11";
+ nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-26.05";
};
outputs = { self, nixpkgs, nix-bitcoin, nixvim, btc-clients, nixpkgs-stable, ... }:
From 2903a61944dba020ba480a11188818c883e8c69d Mon Sep 17 00:00:00 2001
From: naturallaw77
Date: Fri, 5 Jun 2026 10:27:51 -0500
Subject: [PATCH 016/140] updated nix packages
---
flake.lock | 92 +++++++++++++++++-------------------------------------
1 file changed, 29 insertions(+), 63 deletions(-)
diff --git a/flake.lock b/flake.lock
index ee2212c..a2a534b 100755
--- a/flake.lock
+++ b/flake.lock
@@ -1,33 +1,15 @@
{
"nodes": {
- "bip110": {
+ "btc-clients": {
"inputs": {
"nixpkgs": "nixpkgs"
},
"locked": {
- "lastModified": 1778967282,
- "narHash": "sha256-0g9RvVCD6zxY2vy54GhbB1OeeEZdKuxTr9r0whcpRjQ=",
- "owner": "emmanuelrosa",
- "repo": "bitcoin-knots-bip-110-nix",
- "rev": "8d23ed98940d70e42ee870d719677a073a0a5920",
- "type": "github"
- },
- "original": {
- "owner": "emmanuelrosa",
- "repo": "bitcoin-knots-bip-110-nix",
- "type": "github"
- }
- },
- "btc-clients": {
- "inputs": {
- "nixpkgs": "nixpkgs_2"
- },
- "locked": {
- "lastModified": 1779889285,
- "narHash": "sha256-5QOMNn/rxJjsy9n2pAG5+AwUXOAPXSzcr62y1tGHXKA=",
+ "lastModified": 1780397635,
+ "narHash": "sha256-6WH7LKD6i91VLWoz4mEpoULtqVinCEZxG7ZjJPMSi3k=",
"owner": "emmanuelrosa",
"repo": "btc-clients-nix",
- "rev": "9a3dd86e11ea5fb17ace9043aa3d0d5ed359a3ca",
+ "rev": "feacd7684dc6bfcd49c57764944a2049bbd71924",
"type": "github"
},
"original": {
@@ -105,7 +87,7 @@
"inputs": {
"extra-container": "extra-container",
"flake-utils": "flake-utils",
- "nixpkgs": "nixpkgs_3",
+ "nixpkgs": "nixpkgs_2",
"nixpkgs-25_05": "nixpkgs-25_05",
"nixpkgs-unstable": "nixpkgs-unstable"
},
@@ -126,16 +108,15 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1777728799,
- "narHash": "sha256-z7jjYQqhkFKab92VQ3duB7QVO7f7Y62qTFrJYXO/lyo=",
+ "lastModified": 1780218263,
+ "narHash": "sha256-T/f0pPDrH3Qc1VXyQXbK7yfHWRn90l3xwplc/nsxin4=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "4b2287113c2f9a2331c04899b2e2e5ab92dea9c5",
+ "rev": "7fc393d1b46fa000d48ff14e8b6a3c9985f03af0",
"type": "github"
},
"original": {
"owner": "nixos",
- "ref": "master",
"repo": "nixpkgs",
"type": "github"
}
@@ -158,16 +139,16 @@
},
"nixpkgs-stable": {
"locked": {
- "lastModified": 1751274312,
- "narHash": "sha256-/bVBlRpECLVzjV19t5KMdMFWSwKLtb5RyXdjz3LJT+g=",
+ "lastModified": 1780453794,
+ "narHash": "sha256-bXMRa9VTsHSPXL4Cw8R6JJLQeY3Y/IP4+YJCYVmQ7FY=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "50ab793786d9de88ee30ec4e4c24fb4236fc2674",
+ "rev": "6b316287bae2ee04c9b93c8c858d930fd07d7338",
"type": "github"
},
"original": {
"owner": "nixos",
- "ref": "nixos-24.11",
+ "ref": "nixos-26.05",
"repo": "nixpkgs",
"type": "github"
}
@@ -189,21 +170,6 @@
}
},
"nixpkgs_2": {
- "locked": {
- "lastModified": 1777728799,
- "narHash": "sha256-z7jjYQqhkFKab92VQ3duB7QVO7f7Y62qTFrJYXO/lyo=",
- "owner": "NixOS",
- "repo": "nixpkgs",
- "rev": "4b2287113c2f9a2331c04899b2e2e5ab92dea9c5",
- "type": "github"
- },
- "original": {
- "owner": "nixos",
- "repo": "nixpkgs",
- "type": "github"
- }
- },
- "nixpkgs_3": {
"locked": {
"lastModified": 1778737229,
"narHash": "sha256-6xWoytx8jFW4PF1GjRm/i/53trbpKGfz6zjzQGBr4cI=",
@@ -219,13 +185,13 @@
"type": "github"
}
},
- "nixpkgs_4": {
+ "nixpkgs_3": {
"locked": {
- "lastModified": 1779560665,
- "narHash": "sha256-tpyBcxPpcQb8ukyNF7DoCwfSY3VPsxHoYwj00Cayv5o=",
+ "lastModified": 1780243769,
+ "narHash": "sha256-x5UQuRsH3MqI0U9afaXSNqzTPSeZlRLvFAav2Ux1pNw=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "64c08a7ca051951c8eae34e3e3cb1e202fe36786",
+ "rev": "331800de5053fcebacf6813adb5db9c9dca22a0c",
"type": "github"
},
"original": {
@@ -235,13 +201,13 @@
"type": "github"
}
},
- "nixpkgs_5": {
+ "nixpkgs_4": {
"locked": {
- "lastModified": 1779259093,
- "narHash": "sha256-7DKWmH23hL2eYdkxCKeqj2i+yljTKuU+3Nk1UPHOnxc=",
+ "lastModified": 1780336545,
+ "narHash": "sha256-vhVhuXzFrIOfcssC/9hDHx7MHzDKjF3keHuREOQqQiQ=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "d99b013d5d1931ad77fe3912ed218170dec5d9a4",
+ "rev": "4df1b885d76a54e1aa1a318f8d16fd6005b6401f",
"type": "github"
},
"original": {
@@ -254,15 +220,15 @@
"nixvim": {
"inputs": {
"flake-parts": "flake-parts",
- "nixpkgs": "nixpkgs_5",
+ "nixpkgs": "nixpkgs_4",
"systems": "systems_2"
},
"locked": {
- "lastModified": 1779816597,
- "narHash": "sha256-Kgod3gZlhSp6WozZ2pFaclXbWpjs6kQLAtldoxb85Lc=",
+ "lastModified": 1780646548,
+ "narHash": "sha256-Ckyl/l1XBmEwnaHcHD8PvBZk1uph0NqwbJ//CAvB7iE=",
"owner": "nix-community",
"repo": "nixvim",
- "rev": "297f9341476ba7f821a42d7a2805e206ef8c6ef8",
+ "rev": "816a15282e58678dde831477964987d0262d4293",
"type": "github"
},
"original": {
@@ -273,10 +239,9 @@
},
"root": {
"inputs": {
- "bip110": "bip110",
"btc-clients": "btc-clients",
"nix-bitcoin": "nix-bitcoin",
- "nixpkgs": "nixpkgs_4",
+ "nixpkgs": "nixpkgs_3",
"nixpkgs-stable": "nixpkgs-stable",
"nixvim": "nixvim"
}
@@ -298,15 +263,16 @@
},
"systems_2": {
"locked": {
- "lastModified": 1681028828,
- "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "lastModified": 1774449309,
+ "narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=",
"owner": "nix-systems",
"repo": "default",
- "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "rev": "c29398b59d2048c4ab79345812849c9bd15e9150",
"type": "github"
},
"original": {
"owner": "nix-systems",
+ "ref": "future-26.11",
"repo": "default",
"type": "github"
}
From 6c48a9e2391b787c8bb45b34bb9d293bb03edf4d Mon Sep 17 00:00:00 2001
From: naturallaw77
Date: Fri, 5 Jun 2026 10:29:20 -0500
Subject: [PATCH 017/140] sync and removed element-desktop and bitwarden
desktop
---
configuration.nix | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/configuration.nix b/configuration.nix
index 7863170..73c120b 100644
--- a/configuration.nix
+++ b/configuration.nix
@@ -145,10 +145,10 @@
ranger fastfetch gedit openssl pwgen
aspell aspellDicts.en lm_sensors
hunspell hunspellDicts.en_US
- synadm brave dua bitwarden-desktop
+ synadm brave dua
gparted pv unzip parted screen zenity
libargon2 gnome-terminal libreoffice-fresh
- dig firefox element-desktop wp-cli axel
+ dig firefox wp-cli axel
lk-jwt-service livekit-libwebrtc livekit-cli livekit
matrix-synapse age
];
From 7a3a39027569fbe5e63015131748184e2d82add1 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 5 Jun 2026 17:56:09 +0000
Subject: [PATCH 018/140] Initial plan
From dae409e1065fb6295416fc57ff49816fd7c4cd64 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 5 Jun 2026 18:13:16 +0000
Subject: [PATCH 019/140] Plan README changes with placeholder screenshot
---
assets/desktop-screenshot.png | 1485 +++++++++++++++++++++++++++++++++
1 file changed, 1485 insertions(+)
create mode 100644 assets/desktop-screenshot.png
diff --git a/assets/desktop-screenshot.png b/assets/desktop-screenshot.png
new file mode 100644
index 0000000..c0de9d8
--- /dev/null
+++ b/assets/desktop-screenshot.png
@@ -0,0 +1,1485 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Page not found · GitHub · GitHub
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ You signed in with another tab or window. Reload to refresh your session.
+ You signed out in another tab or window. Reload to refresh your session.
+ You switched accounts on another tab or window. Reload to refresh your session.
+
+ Dismiss alert
+
+
+
+