diff --git a/README.md b/README.md
index 7016f44..1e3d482 100755
--- a/README.md
+++ b/README.md
@@ -9,38 +9,244 @@
-# Complete Configuration for Sovran_SystemsOS and the Sovran Pro
+# Sovran_SystemsOS
-A Nix Flake Implementation
+**Own Your Stack. Run Your World.**
-Thanks to all the NixOS creators and developers for creating what is the future of computing.
+---
-https://sovransystems.com
+## 🌐 What is Sovran_SystemsOS?
-Connect on Matrix here: https://matrix.to/#/#sovran-systems:anarchyislove.xyz
+Sovran_SystemsOS is a **declarative, self-hosted operating system built on NixOS** that turns a single machine into your:
-Connect for Support on Matrix here: https://matrix.to/#/#sovran-systems-support:anarchyislove.xyz
+* Personal cloud
+* Private communications hub
+* Bitcoin node
+* Web server
+* Daily desktop
-###
+This isn’t just an OS config — it’s a **complete sovereign computing environment**.
-## DIY Install Of Sovran_SystemsOS
+---
-The write-up to install Sovran_SystemsOS on your own hardware is located here:
+## ⚡ Why It Matters
-https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/src/branch/main/DIY%20Install%20Sovran_SystemsOS.md
+Most people rely on a patchwork of third-party services:
-The DIY support chat on Matrix is located here:
+* Cloud storage owned by corporations
+* Messaging platforms that mine metadata
+* Financial infrastructure you don’t control
-https://matrix.to/#/%23DIY_Sovran_SystemsOS:anarchyislove.xyz
+Sovran_SystemsOS flips that model.
-## License
+👉 You run the services.
+👉 You own the data.
+👉 You control the system.
-Sovran_SystemsOS is licensed under the Apache 2 software licence.
+---
-##
+## 🚀 What You’re Actually Getting
-Created, Handcrafted, and Headquartered in the Midwest – 2022-2026.
+This system doesn’t just install apps — it **assembles an ecosystem**.
-This Gitea is Proudly Powered by a Sovran Pro.
+### 🖥 A Unified Desktop + Server
+
+* Full GNOME desktop
+* Ready for daily use *and* backend services
+* Remote access capabilities
+
+---
+
+### 🌍 A Real Web Stack (Out of the Box)
+
+* Caddy web server with automatic HTTPS
+* Reverse proxy routing already wired
+* Multi-service hosting under your domains
+
+---
+
+### ☁️ Your Own Cloud Platform
+
+* Nextcloud → file storage, sync, collaboration
+* WordPress → publish and host content
+* Vaultwarden → secure password management
+
+---
+
+### 💬 Private Communication Layer
+
+* Matrix Synapse → decentralized messaging backend
+* Element support → modern chat + collaboration
+* Optional voice/video infrastructure
+
+---
+
+### ₿ Sovereign Financial Stack
+
+* Run your own Bitcoin node
+* BTCPay Server for payments
+* Optional mempool explorer
+
+No intermediaries. No permissions.
+
+---
+
+### 🔐 Built-In Security Posture
+
+* Hardened SSH (no password logins)
+* Fail2ban active by default
+* Tor integration available
+* Encrypted secrets via Agenix
+
+---
+
+### 💾 Reliability Without Babysitting
+
+* Automated backups (rsnapshot)
+* Cron jobs for maintenance
+* Database initialization included
+
+---
+
+## 🧠 What Makes It Stand Out
+
+### 1. **This Is Not a “Toolkit” — It’s a System**
+
+Most projects give you pieces.
+
+Sovran_SystemsOS gives you a **pre-integrated stack** where:
+
+* Services already talk to each other
+* Reverse proxy is configured
+* Databases are initialized
+* Ports and firewall rules are handled
+
+You’re not assembling — you’re **activating**.
+
+---
+
+### 2. **Feature Toggles = Power Without Bloat**
+
+Turn features on or off like switches:
+
+```nix id="z91x8a"
+sovran_systemsOS.features.mempool = true;
+sovran_systemsOS.features.haven = true;
+```
+
+No unnecessary services. No wasted resources.
+
+---
+
+### 3. **Reproducibility = Control**
+
+Your entire system is code:
+
+* Rebuild anytime
+* Move to new hardware
+* Roll back instantly
+
+This is infrastructure you can trust because you can **recreate it exactly**.
+
+---
+
+### 4. **Automation Where It Counts**
+
+A huge amount is handled for you:
+
+* Service wiring
+* Reverse proxy setup
+* Scheduled jobs
+* Base security
+
+But unlike “black box” systems, you still retain **full visibility and control**.
+
+---
+
+## ⚠️ Honest Reality (No Hype)
+
+This system **does not eliminate effort**.
+
+You will still need to:
+
+* Configure DNS and domains
+* Manage secrets (Agenix)
+* Understand your enabled services
+* Perform initial setup steps
+
+But here’s the difference:
+
+👉 You’re not starting from scratch
+👉 You’re not duct-taping services together
+👉 You’re not fighting your system
+
+You’re building on a **solid, opinionated foundation**
+
+---
+
+## 🔌 Expand As You Grow
+
+Enable advanced features anytime:
+
+```nix id="0p9k21"
+sovran_systemsOS.features.bitcoin-core = true;
+sovran_systemsOS.features.bip110 = true;
+sovran_systemsOS.features.mempool = true;
+sovran_systemsOS.features.rdp = true;
+```
+
+Available add-ons include:
+
+* Bitcoin Core / Knots switching
+* BIP-110 (enhanced Bitcoin consensus policy)
+* Mempool explorer
+* Nostr relay (Haven)
+* Element voice/video backend
+* Remote desktop
+
+---
+
+## 🛠 Installation
+
+Full guide:
+
+👉 https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/src/branch/main/DIY%20Install%20Sovran_SystemsOS.md
+
+---
+
+## 💬 Community
+
+* General Chat:
+ https://matrix.to/#/#sovran-systems:anarchyislove.xyz
+
+* DIY Support:
+ https://matrix.to/#/#DIY_Sovran_SystemsOS:anarchyislove.xyz
+
+---
+
+## 🧭 Who This Is For
+
+Sovran_SystemsOS is for people who want to:
+
+* Move off Big Tech platforms
+* Run their own infrastructure
+* Understand and control their system
+* Build a sovereign digital life
+
+---
+
+## 🧭 Final Thought
+
+You can keep renting your digital life…
+
+Or you can start owning it.
+
+Sovran_SystemsOS doesn’t promise magic.
+It gives you something more valuable:
+
+👉 **A system you control, understand, and can rebuild at will.**
+
+---
+
+**All Is Love. Fear Is Illusion. All Beings Are Free. Truth Can Never Be Destroyed.**
-All Is Love. Fear Is Illusion. All Beings Are Free. Truth Can Never Be Destroyed.
diff --git a/custom-add-ons.md b/custom-add-ons.md
index 9c76dc4..7fbff53 100644
--- a/custom-add-ons.md
+++ b/custom-add-ons.md
@@ -1,47 +1,66 @@
## Custom Add-ons for your Sovran Pro
-Add-ons are extra features you can have installed before your Sovran Pro is shipped to you.
+Add-ons are extra features you can have installed before your Sovran Pro is shipped to you or you can install them yourself.
1. Since Sovran_SystemsOS runs Bitcoin Knots by default as opposed to Bitcion Core, you can customize your Sovran Pro's Bitcoin node to run Bitcoin Core.
https://github.com/bitcoin/bitcoin
+2. BIP-110 keeps Bitcoin more efficient as Peer to Peer Cash and you can run it along side your Bitocoin node.
-2. The Bitcoin Mempool can be added and can be accessed via Tor or on your local network.
+https://github.com/bitcoin/bips/blob/master/bip-0110.mediawiki
+
+3. The Bitcoin Mempool can be added and can be accessed via Tor or on your local network.
https://github.com/mempool/mempool
+4. The Haven Relay for NOSTR (NOTES AND OTHER STUFF TRANSMITED BY RELAYS) is a Decenterized Social Media/File Sharing.
-The code will be installed in the `custom.nix` file.
+https://github.com/barrydeen/haven
+
+5. You can run the new Element Voice and Video calling backend.
+
+https://github.com/element-hq/element-call
+
+6. You can run the Gnome Remote Desktop to view your desktop from another computer in the nextwork.
+
+https://gitlab.gnome.org/GNOME/gnome-remote-desktop
+
+#### The code will be installed in the `custom.nix` file.
-The code for Bitcoin Core is as follows:
+1. The code for Bitcoin Core is as follows:
```nix
-services.bitcoind.package = lib.mkForce config.nix-bitcoin.pkgs.bitcoind;
+sovran_systemsOS.features.bitcoin-core = true;
```
-
-The code for Mempool is as follows:
+2. The code for BIP-110 is as follows:
```nix
-services.mempool = {
- enable = true;
- frontend.enable = true;
-};
-
-services.mysql.package = lib.mkForce pkgs.mariadb;
-
-nix-bitcoin.onionServices.mempool-frontend.enable = true;
-
-services.caddy = {
- virtualHosts = {
- ":60847" = {
- extraConfig = ''
- reverse_proxy :60845
- encode gzip zstd
- '';
- };
- };
-};
+sovran_systemsOS.features.bip110 = true;
+```
+
+3. The code for Mempool is as follows:
+
+```nix
+sovran_systemsOS.features.mempool = true;
+```
+
+4. The code for Haven Relay is as follows:
+
+```nix
+sovran_systemsOS.features.haven = true;
+```
+
+5. The code for Element Calling is as follows:
+
+```nix
+sovran_systemsOS.features.element-calling = true;
+```
+
+6. The code for Gnome Remote Desktop is as follows:
+
+```nix
+sovran_systemsOS.features.rdp = true;
```
diff --git a/modules/bip110.nix b/modules/bip110.nix
new file mode 100755
index 0000000..5e07e9c
--- /dev/null
+++ b/modules/bip110.nix
@@ -0,0 +1,7 @@
+{ config, lib, pkgs, bip110, ... }:
+
+{
+
+services.bitcoind.packages = lib.mkForce bip110.packages.x86_64-linux.bitcoind-knots-bip-110;
+
+}
diff --git a/modules/bitcoin-core.nix b/modules/bitcoin-core.nix
new file mode 100755
index 0000000..a4951d1
--- /dev/null
+++ b/modules/bitcoin-core.nix
@@ -0,0 +1,7 @@
+{ config, pkgs, lib, ... }:
+
+{
+
+ services.bitcoind.package = lib.mkForce config.nix-bitcoin.pkgs.bitcoind;
+
+}
diff --git a/modules/core/role-logix.nix b/modules/core/role-logix.nix
new file mode 100755
index 0000000..e52331b
--- /dev/null
+++ b/modules/core/role-logix.nix
@@ -0,0 +1,37 @@
+{ config, lib, ... }:
+
+{
+ config = lib.mkMerge [
+
+ # Server-Desktop Role most services enabled
+ (lib.mkIf config.sovran_systemsOS.roles.server-desktop {
+ sovran_systemsOS.features = {
+ synapse = true;
+ bitcoin = true;
+ coturn = true;
+ vaultwarden = true;
+ haven = false;
+ mempool = false;
+ bip110 = false;
+ element-calling = false;
+ bitcoin-core = false;
+ rdp = false;
+ };
+ })
+
+ # Desktop role
+ (lib.mkIf config.sovran_systemsOS.roles.desktop {
+ services.xserver.enable = true;
+ services.desktopManager.gnome.enable = true;
+ })
+
+ # Bitcoin node role
+ (lib.mkIf config.sovran_systemsOS.roles.node {
+ sovran_systemsOS.features = {
+ bitcoin = true;
+ bip110 = false;
+ };
+ })
+
+ ];
+}
diff --git a/modules/core/roles.nix b/modules/core/roles.nix
new file mode 100755
index 0000000..fd0c4eb
--- /dev/null
+++ b/modules/core/roles.nix
@@ -0,0 +1,27 @@
+{ config, lib, ... }:
+
+{
+ options.sovran_systemsOS = {
+ roles = {
+ server-desktop = lib.mkOption {
+ type = lib.types.bool;
+ default = !config.sovran_sovransystemsOS.roles.desktop && !config.sovran_systemsOS.roles.node;
+ };
+ desktop = lib.mkEnableOption "Desktop Role";
+ node = lib.mkEnableOption "Bitcoin Node Only Role";
+ };
+
+ features = {
+ coturn = lib.mkEnableOption "TURN server";
+ synapse = lib.mkEnableOption "Matrix Synapse";
+ bitcoin = lib.mkEnableOption "Bitcoin Ecosystem";
+ vaultwarden = lib.mkEnableOption "Vaultwarden";
+ haven = lib.mkEnableOption "Haven NOSTR relay";
+ bip110 = lib.mkEnableOption "BIP-110 Bitcoin Better Money";
+ mempool = lib.mkEnableOption "Bitcoin Mempool Explorer";
+ element-calling = lib.mkEnableOption "Element Video and Audio Calling";
+ bitcoin-core = lib.mkEnableOption "Bitcoin Core";
+ rdp = lib.mkEnableOption "Gnome Remote Desktop";
+ };
+ };
+}
diff --git a/modules/element-calling.nix b/modules/element-calling.nix
new file mode 100755
index 0000000..bdbe8b4
--- /dev/null
+++ b/modules/element-calling.nix
@@ -0,0 +1,161 @@
+{ config, pkgs, lib, ... }:
+
+let
+
+personalization = import ./personalization.nix;
+
+in
+
+{
+
+ systemd.tmpfiles.rules = [
+ "d /var/lib/domains/element-calling 0750 caddy php -"
+ ];
+
+
+ "${personalization.matrix_url}" = lib.mkForce {
+ extraConfig = ''
+ reverse_proxy /_matrix/* http://localhost:8008
+ reverse_proxy /_synapse/client/* http://localhost:8008
+ header /.well-known/matrix/* Content-Type "application/json"
+ header /.well-known/matrix/* Access-Control-Allow-Origin "*"
+ header /.well-known/matrix/* Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
+ header /.well-known/matrix/* Access-Control-Allow-Headers "X-Requested-With, Content-Type, Authorization"
+ respond /.well-known/matrix/client `{ "m.homeserver": {"base_url": "https://anarchyislove.xyz" }, "org.matrix.msc4143.rtc_foci": [{ "type":"livekit", "livekit_service_url":"https://${personalization.element-calling_url}/livekit/jwt" }] }`
+ '';
+ };
+
+
+ "${personalization.element-calling_url}" = {
+ extraConfig = ''
+ handle /livekit/jwt/sfu/get {
+ uri strip_prefix /livekit/jwt
+ reverse_proxy [::1]:8073 {
+ header_up Host {host}
+ header_up X-Forwarded-Server {host}
+ header_up X-Real-IP {remote_host}
+ header_up X-Forwarded-For {remote_host}
+ }
+ }
+
+ handle {
+ reverse_proxy localhost:7880
+ }
+ '';
+ };
+
+ services.livekit = {
+ enable = true;
+ openFirewall = true;
+ settings = {
+ rtc.use_external_ip = true;
+ rtc.udp_port = "7882-7894";
+ room = {
+ auto_create = false;
+ };
+ turn = {
+ enabled = true;
+ domain = "${personalization.matrix_url}";
+ tls_port = 5349;
+ udp_port = 3478;
+ cert_file = "/var/lib/livekit/${personalization.matrix_url}.crt";
+ key_file = "/var/lib/livekit/${personalization.matrix_url}.key";
+ };
+ };
+ keyFile = "/var/lib/livekit/livekit_keyFile";
+ };
+
+ networking.firewall.allowedTCPPorts = [ 7881 ]; #Livekit TCP Port
+
+ networking.firewall.allowedUDPPortRanges = [
+ { from=7882; to=7894; }
+ ];
+
+ services.lk-jwt-service = {
+ enable = true;
+ port = 8073;
+ livekitUrl = "wss://${personalization.element-calling_url}";
+ keyFile = "/var/lib/livekit/livekit_keyFile";
+ };
+
+ services.matrix-synapse = {
+ settings = lib.mkForce {
+
+ serve_server_wellknown = true;
+
+ public_baseurl = ${personalization.matrix_url};
+
+ experimental_features = {
+ msc3266_enabled = true;
+ msc4222_enabled = true;
+ };
+
+ max_event_delay_duration = "24h";
+
+ rc_message = {
+ per_second = 0.5;
+ burst_count = 30;
+ };
+
+ rc_delayed_event_mgmt = {
+ per_second = 1;
+ burst_count = 20;
+ };
+
+ push.include_content = false;
+ server_name = personalization.matrix_url;
+ url_preview_enabled = true;
+ max_upload_size = "1024M";
+ group_unread_count_by_room = false;
+ encryption_enabled_by_default_for_room_type = "invite";
+ allow_profile_lookup_over_federation = false;
+ allow_device_name_lookup_over_federation = false;
+
+ url_preview_ip_range_blacklist = [
+ "10.0.0.0/8"
+ "100.64.0.0/10"
+ "169.254.0.0/16"
+ "172.16.0.0/12"
+ "192.0.0.0/24"
+ "192.0.2.0/24"
+ "192.168.0.0/16"
+ "192.88.99.0/24"
+ "198.18.0.0/15"
+ "198.51.100.0/24"
+ "2001:db8::/32"
+ "203.0.113.0/24"
+ "224.0.0.0/4"
+ "::1/128"
+ "fc00::/7"
+ "fe80::/10"
+ "fec0::/10"
+ "ff00::/8"
+ ];
+
+ url_preview_ip_ranger_whitelist = [ "127.0.0.1" ];
+ presence.enabled = true;
+ enable_registration = false;
+ registration_shared_secret = config.age.secrets.matrix_reg_secret.path;
+ listeners = [
+ {
+ port = 8008;
+ bind_addresses = [ "::1" ];
+ type = "http";
+ tls = false;
+ x_forwarded = true;
+ resources = [
+ {
+ names = [ "client" ];
+ compress = true;
+ }
+ {
+ names = [ "federation" ];
+ compress = false;
+ }
+ ];
+ }
+ ];
+ };
+ };
+}
+
diff --git a/modules/haven.nix b/modules/haven.nix
new file mode 100755
index 0000000..045c7bb
--- /dev/null
+++ b/modules/haven.nix
@@ -0,0 +1,150 @@
+{config, pkgs, lib, ...}:
+
+let
+
+personalization = import ./personalization.nix;
+
+in
+
+{
+
+ services.haven = {
+ enable = true;
+ settings = {
+ OWNER_NPUB="";
+ RELAY_URL="*name*";
+
+ RELAY_PORT=3355;
+ RELAY_BIND_ADDRESS="0.0.0.0"; # Can be set to a specific IP4 or IP6 address ("" for all interfaces)
+ DB_ENGINE="badger"; # badger, lmdb (lmdb works best with an nvme, otherwise you might have stability issues)
+ LMDB_MAPSIZE=3000000000; # 0 for default (currently ~273GB), or set to a different size in bytes, e.g. 10737418240 for 10GB
+ BLOSSOM_PATH="blossom/";
+
+## Private Relay Settings
+ PRIVATE_RELAY_NAME="*name* private relay";
+ PRIVATE_RELAY_NPUB="";
+ PRIVATE_RELAY_DESCRIPTION="The Relay From Sovran Systems";
+#PRIVATE_RELAY_ICON="https://i.nostr.build/6G6wW.gif"
+
+## Private Relay Rate Limiters
+ PRIVATE_RELAY_EVENT_IP_LIMITER_TOKENS_PER_INTERVAL=50;
+ PRIVATE_RELAY_EVENT_IP_LIMITER_INTERVAL=1;
+ PRIVATE_RELAY_EVENT_IP_LIMITER_MAX_TOKENS=100;
+ PRIVATE_RELAY_ALLOW_EMPTY_FILTERS=true;
+ PRIVATE_RELAY_ALLOW_COMPLEX_FILTERS=true;
+ PRIVATE_RELAY_CONNECTION_RATE_LIMITER_TOKENS_PER_INTERVAL=3;
+ PRIVATE_RELAY_CONNECTION_RATE_LIMITER_INTERVAL=5;
+ PRIVATE_RELAY_CONNECTION_RATE_LIMITER_MAX_TOKENS=9;
+
+## Chat Relay Settings
+ CHAT_RELAY_NAME="*name* chat relay";
+ CHAT_RELAY_NPUB="";
+ CHAT_RELAY_DESCRIPTION="a relay for private chats";
+#CHAT_RELAY_ICON="https://i.nostr.build/6G6wW.gif"
+ CHAT_RELAY_WOT_DEPTH=3;
+ CHAT_RELAY_WOT_REFRESH_INTERVAL_HOURS=24;
+ CHAT_RELAY_MINIMUM_FOLLOWERS=3;
+
+## Chat Relay Rate Limiters
+ CHAT_RELAY_EVENT_IP_LIMITER_TOKENS_PER_INTERVAL=50;
+ CHAT_RELAY_EVENT_IP_LIMITER_INTERVAL=1;
+ CHAT_RELAY_EVENT_IP_LIMITER_MAX_TOKENS=100;
+ CHAT_RELAY_ALLOW_EMPTY_FILTERS=false;
+ CHAT_RELAY_ALLOW_COMPLEX_FILTERS=false;
+ CHAT_RELAY_CONNECTION_RATE_LIMITER_TOKENS_PER_INTERVAL=3;
+ CHAT_RELAY_CONNECTION_RATE_LIMITER_INTERVAL=3;
+ CHAT_RELAY_CONNECTION_RATE_LIMITER_MAX_TOKENS=9;
+
+## Outbox Relay Settings
+ OUTBOX_RELAY_NAME="*name* outbox relay";
+ OUTBOX_RELAY_NPUB="";
+ OUTBOX_RELAY_DESCRIPTION="a relay and Blossom server for public messages and media";
+#OUTBOX_RELAY_ICON="https://i.nostr.build/6G6wW.gif"
+
+## Outbox Relay Rate Limiters
+ OUTBOX_RELAY_EVENT_IP_LIMITER_TOKENS_PER_INTERVAL=100;
+ OUTBOX_RELAY_EVENT_IP_LIMITER_INTERVAL=600;
+ OUTBOX_RELAY_EVENT_IP_LIMITER_MAX_TOKENS=1000;
+ OUTBOX_RELAY_ALLOW_EMPTY_FILTERS=true;
+ OUTBOX_RELAY_ALLOW_COMPLEX_FILTERS=true;
+ OUTBOX_RELAY_CONNECTION_RATE_LIMITER_TOKENS_PER_INTERVAL=30;
+ OUTBOX_RELAY_CONNECTION_RATE_LIMITER_INTERVAL=10;
+ OUTBOX_RELAY_CONNECTION_RATE_LIMITER_MAX_TOKENS=90;
+
+## Inbox Relay Settings
+ INBOX_RELAY_NAME="*name* inbox relay";
+ INBOX_RELAY_NPUB="";
+ INBOX_RELAY_DESCRIPTION="send your interactions with my notes here";
+#INBOX_RELAY_ICON="https://i.nostr.build/6G6wW.gif"
+ INBOX_PULL_INTERVAL_SECONDS=600;
+
+## Inbox Relay Rate Limiters
+ INBOX_RELAY_EVENT_IP_LIMITER_TOKENS_PER_INTERVAL=10;
+ INBOX_RELAY_EVENT_IP_LIMITER_INTERVAL=1;
+ INBOX_RELAY_EVENT_IP_LIMITER_MAX_TOKENS=20;
+ INBOX_RELAY_ALLOW_EMPTY_FILTERS=false;
+ INBOX_RELAY_ALLOW_COMPLEX_FILTERS=false;
+ INBOX_RELAY_CONNECTION_RATE_LIMITER_TOKENS_PER_INTERVAL=3;
+ INBOX_RELAY_CONNECTION_RATE_LIMITER_INTERVAL=1;
+ INBOX_RELAY_CONNECTION_RATE_LIMITER_MAX_TOKENS=9;
+
+## WOT Settings
+ WOT_FETCH_TIMEOUT_SECONDS=60;
+
+ WHITELISTED_NPUBS_FILE="/var/lib/haven/whitelisted_npubs.json";
+
+ BLACKLISTED_NPUBS_FILE="";
+
+
+## LOGGING
+ HAVEN_LOG_LEVEL="INFO"; # DEBUG, INFO, WARNING or ERROR
+ };
+
+ blastrRelays = [
+ "nos.lol"
+ "relay.nostr.band"
+ "relay.snort.social"
+ "nostr.mom"
+ "relay.primal.net"
+ "no.str.cr"
+ "nostr21.com"
+ "nostrue.com"
+ "wot.nostr.party"
+ "wot.sovbit.host"
+ "wot.girino.org"
+ "relay.lexingtonbitcoin.org"
+ "zap.watch"
+ "satsage.xyz"
+ "wons.calva.dev"
+ ];
+
+ };
+
+ systemd.tmpfiles.rules = [
+ "d /var/lib/haven 0750 haven haven -"
+ "f /var/lib/haven/whitelisted_npubs.json 0770 haven haven -"
+ ];
+
+ services.caddy = {
+ virtualHosts = {
+ "${personalization.haven_url}" = {
+ extraConfig = ''
+ reverse_proxy localhost:3355 {
+ header_up Host {host}
+ header_up X-Real-IP {remote_host}
+ header_up X-Forwarded-For {remote_host}
+ header_up X-Forwarded-Proto {scheme}
+ transport http {
+ versions 1.1
+ }
+ }
+ request_body {
+ max_size 100MB
+ }
+ '';
+ };
+ };
+ };
+}
+
+
diff --git a/modules/mempool.nix b/modules/mempool.nix
new file mode 100755
index 0000000..e95f793
--- /dev/null
+++ b/modules/mempool.nix
@@ -0,0 +1,25 @@
+{ config, pkgs, lib, ... }:
+
+{
+
+ services.mempool = {
+ enable = true;
+ frontend.enable = true;
+ };
+
+ services.mysql.package = lib.mkForce pkgs.mariadb;
+
+ nix-bitcoin.onionServices.mempool-frontend.enable = true;
+
+ services.caddy = {
+ virtualHosts = {
+ ":60847" = {
+ extraConfig = ''
+ reverse_proxy :60845
+ encode gzip zstd
+ '';
+ };
+ };
+ };
+
+}
diff --git a/modules/modules.nix b/modules/modules.nix
index c4617cb..8e705fd 100755
--- a/modules/modules.nix
+++ b/modules/modules.nix
@@ -1,15 +1,21 @@
{ config, pkgs, lib, ... }:
{
-
- imports = [
-
- ./php.nix
- ./synapse.nix
- ./coturn.nix
- ./bitcoinecosystem.nix
- ./vaultwarden.nix
- ./Sovran_SystemsOS_File_Fixes_And_New_Services.nix
-
- ];
+ imports =
+ [
+ ./core/roles.nix
+ ./core/role-logic.nix
+ ./php.nix
+ ./Sovran_SystemsOS_File_Fixes_And_New_Services.nix
+ ]
+ ++ lib.optional config.sovran_systemsOS.features.synapse ./synapse.nix
+ ++ lib.optional config.sovran_systemsOS.features.coturn ./coturn.nix
+ ++ lib.optional config.sovran_systemsOS.features.bitcoin ./bitcoinecosystem.nix
+ ++ lib.optional config.sovran_systemsOS.features.vaultwarden ./vaultwarden.nix
+ ++ lib.optional config.sovran_systemsOS.features.haven ./haven.nix
+ ++ lib.optional config.sovran_systemsOS.features.bip110 ./bip110.nix
+ ++ lib.optional config.sovran_systemsOS.features.element-calling ./element-calling.nix
+ ++ lib.optional config.sovran_systemsOS.features.mempool ./mempool.nix
+ ++ lib.optional config.sovran_systemsOS.features.bitcoin-core ./bitcoin-core.nix
+ ++ lib.optional config.sovran_systemsOS.features.rdp ./rdp.nix;
}
diff --git a/modules/personalization.nix b/modules/personalization.nix
index b2f2ca5..f828a53 100755
--- a/modules/personalization.nix
+++ b/modules/personalization.nix
@@ -6,6 +6,8 @@ nextcloud_url = builtins.readFile /var/lib/domains/nextcloud;
btcpayserver_url = builtins.readFile /var/lib/domains/btcpayserver;
caddy_email_for_acme = builtins.readFile /var/lib/domains/sslemail;
vaultwarden_url = builtins.readFile /var/lib/domains/vaultwarden;
+haven_url = builtins.readFile /var/lib/domains/haven;
+element-calling_url = builtins.readFile /var/lib/domains/element-calling;
##
diff --git a/modules/rdp.nix b/modules/rdp.nix
new file mode 100755
index 0000000..2f3c7a7
--- /dev/null
+++ b/modules/rdp.nix
@@ -0,0 +1,52 @@
+{ config, pkgs, lib, ... }:
+
+{
+ services.gnome.gnome-remote-desktop.enable = true;
+
+ systemd.services.gnome-remote-desktop = {
+ wantedBy = [ "graphical.target" ]; # for starting the unit automatically at boot
+ };
+
+ services.displayManager.autoLogin.enable = lib.mkForce false;
+
+ networking.firewall.allowedTCPPorts = [ 3389 ];
+
+ environment.systemPackages = with pkgs; [
+ freerdp
+ ];
+
+ systemd.services.gnome-remote-desktop-setup = {
+ description = "Initialize GNOME Remote Desktop RDP TLS and config";
+ wantedBy = [ "multi-user.target" ];
+ after = [ "gnome-remote-desktop.service" ];
+
+ serviceConfig = {
+ Type = "oneshot";
+ StateDirectory = "gnome-remote-desktop";
+ };
+
+ script = ''
+ set -e
+
+ CERT_DIR=/var/lib/gnome-remote-desktop
+ KEY_FILE=$CERT_DIR/rdp-tls.key
+ CRT_FILE=$CERT_DIR/rdp-tls.crt
+
+ if [ ! -f "$KEY_FILE" ]; then
+ echo "Generating RDP TLS certificate..."
+
+ runuser -u gnome-remote-desktop -- \
+ ${pkgs.freerdp}/bin/winpr-makecert -silent -rdp \
+ -path "$CERT_DIR" rdp-tls
+ else
+ echo "TLS key already exists, skipping generation"
+ fi
+
+ # Always ensure config is set (safe to re-run)
+ ${pkgs.gnome.gnome-remote-desktop}/bin/grdctl --system rdp set-tls-key "$KEY_FILE"
+ ${pkgs.gnome.gnome-remote-desktop}/bin/grdctl --system rdp set-tls-cert "$CRT_FILE"
+ ${pkgs.gnome.gnome-remote-desktop}/bin/grdctl --system rdp enable
+ ${pkgs.gnome.gnome-remote-desktop}/bin/grdctl --system rdp set-credentials "free" "a"
+ '';
+ };
+}