From 66f18445870dc1e0268b6ef1591382567ffbbcad Mon Sep 17 00:00:00 2001 From: LeCoffre Deployment Date: Wed, 1 Oct 2025 15:51:55 +0000 Subject: [PATCH] chore: sync projects/lecoffre/lecoffre_node compose paths, add scripts/push_modules.sh, set bitcoin datadir to projects tree --- .gitignore | 97 +- .gitmodules | 53 +- 4NK_modules/4NK_certificator | 1 + 4NK_modules/4NK_miner | 1 + 4NK_modules/4NK_vault | 1 + 4NK_modules/4NK_web_status | 1 + .../blindbit-oracle | 0 ihm_client => 4NK_modules/ihm_client | 0 4NK_modules/rust-silentpayments | 1 + 4NK_modules/sdk-signer-client | 1 + 4NK_modules/sdk_client | 1 + 4NK_modules/sdk_common | 1 + sdk_relay => 4NK_modules/sdk_relay | 0 4NK_modules/sdk_signer | 1 + sdk_storage => 4NK_modules/sdk_storage | 0 4NK_modules/skeleton | 1 + IA_agents/blindbit-oracle-deployment.md | 2 + .../blindbit-oracle-integration-summary.md | 2 + IA_agents/env-centralisation-policy.md | 2 + .../scripts/nginx-config-symlink.sh | 153 +++ .../scripts/quick-health-check.sh | 3 + IA_agents/prompts/prompt-logs/prompt.md | 6 +- confs/bitcoin/bitcoin.conf | 45 - confs/blindbit-oracle/blindbit.toml | 18 - confs/grafana/grafana.ini | 57 - confs/loki/loki-config.yaml | 76 -- confs/promtail/promtail.yml | 107 -- confs/supervisor/supervisord.conf | 51 - confs/tor/torrc | 21 - docs/CERTIFICATOR_SPECIFICATION.md | 1140 +++++++++++++++++ ...IABLES-ENVIRONNEMENT-NOUVELLE-STRUCTURE.md | 2 + lecoffre-front | 1 - lecoffre_node | 1 - projects/lecoffre/lecoffre-front | 1 + projects/lecoffre/lecoffre_node | 1 + scripts/lecoffre_node/blindbit-maintenance.sh | 2 + .../lecoffre_node/collect-blindbit-logs.sh | 2 + scripts/lecoffre_node/quick-health-check.sh | 2 + scripts/lecoffre_node/wait-bitcoin-ready.sh | 2 + scripts/lecoffre_node/wait-tor-bootstrap.sh | 2 + scripts/push_modules.sh | 89 ++ vault | 1 - 42 files changed, 1485 insertions(+), 464 deletions(-) create mode 160000 4NK_modules/4NK_certificator create mode 160000 4NK_modules/4NK_miner create mode 160000 4NK_modules/4NK_vault create mode 160000 4NK_modules/4NK_web_status rename blindbit-oracle => 4NK_modules/blindbit-oracle (100%) rename ihm_client => 4NK_modules/ihm_client (100%) create mode 160000 4NK_modules/rust-silentpayments create mode 160000 4NK_modules/sdk-signer-client create mode 160000 4NK_modules/sdk_client create mode 160000 4NK_modules/sdk_common rename sdk_relay => 4NK_modules/sdk_relay (100%) create mode 160000 4NK_modules/sdk_signer rename sdk_storage => 4NK_modules/sdk_storage (100%) create mode 160000 4NK_modules/skeleton create mode 100755 IA_agents/prompts/prompt-deploy/scripts/nginx-config-symlink.sh delete mode 100644 confs/bitcoin/bitcoin.conf delete mode 100644 confs/blindbit-oracle/blindbit.toml delete mode 100644 confs/grafana/grafana.ini delete mode 100644 confs/loki/loki-config.yaml delete mode 100644 confs/promtail/promtail.yml delete mode 100644 confs/supervisor/supervisord.conf delete mode 100644 confs/tor/torrc create mode 100644 docs/CERTIFICATOR_SPECIFICATION.md delete mode 160000 lecoffre-front delete mode 160000 lecoffre_node create mode 160000 projects/lecoffre/lecoffre-front create mode 160000 projects/lecoffre/lecoffre_node create mode 100644 scripts/push_modules.sh delete mode 160000 vault diff --git a/.gitignore b/.gitignore index d972538..a7301d1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,30 +2,30 @@ # ============================ # Dossiers de sauvegarde des scripts -*.backup/ -*/backup/ -*/*.backup* +**/backup/ +**/*backup* + +**/.cargo/ -.cargo/ -Cargo.lock -*/.cargo/ -*/Cargo.lock -*.cargo/ -*Cargo.lock # Fichiers temporaires -*.tmp -*.temp -*.log -*.pid +**/*.tmp* +**/*.temp* +**/*.log* +**/*.pid* # Fichiers de configuration locale **/*.env* +**/*.conf* +**/*.yaml* +**/*.yml* +**/*.ini* +**/*.json* +**/*.toml* +**/*.lock* # Données et logs -**/data/ -**/logs/ **/*.logs* **/*.data *.db @@ -41,72 +41,43 @@ ssl/ certs/ # Docker -.docker/ -docker-data/ -docker-volumes/ +**/*.docker* # Cache et build **/*.node_modules/ **/*.dist/ -**/*.build/ -**/*.target/ +**/*build/ +**/*target/ **/*.*.o **/*.so **/*.dylib # IDE et éditeurs -.vscode/ -.idea/ -*.swp -*.swo -*~ +**/*.vscode/ +**/*.idea/ +**/*.swp +**/*.swo +**/*~ # OS -.DS_Store -Thumbs.db -*.tmp +**/*.DS_Store +**/*Thumbs.db +**/*tmp* # Git -.git/ -*.orig +**/*.git/ +**/*.orig* # Backup des projets existants -*.backup/ +**/*backup* -# Fichiers de configuration spécifiques au host -host-config/ -local-config/ -# Données sensibles -secrets/ -private/ -confidential/ - -# Monitoring et métriques -prometheus-data/ -grafana-data/ -loki-data/ - -# Bitcoin et crypto -.bitcoin/ -.4nk/ -wallet/ -keys/ - -# Nginx -nginx-cache/ -nginx-logs/ +**/*wallet* +**/*keys* # Supervisor supervisor-logs/ -# Scripts de déploiement temporaires -deploy-*.tmp -setup-*.tmp -.cursor-server -/home/debian/4NK_env/logs/ -/home/debian/4NK_env/backups/ -backups/ - - -confs \ No newline at end of file +**/*node_modules* +**/*cursor* +**/*pid* \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index a51240a..3a7ba0e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,56 +1,69 @@ -[submodule "lecoffre_node"] - path = lecoffre_node - url = git@git.4nkweb.com:4nk/lecoffre_node.git - branch = ext [submodule "sdk_relay"] - path = sdk_relay + path = 4NK_modules/sdk_relay url = git@git.4nkweb.com:4nk/sdk_relay.git branch = ext [submodule "sdk_storage"] - path = sdk_storage + path = 4NK_modules/sdk_storage url = git@git.4nkweb.com:4nk/sdk_storage.git branch = ext [submodule "ihm_client"] - path = ihm_client + path = 4NK_modules/ihm_client url = git@git.4nkweb.com:4nk/ihm_client.git branch = ext -[submodule "lecoffre-front"] - path = lecoffre-front - url = git@git.4nkweb.com:4nk/lecoffre-front.git - branch = ext [submodule "doc_api"] - path = doc_api + path = 4NK_modules/doc_api url = git@git.4nkweb.com:4nk/doc_api.git branch = ext [submodule "sdk_signer"] - path = sdk_signer + path = 4NK_modules/sdk_signer url = git@git.4nkweb.com:4nk/sdk_signer.git branch = ext [submodule "skeleton"] - path = skeleton + path = 4NK_modules/skeleton url = git@git.4nkweb.com:4nk/skeleton.git branch = dev [submodule "sdk-signer-client"] - path = sdk-signer-client + path = 4NK_modules/sdk-signer-client url = git@git.4nkweb.com:4nk/sdk-signer-client.git branch = ext [submodule "sdk_client"] - path = sdk_client + path = 4NK_modules/sdk_client url = git@git.4nkweb.com:4nk/sdk_client.git branch = ext [submodule "sdk_common"] - path = sdk_common + path = 4NK_modules/sdk_common url = git@git.4nkweb.com:4nk/sdk_common.git branch = ext [submodule "rust-silentPayments"] - path = rust-silentPayments + path = 4NK_modules/rust-silentPayments url = git@github.com:Sosthene00/rust-silentPayments.git branch = add-utils [submodule "blindbit-oracle"] - path = blindbit-oracle + path = 4NK_modules/blindbit-oracle url = https://github.com/setavenger/blindbit-oracle.git branch = master [submodule "4NK_vault"] - path = vault + path = 4NK_modules/4NK_vault url = git@git.4nkweb.com:4nk/4NK_vault.git + branch = ext +[submodule "4NK_certificator"] + path = 4NK_certificator + url = git@git.4nkweb.com:4nk/4NK_certificator.git + branch = main +[submodule "4NK_miner"] + path = 4NK_miner + url = git@git.4nkweb.com:4nk/4NK_miner.git + branch = main +[submodule "4NK_web_status"] + path = 4NK_web_status + url = git@git.4nkweb.com:4nk/4NK_web_status.git + branch = main + +[submodule "lecoffre-front"] + path = projects/lecoffre/lecoffre-front + url = git@git.4nkweb.com:4nk/lecoffre-front.git + branch = ext +[submodule "lecoffre_node"] + path = projects/lecoffre/lecoffre_node + url = git@git.4nkweb.com:4nk/lecoffre_node.git branch = ext \ No newline at end of file diff --git a/4NK_modules/4NK_certificator b/4NK_modules/4NK_certificator new file mode 160000 index 0000000..8006ba9 --- /dev/null +++ b/4NK_modules/4NK_certificator @@ -0,0 +1 @@ +Subproject commit 8006ba998656a3d80dc0f9a3cdd4668cec0aadcd diff --git a/4NK_modules/4NK_miner b/4NK_modules/4NK_miner new file mode 160000 index 0000000..5b504e2 --- /dev/null +++ b/4NK_modules/4NK_miner @@ -0,0 +1 @@ +Subproject commit 5b504e2679dc695bf0fac7faeef55bacc37b824f diff --git a/4NK_modules/4NK_vault b/4NK_modules/4NK_vault new file mode 160000 index 0000000..f4a8dd2 --- /dev/null +++ b/4NK_modules/4NK_vault @@ -0,0 +1 @@ +Subproject commit f4a8dd2e7fc9371c3d591f0afcc09b0e54bdf872 diff --git a/4NK_modules/4NK_web_status b/4NK_modules/4NK_web_status new file mode 160000 index 0000000..643bda3 --- /dev/null +++ b/4NK_modules/4NK_web_status @@ -0,0 +1 @@ +Subproject commit 643bda3eef1eac751b9e75f6a71b8033041a7a17 diff --git a/blindbit-oracle b/4NK_modules/blindbit-oracle similarity index 100% rename from blindbit-oracle rename to 4NK_modules/blindbit-oracle diff --git a/ihm_client b/4NK_modules/ihm_client similarity index 100% rename from ihm_client rename to 4NK_modules/ihm_client diff --git a/4NK_modules/rust-silentpayments b/4NK_modules/rust-silentpayments new file mode 160000 index 0000000..2c3deb8 --- /dev/null +++ b/4NK_modules/rust-silentpayments @@ -0,0 +1 @@ +Subproject commit 2c3deb8831ce2ed2201b386bf51cb450f26da6d8 diff --git a/4NK_modules/sdk-signer-client b/4NK_modules/sdk-signer-client new file mode 160000 index 0000000..ff3e14a --- /dev/null +++ b/4NK_modules/sdk-signer-client @@ -0,0 +1 @@ +Subproject commit ff3e14a86da668caeaf654d94db8ad939820b0b9 diff --git a/4NK_modules/sdk_client b/4NK_modules/sdk_client new file mode 160000 index 0000000..c09135c --- /dev/null +++ b/4NK_modules/sdk_client @@ -0,0 +1 @@ +Subproject commit c09135c4eb785fa5ef242cd106bb1e628d5f68fa diff --git a/4NK_modules/sdk_common b/4NK_modules/sdk_common new file mode 160000 index 0000000..72bb222 --- /dev/null +++ b/4NK_modules/sdk_common @@ -0,0 +1 @@ +Subproject commit 72bb22282737d9140cfd2fbfc9111b9c10d7e3ff diff --git a/sdk_relay b/4NK_modules/sdk_relay similarity index 100% rename from sdk_relay rename to 4NK_modules/sdk_relay diff --git a/4NK_modules/sdk_signer b/4NK_modules/sdk_signer new file mode 160000 index 0000000..089bf06 --- /dev/null +++ b/4NK_modules/sdk_signer @@ -0,0 +1 @@ +Subproject commit 089bf06502eef2fb49e99ba9e614ddf3cbf7c3a0 diff --git a/sdk_storage b/4NK_modules/sdk_storage similarity index 100% rename from sdk_storage rename to 4NK_modules/sdk_storage diff --git a/4NK_modules/skeleton b/4NK_modules/skeleton new file mode 160000 index 0000000..68f6b31 --- /dev/null +++ b/4NK_modules/skeleton @@ -0,0 +1 @@ +Subproject commit 68f6b31a6c573fcbc4addef9f5aae2b11096b25f diff --git a/IA_agents/blindbit-oracle-deployment.md b/IA_agents/blindbit-oracle-deployment.md index 5e315fe..41265ef 100644 --- a/IA_agents/blindbit-oracle-deployment.md +++ b/IA_agents/blindbit-oracle-deployment.md @@ -252,3 +252,5 @@ docker logs blindbit-oracle | grep -i "error" + + diff --git a/IA_agents/blindbit-oracle-integration-summary.md b/IA_agents/blindbit-oracle-integration-summary.md index 1f08cc3..9bdd302 100644 --- a/IA_agents/blindbit-oracle-integration-summary.md +++ b/IA_agents/blindbit-oracle-integration-summary.md @@ -184,3 +184,5 @@ blindbit: + + diff --git a/IA_agents/env-centralisation-policy.md b/IA_agents/env-centralisation-policy.md index 77575fb..81d6f77 100644 --- a/IA_agents/env-centralisation-policy.md +++ b/IA_agents/env-centralisation-policy.md @@ -263,3 +263,5 @@ La nouvelle structure des variables d'environnement améliore la sécurité, la + + diff --git a/IA_agents/prompts/prompt-deploy/scripts/nginx-config-symlink.sh b/IA_agents/prompts/prompt-deploy/scripts/nginx-config-symlink.sh new file mode 100755 index 0000000..fe6b80b --- /dev/null +++ b/IA_agents/prompts/prompt-deploy/scripts/nginx-config-symlink.sh @@ -0,0 +1,153 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Script pour remplacer les configurations nginx par des liens symboliques +# vers les fichiers centralisés dans /home/debian/4NK_env/confs/nginx + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ROOT_DIR="$(cd "$SCRIPT_DIR/../../../.." && pwd)" +NGINX_CONF_DIR="/home/debian/4NK_env/confs/nginx" +NGINX_ACTIVE_DIR="/etc/nginx/sites-available" +NGINX_ENABLED_DIR="/etc/nginx/sites-enabled" + +echo "==========================================" +echo " Configuration Nginx - Liens Symboliques" +echo "==========================================" + +# Vérifier que le répertoire de configuration centralisé existe +if [ ! -d "$NGINX_CONF_DIR" ]; then + echo "❌ Erreur: Le répertoire $NGINX_CONF_DIR n'existe pas" + exit 1 +fi + +echo "📁 Répertoire de configuration centralisé: $NGINX_CONF_DIR" +echo "📁 Répertoire nginx sites-available: $NGINX_ACTIVE_DIR" +echo "📁 Répertoire nginx sites-enabled: $NGINX_ENABLED_DIR" + +# Fonction pour créer un lien symbolique +create_symlink() { + local source="$1" + local target="$2" + local description="$3" + + echo "🔗 Création du lien: $description" + echo " Source: $source" + echo " Cible: $target" + + # Supprimer le fichier/cible existant s'il existe + if [ -e "$target" ] || [ -L "$target" ]; then + echo " Suppression de l'ancien fichier/lien: $target" + sudo rm -f "$target" + fi + + # Créer le lien symbolique + sudo ln -sf "$source" "$target" + + if [ -L "$target" ]; then + echo " ✅ Lien créé avec succès" + else + echo " ❌ Erreur lors de la création du lien" + return 1 + fi +} + +echo "" +echo "🔧 Création des liens symboliques..." + +# Lister les fichiers de configuration dans le répertoire centralisé +config_files=$(find "$NGINX_CONF_DIR" -name "*.conf" -type f) + +if [ -z "$config_files" ]; then + echo "❌ Aucun fichier .conf trouvé dans $NGINX_CONF_DIR" + exit 1 +fi + +echo "📋 Fichiers de configuration trouvés:" +echo "$config_files" | while read -r file; do + echo " - $(basename "$file")" +done + +echo "" +echo "🔗 Création des liens dans sites-available..." + +# Créer les liens dans sites-available +echo "$config_files" | while read -r source_file; do + filename=$(basename "$source_file") + target_file="$NGINX_ACTIVE_DIR/$filename" + + create_symlink "$source_file" "$target_file" "$filename" +done + +echo "" +echo "📋 Configuration actuelle de nginx..." + +# Lister les configurations actives (sites-available) +echo "📁 Fichiers dans sites-available:" +if [ -d "$NGINX_ACTIVE_DIR" ]; then + ls -la "$NGINX_ACTIVE_DIR" | grep -E "\.(conf|link)$" || echo " Aucun fichier .conf trouvé" +else + echo " ❌ Répertoire $NGINX_ACTIVE_DIR n'existe pas" +fi + +# Lister les configurations activées (sites-enabled) +echo "" +echo "📁 Fichiers dans sites-enabled:" +if [ -d "$NGINX_ENABLED_DIR" ]; then + ls -la "$NGINX_ENABLED_DIR" | grep -E "\.(conf|link)$" || echo " Aucun fichier .conf activé" +else + echo " ❌ Répertoire $NGINX_ENABLED_DIR n'existe pas" +fi + +echo "" +echo "🧪 Test de la configuration nginx..." + +# Tester la configuration nginx +if sudo nginx -t; then + echo "✅ Configuration nginx valide" + + echo "" + echo "🔄 Redémarrage de nginx..." + + # Redémarrer nginx + if sudo systemctl reload nginx; then + echo "✅ Nginx rechargé avec succès" + else + echo "❌ Erreur lors du rechargement de nginx" + echo "🔄 Tentative de redémarrage complet..." + if sudo systemctl restart nginx; then + echo "✅ Nginx redémarré avec succès" + else + echo "❌ Erreur lors du redémarrage de nginx" + exit 1 + fi + fi + + echo "" + echo "📊 Statut de nginx:" + sudo systemctl status nginx --no-pager -l + +else + echo "❌ Configuration nginx invalide" + echo "🔍 Détails de l'erreur:" + sudo nginx -t 2>&1 || true + exit 1 +fi + +echo "" +echo "==========================================" +echo "✅ Configuration nginx terminée avec succès" +echo "==========================================" + +# Afficher un résumé des liens créés +echo "" +echo "📋 Résumé des liens créés:" +echo "$config_files" | while read -r source_file; do + filename=$(basename "$source_file") + target_file="$NGINX_ACTIVE_DIR/$filename" + if [ -L "$target_file" ]; then + echo " ✅ $filename -> $(readlink "$target_file")" + else + echo " ❌ $filename -> Lien non créé" + fi +done + diff --git a/IA_agents/prompts/prompt-deploy/scripts/quick-health-check.sh b/IA_agents/prompts/prompt-deploy/scripts/quick-health-check.sh index 5540c21..304e8a8 100644 --- a/IA_agents/prompts/prompt-deploy/scripts/quick-health-check.sh +++ b/IA_agents/prompts/prompt-deploy/scripts/quick-health-check.sh @@ -12,3 +12,6 @@ if [ ! -x "$CHECK" ]; then fi exec "$CHECK" + + + diff --git a/IA_agents/prompts/prompt-logs/prompt.md b/IA_agents/prompts/prompt-logs/prompt.md index de27c36..7230ad4 100644 --- a/IA_agents/prompts/prompt-logs/prompt.md +++ b/IA_agents/prompts/prompt-logs/prompt.md @@ -1,10 +1,10 @@ ## Consignes de production et de consultation des logs ### Centralisation des logs -- Dossier central: `/home/debian/4NK_env/logs/` +- Dossier central: `/home/debian/4NK_env/lecoffre_node/logs/` - Sous-dossiers standardisés par service: - `nginx/`, `lecoffre-front/`, `ihm_client/`, `sdk_relay/`, `sdk_storage/`, `bitcoin/`, `blindbit/`, `miner/`, `tor/` -- Docker Compose monte chaque service avec un volume: `/home/debian/4NK_env/logs/:/var/log/` +- Docker Compose monte chaque service avec un volume: `/home/debian/4NK_env/lecoffre_node/logs/:/var/log/` ### Instrumentation et propagation - Nginx JSON logging via `lecoffre_node/conf/nginx/logging.conf` avec `log_format lecoffre_json` incluant: `time`, `request_id`, `remote_addr`, `host`, `method`, `uri`, `args`, `status`, `bytes`, `referer`, `user_agent`, `request_time`, `upstream_*`, `x_forwarded_for`. @@ -23,7 +23,7 @@ - `grep '"/api/v1/idnot/' /home/debian/4NK_env/logs/nginx/lecoffre_front_access.log | jq . | tail -n 50` ### Promtail → Loki → Grafana -- Promtail scrute: `/home/debian/4NK_env/logs/**` (jobs par service). +- Promtail scrute: `/home/debian/4NK_env/lecoffre_node/logs/**` (jobs par service). - Loki reçoit sur `http://loki:3100`. - Grafana (local): `https://dev4.4nkweb.com/grafana/` → Explore → Datasource Loki. - Requêtes utiles: `{job="lecoffre-front"}`, `{job="nginx"}`, `{job="sdk_relay"}`. diff --git a/confs/bitcoin/bitcoin.conf b/confs/bitcoin/bitcoin.conf deleted file mode 100644 index c08ca72..0000000 --- a/confs/bitcoin/bitcoin.conf +++ /dev/null @@ -1,45 +0,0 @@ -# Configuration globale -signet=1 -server=1 -datadir=/home/debian/4NK_env/logs/bitcoin - -[signet] -daemon=0 -txindex=1 -upnp=1 -#debug=1 -#loglevel=debug -logthreadnames=1 -onion=tor:9050 -listenonion=1 -onlynet=onion - -# Paramètres RPC -rpcauth=bitcoin:c8ea921c7357bd6a5a8a7c43a12350a7$955e25b17672987b17c5a12f12cd8b9c1d38f0f86201c8cd47fc431f2e1c7956 -rpcallowip=0.0.0.0/0 -rpcworkqueue=32 -rpcthreads=4 -rpcdoccheck=1 - -# Paramètres ZMQ -zmqpubhashblock=tcp://:29000 -zmqpubrawtx=tcp://:29001 - -listen=1 -bind=:38333 -rpcbind=:38332 -rpcport=38332 -fallbackfee=0.0001 -blockfilterindex=1 -datacarriersize=205 -acceptnonstdtxn=1 -dustrelayfee=0.00000001 -minrelaytxfee=0.00000001 -prune=0 -signetchallenge=0020341c43803863c252df326e73574a27d7e19322992061017b0dc893e2eab90821 -wallet=mining -wallet=watchonly -maxtxfee=1 -addnode=tlv2yqamflv22vfdzy2hha2nwmt6zrwrhjjzz4lx7qyq7lyc6wfhabyd.onion -addnode=6xi33lwwslsx3yi3f7c56wnqtdx4v73vj2up3prrwebpwbz6qisnqbyd.onion -addnode=id7e3r3d2epen2v65jebjhmx77aimu7oyhcg45zadafypr4crqsytfid.onion \ No newline at end of file diff --git a/confs/blindbit-oracle/blindbit.toml b/confs/blindbit-oracle/blindbit.toml deleted file mode 100644 index 715f697..0000000 --- a/confs/blindbit-oracle/blindbit.toml +++ /dev/null @@ -1,18 +0,0 @@ -# Configuration Blindbit Oracle -host = "0.0.0.0:8000" -chain = "signet" -rpc_endpoint = "http://bitcoin:38332" -cookie_path = "/home/debian/4NK_env/data/bitcoin/signet/.cookie" -rpc_user = "" -rpc_pass = "" -sync_start_height = 1 - -# Performance -max_parallel_tweak_computations = 4 -max_parallel_requests = 4 - -# Index -tweaks_only = 0 -tweaks_full_basic = 1 -tweaks_full_with_dust_filter = 1 -tweaks_cut_through_with_dust_filter = 1 diff --git a/confs/grafana/grafana.ini b/confs/grafana/grafana.ini deleted file mode 100644 index a637557..0000000 --- a/confs/grafana/grafana.ini +++ /dev/null @@ -1,57 +0,0 @@ -# Configuration Grafana avancée pour LeCoffre Node - -[server] -# URL publique de Grafana -root_url = https://dev4.4nkweb.com/grafana - -# Configuration de sécurité -enable_gzip = true -cert_file = -cert_key = -enforce_domain = false - -[security] -# Configuration de sécurité -admin_user = admin -admin_password = admin123 -secret_key = lecoffre_grafana_secret_key_2025 - -# Configuration des sessions -cookie_secure = true -cookie_samesite = strict - -[users] -# Configuration des utilisateurs -allow_sign_up = false -allow_org_create = false -auto_assign_org = true -auto_assign_org_id = 1 -auto_assign_org_role = Viewer - -[auth.anonymous] -# Accès anonyme désactivé pour la sécurité -enabled = false - -[dashboards] -# Configuration des dashboards -default_home_dashboard_path = /home/debian/4NK_env/confs/grafana/dashboards/lecoffre-overview.json - -[unified_alerting] -# Configuration des alertes unifiées -enabled = true - -[log] -# Configuration des logs Grafana -mode = console -level = info -format = json - -[metrics] -# Métriques Prometheus -enabled = true -basic_auth_username = -basic_auth_password = - -[feature_toggles] -# Fonctionnalités activées -enable = traceqlEditor diff --git a/confs/loki/loki-config.yaml b/confs/loki/loki-config.yaml deleted file mode 100644 index f1bf1dd..0000000 --- a/confs/loki/loki-config.yaml +++ /dev/null @@ -1,76 +0,0 @@ -auth_enabled: false - -server: - http_listen_port: 3100 - grpc_listen_port: 9096 - http_listen_address: 0.0.0.0 - grpc_listen_address: 0.0.0.0 - -common: - instance_addr: 0.0.0.0 - path_prefix: /loki - storage: - filesystem: - chunks_directory: /loki/chunks - rules_directory: /loki/rules - replication_factor: 1 - ring: - kvstore: - store: inmemory - -schema_config: - configs: - - from: 2020-10-24 - store: tsdb - object_store: filesystem - schema: v13 - index: - prefix: index_ - period: 24h - -ruler: - alertmanager_url: http://localhost:9093 - -# Configuration de l'ingester - SEULEMENT le paramètre crucial -ingester: - lifecycler: - min_ready_duration: 5s # Réduit le délai de 15s à 5s - -# Configuration des limites -limits_config: - reject_old_samples: true - reject_old_samples_max_age: 168h - max_cache_freshness_per_query: 10m - split_queries_by_interval: 15m - max_query_parallelism: 32 - max_streams_per_user: 0 - max_line_size: 256000 - ingestion_rate_mb: 16 - ingestion_burst_size_mb: 32 - per_stream_rate_limit: 3MB - per_stream_rate_limit_burst: 15MB - max_entries_limit_per_query: 5000 - max_query_series: 500 - max_query_length: 721h - cardinality_limit: 100000 - max_streams_matchers_per_query: 1000 - max_concurrent_tail_requests: 10 - -# Configuration du storage -storage_config: - tsdb_shipper: - active_index_directory: /loki/tsdb-index - cache_location: /loki/tsdb-cache - filesystem: - directory: /loki/chunks - -# Configuration du compactor -compactor: - working_directory: /loki/compactor - compaction_interval: 10m - retention_enabled: false - delete_request_store: filesystem - -# Analytics désactivés -analytics: - reporting_enabled: false \ No newline at end of file diff --git a/confs/promtail/promtail.yml b/confs/promtail/promtail.yml deleted file mode 100644 index 6e83b0e..0000000 --- a/confs/promtail/promtail.yml +++ /dev/null @@ -1,107 +0,0 @@ -server: - http_listen_port: 8090 - grpc_listen_port: 0 - -positions: - filename: /tmp/positions.yaml - -clients: - - url: http://loki:3100/loki/api/v1/push - -scrape_configs: - # Bitcoin Signet Logs - - job_name: bitcoin - static_configs: - - targets: - - localhost - labels: - job: bitcoin - service: bitcoin-signet - __path__: /home/debian/4NK_env/lecoffre_node/logs/bitcoin/*.log - - # Blindbit Oracle Logs - - job_name: blindbit - static_configs: - - targets: - - localhost - labels: - job: blindbit - service: blindbit-oracle - __path__: /home/debian/4NK_env/lecoffre_node/logs/blindbit-oracle/*.log - - # SDK Relay Logs - - job_name: sdk_relay - static_configs: - - targets: - - localhost - labels: - job: sdk_relay - service: sdk_relay - __path__: /home/debian/4NK_env/lecoffre_node/logs/sdk_relay/*.log - - # SDK Storage Logs - - job_name: sdk_storage - static_configs: - - targets: - - localhost - labels: - job: sdk_storage - service: sdk_storage - __path__: /home/debian/4NK_env/lecoffre_node/logs/sdk_storage/*.log - - # LeCoffre Frontend Logs - - job_name: lecoffre-front - static_configs: - - targets: - - localhost - labels: - job: lecoffre-front - service: lecoffre-front - __path__: /home/debian/4NK_env/lecoffre_node/logs/lecoffre-front/*.log - - # IHM Client Logs - - job_name: ihm_client - static_configs: - - targets: - - localhost - labels: - job: ihm_client - service: ihm_client - __path__: /home/debian/4NK_env/lecoffre_node/logs/ihm_client/*.log - - # Miner Logs - - job_name: miner - static_configs: - - targets: - - localhost - labels: - job: miner - service: signet_miner - __path__: /home/debian/4NK_env/lecoffre_node/logs/miner/*.log - - # Tor Logs - - job_name: tor - static_configs: - - targets: - - localhost - labels: - job: tor - service: tor-proxy - __path__: /home/debian/4NK_env/lecoffre_node/logs/tor/*.log - - # Docker Container Logs - - job_name: docker - docker_sd_configs: - - host: unix:///var/run/docker.sock - refresh_interval: 5s - filters: - - name: label - values: ["com.centurylinklabs.watchtower.enable=true"] - relabel_configs: - - source_labels: ['__meta_docker_container_name'] - regex: '/?(.*)' - target_label: 'container_name' - - source_labels: ['__meta_docker_container_log_stream'] - target_label: 'logstream' - - source_labels: ['__meta_docker_container_label_logging_job_name'] - target_label: 'job' diff --git a/confs/supervisor/supervisord.conf b/confs/supervisor/supervisord.conf deleted file mode 100644 index b4b99e7..0000000 --- a/confs/supervisor/supervisord.conf +++ /dev/null @@ -1,51 +0,0 @@ -[supervisord] -nodaemon=true -user=root -logfile=/var/log/supervisor/supervisord.log -pidfile=/var/run/supervisord.pid -childlogdir=/var/log/supervisor - -[unix_http_server] -file=/var/run/supervisor.sock -chmod=0700 - -[supervisorctl] -serverurl=unix:///var/run/supervisor.sock - -[rpcinterface:supervisor] -supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface - -[program:nginx] -command=/usr/sbin/nginx -g "daemon off;" -autostart=true -autorestart=true -stderr_logfile=/var/log/supervisor/nginx.err.log -stdout_logfile=/var/log/supervisor/nginx.out.log -user=root - -[program:docker-compose] -command=/app/scripts/startup.sh -directory=/app -autostart=true -autorestart=true -stderr_logfile=/var/log/supervisor/docker-compose.err.log -stdout_logfile=/var/log/supervisor/docker-compose.out.log -user=appuser -environment=HOME="/app" - -[program:cron] -command=/usr/sbin/cron -f -autostart=true -autorestart=true -stderr_logfile=/var/log/supervisor/cron.err.log -stdout_logfile=/var/log/supervisor/cron.out.log -user=root - -[program:logrotate] -command=/usr/sbin/logrotate /etc/logrotate.d/lecoffre -autostart=true -autorestart=false -startsecs=0 -exitcodes=0 -user=root - diff --git a/confs/tor/torrc b/confs/tor/torrc deleted file mode 100644 index 91699d0..0000000 --- a/confs/tor/torrc +++ /dev/null @@ -1,21 +0,0 @@ -# Configuration Tor pour LeCoffre Node -# Écoute sur 127.0.0.1 pour la sécurité - -# Port SOCKS pour les connexions sortantes -SOCKSPort 127.0.0.1:9050 - -# Port de contrôle (désactivé pour la sécurité) -# ControlPort 127.0.0.1:9050 - -# Configuration de base -Log notice file /home/debian/4NK_env/logs/tor/tor.log -DataDirectory /home/debian/4NK_env/data/tor - -# Configuration réseau -ClientOnly 1 -SafeLogging 1 -WarnUnsafeSocks 1 - -# Désactiver les services cachés -HiddenServiceDir /home/debian/4NK_env/data/tor/hidden_service/ -HiddenServicePort 80 127.0.0.1:80 diff --git a/docs/CERTIFICATOR_SPECIFICATION.md b/docs/CERTIFICATOR_SPECIFICATION.md new file mode 100644 index 0000000..3228e0b --- /dev/null +++ b/docs/CERTIFICATOR_SPECIFICATION.md @@ -0,0 +1,1140 @@ +# Spécification du Service 4NK Certificator + +**Version:** 1.0 +**Date:** 1 octobre 2025 +**Auteur:** Système 4NK + +## Table des matières + +1. [Vue d'ensemble](#vue-densemble) +2. [Objectifs et cas d'usage](#objectifs-et-cas-dusage) +3. [Architecture technique](#architecture-technique) +4. [Protocole d'ancrage](#protocole-dancrage) +5. [Modèle de données](#modèle-de-données) +6. [API et interfaces](#api-et-interfaces) +7. [Sécurité et validation](#sécurité-et-validation) +8. [Déploiement et configuration](#déploiement-et-configuration) +9. [Roadmap et évolutions](#roadmap-et-évolutions) + +--- + +## 1. Vue d'ensemble + +### 1.1 Définition + +Le **Certificator** est un service d'ancrage cryptographique qui enregistre périodiquement sur le mainnet Bitcoin l'état des échanges de données transitant par les relais 4NK. Il fournit une preuve vérifiable et immuable du volume de données échangées, avec un système de paiement conditionnel pour activer l'ancrage. + +### 1.2 Principes fondamentaux + +- **Ancrage périodique** : Enregistrement mensuel (en nombre de blocs Bitcoin) de l'empreinte des données +- **Paiement conditionnel** : Ancrage activé uniquement si paiement détecté +- **Immutabilité** : Utilisation du mainnet Bitcoin comme registre de vérité +- **Transparence** : Vérification publique des ancrages via la blockchain +- **Intégrité** : Hash cryptographique de l'état du processus + +### 1.3 Composants principaux + +``` +┌────────────────────────────────────────────────────────────┐ +│ Écosystème 4NK │ +│ ┌──────────────┐ ┌──────────────────┐ ┌──────────────┐ │ +│ │ sdk_relay │───►│ 4NK Certificator │───►│Bitcoin Mainnet│ +│ │ (messages) │ │ (ancrage) │ │ (OP_RETURN) │ +│ └──────────────┘ └──────┬───────┘ └──────────────┘ │ +│ │ │ +│ ┌──────▼───────┐ │ +│ │ Process DB │ │ +│ │ (metrics + │ │ +│ │ anchors) │ │ +│ └──────────────┘ │ +└────────────────────────────────────────────────────────────┘ +``` + +--- + +## 2. Objectifs et cas d'usage + +### 2.1 Objectifs principaux + +1. **Traçabilité** : Enregistrer l'historique des volumes échangés +2. **Auditabilité** : Permettre la vérification indépendante des métriques +3. **Monétisation** : Système de paiement pour services premium (ancrage garanti) +4. **Non-répudiation** : Preuve cryptographique de l'activité réseau +5. **Conformité** : Support pour audits réglementaires + +### 2.2 Cas d'usage + +#### Cas 1 : Facturation basée sur l'usage +``` +Scénario: +- Un processus collaboratif échange 1 TB de données via sdk_relay +- Le champ "price: { priceMoSats: 100, btcAddress: bc1q... }" est défini +- L'utilisateur paie 100 sats pour 1 GB (100,000 sats total) +- Le Certificator ancre mensuellement les métriques sur Bitcoin +- L'auditeur vérifie les ancrages pour valider la facture +``` + +#### Cas 2 : Preuve de conformité réglementaire +``` +Scénario: +- Une organisation doit prouver le volume de données traitées +- Le Certificator génère des ancrages mensuels automatiques +- Les auditeurs vérifient les transactions Bitcoin correspondantes +- Les métriques sont immuables et vérifiables publiquement +``` + +#### Cas 3 : SLA et garanties de service +``` +Scénario: +- Un fournisseur garantit un uptime et un volume minimal +- Le Certificator enregistre les métriques réelles +- En cas de litige, les ancrages Bitcoin font foi +- Calcul automatique des pénalités si SLA non respecté +``` + +### 2.3 Bénéfices + +- **Confiance** : Ancrage sur Bitcoin = immutabilité garantie +- **Transparence** : Métriques vérifiables par tous +- **Automatisation** : Réduction des processus manuels de facturation +- **Réduction des litiges** : Preuve cryptographique irréfutable + +--- + +## 3. Architecture technique + +### 3.1 Architecture globale + +``` +┌─────────────────────────────────────────────────────────────┐ +│ CERTIFICATOR SERVICE │ +├─────────────────────────────────────────────────────────────┤ +│ │ +│ ┌───────────────────────────────────────────────────────┐ │ +│ │ Data Collection Layer │ │ +│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ +│ │ │ Relay │ │ Process │ │ Payment │ │ │ +│ │ │ Monitor │ │ Scanner │ │ Watcher │ │ │ +│ │ └────────────┘ └────────────┘ └────────────┘ │ │ +│ └───────────────────────┬───────────────────────────────┘ │ +│ │ │ +│ ┌───────────────────────▼───────────────────────────────┐ │ +│ │ Aggregation & Metrics Engine │ │ +│ │ ┌───────────────┐ ┌───────────────┐ │ │ +│ │ │ Volume │ │ State │ │ │ +│ │ │ Calculator │ │ Hasher │ │ │ +│ │ └───────────────┘ └───────────────┘ │ │ +│ └───────────────────────┬───────────────────────────────┘ │ +│ │ │ +│ ┌───────────────────────▼───────────────────────────────┐ │ +│ │ Anchoring Decision Engine │ │ +│ │ ┌─────────────────────────────────────────┐ │ │ +│ │ │ IF price.btcAddress credited >= priceMoSats THEN │ │ +│ │ │ anchor_on_mainnet() │ │ +│ │ └─────────────────────────────────────────┘ │ │ +│ └───────────────────────┬───────────────────────────────┘ │ +│ │ │ +│ ┌───────────────────────▼───────────────────────────────┐ │ +│ │ Bitcoin Mainnet Interface │ │ +│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ +│ │ │ TX Builder │ │ OP_RETURN │ │ Broadcast │ │ │ +│ │ │ │ │ Encoder │ │ Manager │ │ │ +│ │ └────────────┘ └────────────┘ └────────────┘ │ │ +│ └─────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────────────────────────────────┐ │ +│ │ Storage & Indexing Layer │ │ +│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ +│ │ │ Metrics DB │ │ Anchor DB │ │ Audit Log │ │ │ +│ │ └────────────┘ └────────────┘ └────────────┘ │ │ +│ └─────────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────┘ + +┌─────────────────────────────────────────────────────────────┐ +│ External Interfaces │ +│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ +│ │ REST API │ │ WebSocket │ │ Bitcoin RPC│ │ +│ └────────────┘ └────────────┘ └────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +### 3.2 Technologies + +- **Runtime** : Rust (performance, sécurité, compatibilité sdk_relay) +- **Database** : PostgreSQL (métriques, ancrages) + Redis (cache) +- **Bitcoin** : bitcoincore-rpc + BDK (Bitcoin Dev Kit) +- **Monitoring** : Prometheus + Grafana +- **API** : Actix-web (REST) + Tokio-tungstenite (WebSocket) + +### 3.3 Modules principaux + +#### Module 1: Relay Monitor +```rust +// Écoute les messages transitant par sdk_relay +pub struct RelayMonitor { + relay_connection: WebSocket, + process_registry: Arc, +} + +impl RelayMonitor { + // Capture les messages Commit, NewTx, Cipher + pub async fn monitor_messages(&mut self) -> Result<()>; + + // Incrémente les compteurs de volume par processus + pub fn record_data_volume(&self, process_id: OutPoint, bytes: u64) -> Result<()>; +} +``` + +#### Module 2: Process Scanner +```rust +// Analyse les ProcessState pour détecter le champ "price" +pub struct ProcessScanner { + sdk_relay_api: RelayClient, +} + +impl ProcessScanner { + // Récupère tous les processus depuis le relay + pub async fn scan_all_processes(&self) -> Result>; + + // Extrait le champ price.priceMoSats et price.btcAddress + pub fn extract_price_config(&self, process: &Process) -> Option; +} +``` + +#### Module 3: Payment Watcher +```rust +// Surveille les paiements Bitcoin sur les adresses configurées +pub struct PaymentWatcher { + bitcoin_rpc: Client, + watched_addresses: HashMap, +} + +impl PaymentWatcher { + // Écoute les nouvelles transactions + pub async fn watch_payments(&mut self) -> Result<()>; + + // Vérifie si un paiement >= priceMoSats est arrivé + pub fn check_payment_received(&self, addr: &Address, required: u64) -> Result; +} +``` + +#### Module 4: Anchor Engine +```rust +// Gère les ancrages périodiques sur Bitcoin mainnet +pub struct AnchorEngine { + bitcoin_wallet: Wallet, + anchor_interval: u32, // Blocs +} + +impl AnchorEngine { + // Calcule le hash d'état du processus + pub fn compute_process_state_hash(&self, process: &Process, metrics: &Metrics) -> [u8; 32]; + + // Crée une transaction OP_RETURN avec le hash + pub fn create_anchor_tx(&self, hash: [u8; 32]) -> Result; + + // Broadcast sur le mainnet + pub async fn broadcast_anchor(&self, tx: Transaction) -> Result; +} +``` + +### 3.4 Flux de données + +#### Flux 1 : Enregistrement des métriques +``` +┌──────────────┐ +│ sdk_relay │ +│ (WebSocket) │ +└──────┬───────┘ + │ Messages: Commit, Cipher, NewTx + ▼ +┌──────────────────┐ +│ RelayMonitor │ +│ - Capture msgs │ +│ - Extrait size │ +└──────┬───────────┘ + │ volume_bytes + ▼ +┌──────────────────┐ +│ Metrics DB │ +│ process_id │ +│ timestamp │ +│ bytes_sent │ +│ bytes_received │ +└──────────────────┘ +``` + +#### Flux 2 : Détection de paiement +``` +┌──────────────────┐ +│ Bitcoin Mainnet │ +│ (mempool + blocs)│ +└──────┬───────────┘ + │ ZMQ: rawtx + ▼ +┌──────────────────────┐ +│ PaymentWatcher │ +│ - Filter addr │ +│ - Check amount │ +└──────┬───────────────┘ + │ payment_confirmed + ▼ +┌──────────────────────┐ +│ Process DB │ +│ UPDATE │ +│ payment_status = │ +│ 'PAID' │ +└──────────────────────┘ +``` + +#### Flux 3 : Ancrage périodique +``` +┌──────────────────┐ +│ Scheduler │ +│ (cron: monthly) │ +└──────┬───────────┘ + │ trigger: block_height % ANCHOR_INTERVAL == 0 + ▼ +┌───────────────────────────┐ +│ AnchorEngine │ +│ FOR EACH process: │ +│ IF payment_status=PAID: │ +│ compute_hash() │ +│ create_anchor_tx() │ +│ broadcast() │ +└──────┬────────────────────┘ + │ OP_RETURN tx + ▼ +┌──────────────────┐ +│ Bitcoin Mainnet │ +│ Block N │ +│ TX: OP_RETURN │ +│ 0x4E4B... (hash) │ +└──────────────────┘ +``` + +--- + +## 4. Protocole d'ancrage + +### 4.1 Période d'ancrage + +**Définition** : L'ancrage se produit tous les `ANCHOR_INTERVAL` blocs Bitcoin. + +```rust +// Configuration +const ANCHOR_INTERVAL_BLOCKS: u32 = 4320; // ~30 jours (144 blocs/jour) + +// Détection du moment d'ancrage +fn should_anchor(current_block: u32, last_anchor_block: u32) -> bool { + (current_block - last_anchor_block) >= ANCHOR_INTERVAL_BLOCKS +} +``` + +**Variantes configurables** : +- **Hebdomadaire** : 1008 blocs (~7 jours) +- **Mensuel** : 4320 blocs (~30 jours) +- **Trimestriel** : 12960 blocs (~90 jours) + +### 4.2 Calcul de l'empreinte + +L'empreinte (hash) inclut : + +```rust +pub struct ProcessStateSnapshot { + pub process_id: OutPoint, + pub period_start_block: u32, + pub period_end_block: u32, + pub total_bytes_sent: u64, + pub total_bytes_received: u64, + pub message_count: u64, + pub participants: Vec, // Adresses Silent Payment + pub state_merkle_root: [u8; 32], // Dernier state_id du Process +} + +impl ProcessStateSnapshot { + pub fn compute_anchor_hash(&self) -> [u8; 32] { + let mut hasher = Sha256::new(); + hasher.update(&self.process_id.txid.to_byte_array()); + hasher.update(&self.process_id.vout.to_le_bytes()); + hasher.update(&self.period_start_block.to_le_bytes()); + hasher.update(&self.period_end_block.to_le_bytes()); + hasher.update(&self.total_bytes_sent.to_le_bytes()); + hasher.update(&self.total_bytes_received.to_le_bytes()); + hasher.update(&self.message_count.to_le_bytes()); + hasher.update(&self.state_merkle_root); + + // Ajout d'un tag pour éviter les collisions + let tag = b"4NK-CERTIFICATOR-V1"; + hasher.update(tag); + + hasher.finalize().into() + } +} +``` + +### 4.3 Condition de paiement + +**Règle** : Un ancrage sur le mainnet se produit **SI ET SEULEMENT SI** : + +```rust +pub struct PriceConfig { + pub price_mo_sats: u64, // Prix en sats par MB + pub btc_address: Address, +} + +impl PriceConfig { + pub fn check_payment_condition( + &self, + total_mb: u64, + paid_amount: u64, + ) -> bool { + let required = self.price_mo_sats * total_mb; + paid_amount >= required + } +} +``` + +**Exemple** : +```json +{ + "price": { + "priceMoSats": 100, + "btcAddress": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh" + } +} +``` + +- Volume échangé : 500 MB +- Montant requis : `100 × 500 = 50,000 sats` +- Si `bc1qxy2...` reçoit ≥ 50,000 sats → **Ancrage activé** +- Sinon → Métriques enregistrées localement uniquement + +### 4.4 Format OP_RETURN + +**Structure** : + +``` +┌─────────────────────────────────────────────────┐ +│ OP_RETURN │ +├─────────────────────────────────────────────────┤ +│ 0x6a (OP_RETURN opcode) │ +│ 0x24 (Push 36 bytes) │ +│ 0x4E 0x4B 0x41 0x31 ("NKA1" = 4NK Anchor v1) │ +│ [32 bytes] (anchor_hash) │ +└─────────────────────────────────────────────────┘ +Total: 38 bytes +``` + +**Code Rust** : + +```rust +pub fn create_op_return_anchor(hash: [u8; 32]) -> ScriptBuf { + let mut data = Vec::new(); + data.extend_from_slice(b"NKA1"); // Protocol identifier + data.extend_from_slice(&hash); + + ScriptBuf::new_op_return(&data) +} +``` + +### 4.5 Vérification d'ancrage + +**Processus de vérification** : + +1. **Récupérer la transaction** : + ```bash + bitcoin-cli getrawtransaction true + ``` + +2. **Extraire l'OP_RETURN** : + ```rust + pub fn extract_anchor_from_tx(tx: &Transaction) -> Option<[u8; 32]> { + for output in &tx.output { + if output.script_pubkey.is_op_return() { + let data = &output.script_pubkey.as_bytes()[2..]; // Skip 0x6a + push + if data.len() == 36 && &data[0..4] == b"NKA1" { + return Some(data[4..36].try_into().ok()?); + } + } + } + None + } + ``` + +3. **Recalculer le hash local** : + ```rust + let snapshot = get_snapshot_for_period(process_id, period)?; + let expected_hash = snapshot.compute_anchor_hash(); + ``` + +4. **Comparer** : + ```rust + if extracted_hash == expected_hash { + println!("✅ Ancrage vérifié"); + } else { + println!("❌ Hash invalide"); + } + ``` + +--- + +## 5. Modèle de données + +### 5.1 Schéma de base de données + +#### Table: `processes` +```sql +CREATE TABLE processes ( + process_id TEXT PRIMARY KEY, -- OutPoint format "txid:vout" + created_at TIMESTAMP NOT NULL, + last_updated TIMESTAMP NOT NULL, + price_mo_sats BIGINT, -- NULL si pas de pricing + btc_address TEXT, -- NULL si pas de pricing + payment_status TEXT DEFAULT 'UNPAID', -- UNPAID, PENDING, PAID + total_paid_sats BIGINT DEFAULT 0, + state_merkle_root BYTEA -- Dernier state_id connu +); + +CREATE INDEX idx_processes_payment ON processes(payment_status); +CREATE INDEX idx_processes_address ON processes(btc_address); +``` + +#### Table: `metrics` +```sql +CREATE TABLE metrics ( + id SERIAL PRIMARY KEY, + process_id TEXT REFERENCES processes(process_id), + timestamp TIMESTAMP NOT NULL, + block_height INTEGER NOT NULL, + bytes_sent BIGINT NOT NULL DEFAULT 0, + bytes_received BIGINT NOT NULL DEFAULT 0, + message_count INTEGER NOT NULL DEFAULT 0 +); + +CREATE INDEX idx_metrics_process_time ON metrics(process_id, timestamp); +CREATE INDEX idx_metrics_block ON metrics(block_height); +``` + +#### Table: `anchors` +```sql +CREATE TABLE anchors ( + id SERIAL PRIMARY KEY, + process_id TEXT REFERENCES processes(process_id), + anchor_hash BYTEA NOT NULL, -- 32 bytes + period_start_block INTEGER NOT NULL, + period_end_block INTEGER NOT NULL, + total_mb BIGINT NOT NULL, + anchor_txid TEXT, -- Bitcoin mainnet txid + anchor_block INTEGER, -- Block confirmé + created_at TIMESTAMP NOT NULL, + status TEXT DEFAULT 'PENDING' -- PENDING, BROADCASTED, CONFIRMED +); + +CREATE INDEX idx_anchors_process ON anchors(process_id); +CREATE INDEX idx_anchors_txid ON anchors(anchor_txid); +CREATE INDEX idx_anchors_period ON anchors(period_start_block, period_end_block); +``` + +#### Table: `payments` +```sql +CREATE TABLE payments ( + id SERIAL PRIMARY KEY, + process_id TEXT REFERENCES processes(process_id), + txid TEXT NOT NULL, + vout INTEGER NOT NULL, + amount_sats BIGINT NOT NULL, + received_at TIMESTAMP NOT NULL, + block_height INTEGER, + confirmations INTEGER DEFAULT 0 +); + +CREATE INDEX idx_payments_process ON payments(process_id); +CREATE INDEX idx_payments_txid ON payments(txid); +``` + +### 5.2 Modèles Rust + +```rust +use serde::{Deserialize, Serialize}; +use bitcoin::{OutPoint, Address, Txid}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Process { + pub process_id: OutPoint, + pub created_at: i64, + pub last_updated: i64, + pub price_config: Option, + pub payment_status: PaymentStatus, + pub total_paid_sats: u64, + pub state_merkle_root: [u8; 32], +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PriceConfig { + pub price_mo_sats: u64, + pub btc_address: Address, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum PaymentStatus { + Unpaid, + Pending, // Paiement vu en mempool + Paid, // Paiement confirmé +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Metric { + pub id: Option, + pub process_id: OutPoint, + pub timestamp: i64, + pub block_height: u32, + pub bytes_sent: u64, + pub bytes_received: u64, + pub message_count: u32, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Anchor { + pub id: Option, + pub process_id: OutPoint, + pub anchor_hash: [u8; 32], + pub period_start_block: u32, + pub period_end_block: u32, + pub total_mb: u64, + pub anchor_txid: Option, + pub anchor_block: Option, + pub created_at: i64, + pub status: AnchorStatus, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub enum AnchorStatus { + Pending, // En attente de création de tx + Broadcasted, // Tx envoyée au réseau + Confirmed, // Tx confirmée dans un bloc + Failed, // Échec de broadcast +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Payment { + pub id: Option, + pub process_id: OutPoint, + pub txid: Txid, + pub vout: u32, + pub amount_sats: u64, + pub received_at: i64, + pub block_height: Option, + pub confirmations: u32, +} +``` + +--- + +## 6. API et interfaces + +### 6.1 REST API + +#### Endpoint: `GET /api/v1/processes` +**Description** : Liste tous les processus surveillés + +**Réponse** : +```json +{ + "processes": [ + { + "process_id": "abc123:0", + "created_at": 1696118400, + "price_config": { + "price_mo_sats": 100, + "btc_address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh" + }, + "payment_status": "PAID", + "total_paid_sats": 50000, + "total_mb_exchanged": 500 + } + ] +} +``` + +#### Endpoint: `GET /api/v1/processes/:process_id/metrics` +**Description** : Métriques pour un processus donné + +**Paramètres de requête** : +- `start_block` (optionnel) : Bloc de début +- `end_block` (optionnel) : Bloc de fin + +**Réponse** : +```json +{ + "process_id": "abc123:0", + "period": { + "start_block": 800000, + "end_block": 804320 + }, + "metrics": { + "total_bytes_sent": 524288000, + "total_bytes_received": 104857600, + "total_mb": 600, + "message_count": 1250 + } +} +``` + +#### Endpoint: `GET /api/v1/processes/:process_id/anchors` +**Description** : Liste des ancrages pour un processus + +**Réponse** : +```json +{ + "process_id": "abc123:0", + "anchors": [ + { + "anchor_hash": "a3f5e8b9c2d1...", + "period_start_block": 800000, + "period_end_block": 804320, + "total_mb": 600, + "anchor_txid": "def456...", + "anchor_block": 804325, + "status": "CONFIRMED", + "explorer_url": "https://mempool.space/tx/def456..." + } + ] +} +``` + +#### Endpoint: `POST /api/v1/anchors/verify` +**Description** : Vérifie un ancrage + +**Corps de la requête** : +```json +{ + "anchor_hash": "a3f5e8b9c2d1...", + "txid": "def456..." +} +``` + +**Réponse** : +```json +{ + "valid": true, + "details": { + "tx_found": true, + "hash_matches": true, + "confirmations": 6, + "block_height": 804325 + } +} +``` + +#### Endpoint: `GET /api/v1/payments/:address` +**Description** : Historique des paiements pour une adresse + +**Réponse** : +```json +{ + "address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", + "total_received_sats": 50000, + "payments": [ + { + "txid": "ghi789...", + "vout": 0, + "amount_sats": 50000, + "received_at": 1696118400, + "confirmations": 12 + } + ] +} +``` + +### 6.2 WebSocket API + +**Connexion** : `ws://certificator:8082/ws` + +#### Event: `anchor_created` +```json +{ + "type": "anchor_created", + "data": { + "process_id": "abc123:0", + "anchor_hash": "a3f5e8b9c2d1...", + "period_end_block": 804320, + "total_mb": 600 + } +} +``` + +#### Event: `anchor_broadcasted` +```json +{ + "type": "anchor_broadcasted", + "data": { + "process_id": "abc123:0", + "anchor_hash": "a3f5e8b9c2d1...", + "txid": "def456...", + "status": "BROADCASTED" + } +} +``` + +#### Event: `anchor_confirmed` +```json +{ + "type": "anchor_confirmed", + "data": { + "process_id": "abc123:0", + "anchor_hash": "a3f5e8b9c2d1...", + "txid": "def456...", + "block_height": 804325, + "confirmations": 6 + } +} +``` + +#### Event: `payment_detected` +```json +{ + "type": "payment_detected", + "data": { + "process_id": "abc123:0", + "address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh", + "amount_sats": 50000, + "txid": "ghi789...", + "status": "PENDING" + } +} +``` + +### 6.3 CLI + +```bash +# Lister les processus +certificator-cli processes list + +# Afficher les métriques d'un processus +certificator-cli metrics get --process-id abc123:0 --period 30d + +# Forcer un ancrage manuel +certificator-cli anchor create --process-id abc123:0 + +# Vérifier un ancrage +certificator-cli anchor verify --txid def456... + +# Surveiller une adresse de paiement +certificator-cli payments watch --address bc1q... +``` + +--- + +## 7. Sécurité et validation + +### 7.1 Authentification + +**Mécanisme** : JWT (JSON Web Tokens) pour l'API REST + +```rust +// Génération d'un token +pub fn generate_jwt(user_sp_address: &str) -> Result { + let claims = Claims { + sub: user_sp_address.to_string(), + exp: (Utc::now() + Duration::hours(24)).timestamp(), + }; + encode(&Header::default(), &claims, &ENCODING_KEY) +} + +// Middleware de vérification +pub async fn verify_jwt(token: &str) -> Result { + decode::(token, &DECODING_KEY, &Validation::default()) + .map(|data| data.claims) +} +``` + +### 7.2 Autorisations + +**Règles** : +- **Lecture publique** : Métriques et ancrages lisibles par tous +- **Écriture restreinte** : Seuls les membres du processus peuvent déclencher un ancrage manuel +- **Admin** : Contrôle de la configuration (ANCHOR_INTERVAL, frais de transaction) + +### 7.3 Validation des données + +```rust +impl PriceConfig { + pub fn validate(&self) -> Result<()> { + // Prix non nul + if self.price_mo_sats == 0 { + return Err(anyhow!("price_mo_sats must be > 0")); + } + + // Adresse Bitcoin valide + if self.btc_address.network != Network::Bitcoin { + return Err(anyhow!("Only mainnet addresses allowed")); + } + + // Prix raisonnable (< 1000 sats/MB) + if self.price_mo_sats > 1000 { + return Err(anyhow!("price_mo_sats too high (max 1000)")); + } + + Ok(()) + } +} +``` + +### 7.4 Protection contre les attaques + +#### Attaque : Manipulation des métriques +**Mitigation** : +- Hash cryptographique inclut tous les champs +- Signatures des messages relay vérifiées +- Logs immuables (append-only) + +#### Attaque : Spam d'ancrages +**Mitigation** : +- Rate limiting : 1 ancrage par processus par période +- Coût en frais Bitcoin (dissuasif) +- Filtrage : seuls les processus avec paiement validé + +#### Attaque : Faux paiement +**Mitigation** : +- Vérification on-chain (Bitcoin RPC) +- Attente de 6 confirmations minimum +- Surveillance du montant exact (>= prix requis) + +--- + +## 8. Déploiement et configuration + +### 8.1 Configuration + +**Fichier** : `certificator.toml` + +```toml +[server] +host = "0.0.0.0" +port = 8082 +log_level = "info" + +[bitcoin] +network = "mainnet" +rpc_url = "http://localhost:8332" +rpc_user = "bitcoin" +rpc_password = "your_password" +wallet_name = "certificator_wallet" +min_confirmations = 6 + +[relay] +websocket_url = "ws://sdk_relay:8090" +monitor_interval_secs = 60 + +[anchoring] +interval_blocks = 4320 # ~30 jours +auto_anchor = true +tx_fee_sat_per_vbyte = 10 + +[database] +url = "postgresql://certificator:password@localhost/certificator_db" +max_connections = 10 + +[redis] +url = "redis://localhost:6379" +cache_ttl_secs = 3600 + +[api] +jwt_secret = "your_secret_key_here" +cors_allowed_origins = ["https://dev4.4nkweb.com"] +``` + +### 8.2 Docker Compose + +**Fichier** : `docker-compose.certificator.yml` + +```yaml +version: '3.8' + +services: + certificator: + build: + context: ./certificator + dockerfile: Dockerfile + container_name: certificator + env_file: + - /home/debian/4NK_env/confs/certificator/.env + ports: + - "0.0.0.0:8082:8082" + volumes: + - /home/debian/4NK_env/confs/certificator/certificator.toml:/app/config.toml:ro + - certificator_data:/app/data + - /home/debian/4NK_env/logs/certificator:/var/log/certificator + networks: + - btcnet + depends_on: + - certificator_db + - redis + - bitcoin-signet # À remplacer par mainnet en prod + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8082/health"] + interval: 30s + timeout: 10s + retries: 3 + restart: unless-stopped + + certificator_db: + image: postgres:15-alpine + container_name: certificator_db + environment: + POSTGRES_DB: certificator_db + POSTGRES_USER: certificator + POSTGRES_PASSWORD: secure_password_here + volumes: + - certificator_pgdata:/var/lib/postgresql/data + networks: + - btcnet + restart: unless-stopped + + redis: + image: redis:7-alpine + container_name: certificator_redis + volumes: + - certificator_redis:/data + networks: + - btcnet + restart: unless-stopped + +volumes: + certificator_data: + name: certificator_data + certificator_pgdata: + name: certificator_pgdata + certificator_redis: + name: certificator_redis + +networks: + btcnet: + external: true + name: 4nk_node_btcnet +``` + +### 8.3 Déploiement + +**Étapes** : + +1. **Cloner le repository** : + ```bash + cd /home/debian/4NK_env + git clone https://git.4nkweb.com/4nk/4NK_certificator.git + ``` + +2. **Configuration** : + ```bash + mkdir -p confs/4nk_certificator + cp 4NK_certificator/config/certificator.toml.example confs/4nk_certificator/certificator.toml + nano confs/4nk_certificator/certificator.toml # Éditer la config + ``` + +3. **Build** : + ```bash + cd 4NK_certificator + docker build -t git.4nkweb.com/4nk/4nk_certificator:latest . + ``` + +4. **Initialiser la DB** : + ```bash + docker compose -f docker-compose.certificator.yml up -d certificator_db + docker exec -it 4nk_certificator_db psql -U certificator -d certificator_db -f /app/schema.sql + ``` + +5. **Lancement** : + ```bash + docker compose -f docker-compose.certificator.yml up -d + ``` + +6. **Vérification** : + ```bash + curl http://localhost:8082/health + docker logs -f 4nk_certificator + ``` + +### 8.4 Monitoring + +**Prometheus metrics** : `http://4nk_certificator:8082/metrics` + +``` +# HELP 4nk_certificator_processes_total Total number of monitored processes +# TYPE 4nk_certificator_processes_total gauge +4nk_certificator_processes_total 42 + +# HELP 4nk_certificator_anchors_created_total Total anchors created +# TYPE 4nk_certificator_anchors_created_total counter +4nk_certificator_anchors_created_total 120 + +# HELP 4nk_certificator_anchors_confirmed_total Total anchors confirmed on-chain +# TYPE 4nk_certificator_anchors_confirmed_total counter +4nk_certificator_anchors_confirmed_total 118 + +# HELP 4nk_certificator_data_volume_bytes Total data volume monitored +# TYPE 4nk_certificator_data_volume_bytes counter +4nk_certificator_data_volume_bytes 5242880000 +``` + +**Grafana Dashboard** : +- Volume de données par processus (graphique temporel) +- Taux d'ancrages confirmés (%) +- Paiements reçus vs requis +- Latence de broadcast des transactions + +--- + +## 9. Roadmap et évolutions + +### 9.1 Phase 1 : MVP (Q4 2025) + +- [x] Spécification complète +- [ ] Implémentation Rust du service de base +- [ ] Monitoring des messages relay +- [ ] Calcul des métriques +- [ ] Ancrage sur Bitcoin Testnet +- [ ] API REST de base + +### 9.2 Phase 2 : Production (Q1 2026) + +- [ ] Ancrage sur Bitcoin Mainnet +- [ ] Surveillance des paiements +- [ ] WebSocket pour events en temps réel +- [ ] Dashboard Grafana dédié +- [ ] Tests de charge et optimisation + +### 9.3 Phase 3 : Avancé (Q2 2026) + +- [ ] Support multi-relais (agrégation de métriques) +- [ ] Preuve Merkle pour sous-ensembles de données +- [ ] Export PDF de certificats d'ancrage +- [ ] API de vérification tierce (pour auditeurs) +- [ ] Intégration Lightning Network (paiements instantanés) + +### 9.4 Phase 4 : Écosystème (Q3-Q4 2026) + +- [ ] Marketplace de services d'ancrage +- [ ] SLA dynamiques avec pénalités automatiques +- [ ] Oracles de données (prix, taux de change) +- [ ] Intégration avec services de facturation (Stripe, etc.) +- [ ] Support de multiples blockchains (Ethereum, Liquid) + +--- + +## Conclusion + +Le **Certificator** apporte une couche de confiance et de traçabilité essentielle à l'écosystème 4NK. En ancrant périodiquement les métriques de données sur le mainnet Bitcoin, il garantit : + +- **Immutabilité** : Les données ne peuvent être modifiées rétroactivement +- **Transparence** : Vérification publique des ancrages +- **Monétisation** : Modèle économique basé sur l'usage réel +- **Auditabilité** : Preuves cryptographiques pour conformité réglementaire + +L'intégration avec le système de processus 4NK (Silent Payments, validation multi-signatures, relais décentralisés) crée un écosystème cohérent et innovant pour les applications collaboratives décentralisées. + +--- + +**Document généré le 1 octobre 2025** +**Version 1.0 - Spécification initiale** diff --git a/docs/VARIABLES-ENVIRONNEMENT-NOUVELLE-STRUCTURE.md b/docs/VARIABLES-ENVIRONNEMENT-NOUVELLE-STRUCTURE.md index ac31091..ae93a3d 100644 --- a/docs/VARIABLES-ENVIRONNEMENT-NOUVELLE-STRUCTURE.md +++ b/docs/VARIABLES-ENVIRONNEMENT-NOUVELLE-STRUCTURE.md @@ -189,3 +189,5 @@ Les scripts ont été mis à jour pour utiliser la nouvelle structure : + + diff --git a/lecoffre-front b/lecoffre-front deleted file mode 160000 index 041ff5e..0000000 --- a/lecoffre-front +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 041ff5e98f1236b4e5189f878e957274b383c3e7 diff --git a/lecoffre_node b/lecoffre_node deleted file mode 160000 index 67a1a48..0000000 --- a/lecoffre_node +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 67a1a48fb63cb4d35d61489cf3c341a27a3c94fb diff --git a/projects/lecoffre/lecoffre-front b/projects/lecoffre/lecoffre-front new file mode 160000 index 0000000..0bed1ce --- /dev/null +++ b/projects/lecoffre/lecoffre-front @@ -0,0 +1 @@ +Subproject commit 0bed1cecc91505adb5e30bde48e5ff189b078731 diff --git a/projects/lecoffre/lecoffre_node b/projects/lecoffre/lecoffre_node new file mode 160000 index 0000000..35a209c --- /dev/null +++ b/projects/lecoffre/lecoffre_node @@ -0,0 +1 @@ +Subproject commit 35a209ce8b9109830b4b24e89285f25c0320b9af diff --git a/scripts/lecoffre_node/blindbit-maintenance.sh b/scripts/lecoffre_node/blindbit-maintenance.sh index e4f1dcb..feca937 100755 --- a/scripts/lecoffre_node/blindbit-maintenance.sh +++ b/scripts/lecoffre_node/blindbit-maintenance.sh @@ -229,3 +229,5 @@ done + + diff --git a/scripts/lecoffre_node/collect-blindbit-logs.sh b/scripts/lecoffre_node/collect-blindbit-logs.sh index bf3a050..8c33863 100755 --- a/scripts/lecoffre_node/collect-blindbit-logs.sh +++ b/scripts/lecoffre_node/collect-blindbit-logs.sh @@ -112,3 +112,5 @@ echo "Test API: api_test_${TIMESTAMP}.txt" + + diff --git a/scripts/lecoffre_node/quick-health-check.sh b/scripts/lecoffre_node/quick-health-check.sh index dc0b406..3a23822 100755 --- a/scripts/lecoffre_node/quick-health-check.sh +++ b/scripts/lecoffre_node/quick-health-check.sh @@ -90,3 +90,5 @@ echo -e "${CYAN}========================================${NC}" + + diff --git a/scripts/lecoffre_node/wait-bitcoin-ready.sh b/scripts/lecoffre_node/wait-bitcoin-ready.sh index a1f27dc..7ef8fce 100755 --- a/scripts/lecoffre_node/wait-bitcoin-ready.sh +++ b/scripts/lecoffre_node/wait-bitcoin-ready.sh @@ -28,3 +28,5 @@ exit 1 + + diff --git a/scripts/lecoffre_node/wait-tor-bootstrap.sh b/scripts/lecoffre_node/wait-tor-bootstrap.sh index 8293945..23d690d 100755 --- a/scripts/lecoffre_node/wait-tor-bootstrap.sh +++ b/scripts/lecoffre_node/wait-tor-bootstrap.sh @@ -28,3 +28,5 @@ exit 1 + + diff --git a/scripts/push_modules.sh b/scripts/push_modules.sh new file mode 100644 index 0000000..666e533 --- /dev/null +++ b/scripts/push_modules.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env sh +set -euo pipefail + +# This script prepares and pushes local module sources to their Gitea remotes. +# It is idempotent and safe to re-run. + +ROOT="/home/debian/4NK_env" +MOD_ROOT="$ROOT/4NK_modules" + +GIT="/usr/bin/git" + +log() { printf "%s\n" "$*"; } + +ensure_dir() { + [ -d "$1" ] || mkdir -p "$1" +} + +copy_if_exists() { + src="$1"; dst="$2" + if [ -d "$src" ]; then + log "[copy] $src -> $dst" + ensure_dir "$dst" + # Copy all contents (including dotfiles) without nuking existing .git + (cd "$src" && tar cf - .) | (cd "$dst" && tar xpf -) + else + log "[skip] source not found: $src" + fi +} + +git_init_and_push() { + module_dir="$1" # e.g. /home/debian/4NK_env/4NK_modules/4NK_miner + remote_url="$2" # e.g. git@git.4nkweb.com:4nk/4NK_miner.git + commit_msg="$3" # commit message + + ensure_dir "$module_dir" + cd "$module_dir" + + if [ ! -d .git ]; then + $GIT init + fi + + # Configure default branch ext + $GIT checkout -B ext + + # Set remote + $GIT remote remove origin 2>/dev/null || true + $GIT remote add origin "$remote_url" + + # Stage changes + $GIT add -A + + # Commit if there are changes + if ! $GIT diff --cached --quiet; then + $GIT commit -m "$commit_msg" + else + log "[info] no changes to commit in $(basename "$module_dir")" + fi + + # Push ext + $GIT push -u origin ext +} + +main() { + # 1) Prepare module roots + ensure_dir "$MOD_ROOT/4NK_miner" + ensure_dir "$MOD_ROOT/4NK_web_status" + + # 2) Copy sources from projects if present + copy_if_exists "$ROOT/projects/lecoffre/lecoffre_node/miner" "$MOD_ROOT/4NK_miner" + copy_if_exists "$ROOT/projects/lecoffre/lecoffre_node/web" "$MOD_ROOT/4NK_web_status" + + # 3) Push 4NK_miner + git_init_and_push \ + "$MOD_ROOT/4NK_miner" \ + "git@git.4nkweb.com:4nk/4NK_miner.git" \ + "chore: initial import from lecoffre_node/miner" + + # 4) Push 4NK_web_status + git_init_and_push \ + "$MOD_ROOT/4NK_web_status" \ + "git@git.4nkweb.com:4nk/4NK_web_status.git" \ + "chore: initial import from lecoffre_node/web" + + log "[OK] Modules pushed. Optionally register as submodules in the root repo:" + log " cd $ROOT && git submodule add -f git@git.4nkweb.com:4nk/4NK_miner.git 4NK_modules/4NK_miner" + log " cd $ROOT && git submodule add -f git@git.4nkweb.com:4nk/4NK_web_status.git 4NK_modules/4NK_web_status" +} + +main "$@" diff --git a/vault b/vault deleted file mode 160000 index 4d314db..0000000 --- a/vault +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4d314db8898c66f25420824a65b7a71e4fa6e823