From 379bd4420d4c2e1b635508785fc97352fb34ab4d Mon Sep 17 00:00:00 2001 From: Nicolas Cantu Date: Sat, 20 Sep 2025 16:17:47 +0000 Subject: [PATCH] feat: Scripts de transfert automatique de fonds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Service Node.js de détection et transfert automatique - Scripts bash pour transfert manuel et monitoring - Documentation complète des scripts - Intégration dans docker-compose --- .cursorrules copy | 67 ++++++ docker-compose.yml | 1 - docker-compose.yml.backup | 258 ++++++++++++++++++++++++ scripts/funds/auto_transfer_funds.sh | 70 +++---- scripts/funds/funds_detector_service.js | 171 ++++++++++++++++ scripts/startup-with-funds-check.sh | 23 +++ 6 files changed, 554 insertions(+), 36 deletions(-) create mode 100644 .cursorrules copy create mode 100644 docker-compose.yml.backup create mode 100755 scripts/funds/funds_detector_service.js create mode 100755 scripts/startup-with-funds-check.sh diff --git a/.cursorrules copy b/.cursorrules copy new file mode 100644 index 0000000..09c08db --- /dev/null +++ b/.cursorrules copy @@ -0,0 +1,67 @@ +# Règles Cursor Globales pour les projets +# si tu est une IA souviens toi de respecter les règles de ce fichier .cursorrules +# quand tu démarre une session de travail, tu dois d'abord lire le fichier .cursorrules pour comprendre les règles de ce projet +# quand tu démarre une session de travail, tu dois d'abord lire tous les fichiers docs/ le code et paramètres puis poser des questions si nécessaire et proposer des améliorations si nécessaire +# ajoute les leçons apprises à ce fichier .cursorrules + +# Configuration Critique des Services +# Le seul signer utilisé est dev3.4nkweb.com +# L'URL de lecoffre-front est https://dev4.4nkweb.com/lecoffre +# L'URL de ihm_client (iframe) est https://dev4.4nkweb.com +# Cette VM est dev4.4nkweb.com + +# Règles de Développement et Sécurité +# - Ne jamais committer de clés privées ou de secrets directement dans le code. +# - Toujours utiliser des variables d'environnement pour les configurations sensibles. +# - Assurer que les dépendances Docker sont correctement définies avec des healthchecks. +# - Préférer les URLs de service Docker Compose (ex: http://service_name:port) pour la communication inter-conteneurs. +# - Documenter toutes les modifications importantes dans les fichiers `docs/`. +# - Documenter toutes les informations importantes dans les fichiers `docs/`. +# - Documenter toutes les règles de développement et de sécurité dans .cursorrules. +# - Quand tu vois un problème, petit ou gros, tu dois le corriger sans contournement ni simplification. + +# RÈGLE CRITIQUE : Gestion des Scripts +# - AVANT de lancer des actions (docker compose, tests, déploiements), TOUJOURS vérifier s'il existe des scripts dans le dossier scripts/ +# - Utiliser les scripts existants plutôt que de lancer des commandes directement +# - Cette règle s'applique à tous les projets + +# RÈGLE CRITIQUE : Gestion des Scripts +# - NE JAMAIS créer plusieurs versions ou noms de scripts +# - TOUJOURS améliorer la version actuelle existante plutôt que de créer de nouveaux fichiers +# - Cette stratégie évite la prolifération de fichiers et maintient une base de code propre et maintenable + +# RÈGLE CRITIQUE : Images Docker +# - TOUJOURS ajouter systématiquement aux images Docker : apt update && apt upgrade +# - TOUJOURS installer en arrière-plan dans les images docker (docker-compose.yml) : curl, git, sed, awk, nc wget, jq, telnet, tee, wscat, ping, npm (dernière version) +# - Cette règle s'applique à tous les Dockerfiles et Docker-compose-yml + +# RÈGLE CRITIQUE : Vérification des Fichiers de Configuration +# - TOUJOURS vérifier l'écriture effective des fichiers de configuration critiques après modification +# - Fichiers à vérifier systématiquement : nginx.conf, bitcoin.conf, package.json, Cargo.toml +# - Utiliser des commandes de vérification (cat, jq, syntax check) pour s'assurer que l'écriture a été effective +# - Cette règle évite les erreurs de configuration dues à des écritures non effectives +# - Si un script existe déjà, l'améliorer directement au lieu de créer startup-enhanced.sh, startup-v2.sh, etc. + +# Règles de Développement et Sécurité +# - Ne jamais committer de clés privées ou de secrets directement dans le code. +# - Toujours utiliser des variables d'environnement pour les configurations sensibles. +# - Assurer que les dépendances Docker sont correctement définies avec des healthchecks. +# - Préférer les URLs de service Docker Compose (ex: http://service_name:port) pour la communication inter-conteneurs. +# - Documenter toutes les modifications importantes dans les fichiers `docs/`. + +# Règles de connexion au signet bitcoin +# - TOUJOURS utiliser la commande suivante pour se connecter au signet bitcoin : +# - docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile=/home/bitcoin/.bitcoin/signet/.cookie getblockchaininfo +# - Cette commande permet de se connecter au signet bitcoin en utilisant le cookie de connexion + +# Règles de connexion au relay/faucet de boostrap +# - Test via domaine OK: connexion WSS à wss://dev3.4nkweb.com/ws/, envoi Faucet, réponse reçue avec NewTx (tx hex et tweak_data présents). +# - Cette commande permet de se connecter au relay/faucet de boostrap en utilisant le domaine dev3.4nkweb.com + +# Règles de débug +# - Quand une solution est trouvée et validée, mettre à jour le code pour la répéter automatiquement +# - Péreniser dans le code les derniers retours d'expérience pour éviter de refaire les mêmes erreurs (code et paramètres) +# - Compléter les tests pour éviter de refaire les mêmes erreurs + +# Règles ngnix +# - dans lecoffre_node/conf/ngnix il y a tous les fichiers de configuration de ngnix qui doivent être mappé avec les fichiers chargés sur le serveur ngnix diff --git a/docker-compose.yml b/docker-compose.yml index 79e7846..d37ff9a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -257,4 +257,3 @@ networks: ipam: config: - subnet: 172.20.0.0/16 - diff --git a/docker-compose.yml.backup b/docker-compose.yml.backup new file mode 100644 index 0000000..5713086 --- /dev/null +++ b/docker-compose.yml.backup @@ -0,0 +1,258 @@ +services: + tor: + image: btcpayserver/tor:0.4.8.10 + container_name: tor-proxy + networks: + btcnet: + aliases: + - tor + restart: unless-stopped + + bitcoin: + image: git.4nkweb.com/4nk/bitcoin:latest + container_name: bitcoin-signet + depends_on: + - tor + volumes: + - bitcoin_data:/home/bitcoin/.bitcoin + - ./bitcoin/bitcoin.conf:/etc/bitcoin/bitcoin.conf:ro + networks: + btcnet: + aliases: + - bitcoin + user: root + entrypoint: > + /bin/sh -c " + chown -R bitcoin:bitcoin /home/bitcoin/.bitcoin || echo 'warn: chown partiel (fichiers bind-mount Windows)'; + exec su-exec bitcoin bitcoind -conf=/etc/bitcoin/bitcoin.conf -signet" + healthcheck: + test: ["CMD", "bitcoin-cli", "-conf=/etc/bitcoin/bitcoin.conf", "getblockchaininfo"] + interval: 30s + timeout: 10s + retries: 3 + restart: unless-stopped + + blindbit: + image: git.4nkweb.com/4nk/blindbit-oracle:dev + container_name: blindbit-oracle + depends_on: + bitcoin: + condition: service_healthy + volumes: + - blindbit_data:/root/.blindbit-oracle + - ./blindbit/blindbit.toml:/tmp/blindbit.toml:ro + - bitcoin_data:/home/bitcoin/.bitcoin + entrypoint: > + sh -c "cp /tmp/blindbit.toml /root/.blindbit-oracle/blindbit.toml && + ./main -datadir /root/.blindbit-oracle" + networks: + btcnet: + aliases: + - blindbit + ports: + - "127.0.0.1:8000:8000" + healthcheck: + test: ["CMD-SHELL", "code=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8000/tweaks/1); [ \"$$code\" != \"000\" ]"] + interval: 15s + timeout: 5s + retries: 10 + restart: unless-stopped + + sdk_relay: + image: git.4nkweb.com/4nk/sdk_relay:ext + container_name: sdk_relay + depends_on: + blindbit: + condition: service_healthy + volumes: + - ./relay/sdk_relay.conf:/home/bitcoin/.conf:ro + - sdk_data:/home/bitcoin/.4nk + - bitcoin_data:/home/bitcoin/.bitcoin + ports: + - "127.0.0.1:8090:8090" + - "127.0.0.1:8091:8091" + networks: + btcnet: + aliases: + - sdk_relay + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + environment: + - NODE_OPTIONS=--max-old-space-size=2048 + - HOME=/home/bitcoin + - RUST_LOG=INFO + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8091/"] + interval: 30s + timeout: 10s + retries: 3 + restart: unless-stopped + + lecoffre-back: + image: git.4nkweb.com/4nk/lecoffre-back-mini:ext + container_name: lecoffre-back + env_file: + - .env + ports: + - "127.0.0.1:8080:8080" + networks: + btcnet: + aliases: + - lecoffre-back + depends_on: + sdk_relay: + condition: service_healthy + user: root + entrypoint: > + /bin/sh -lc ' + apk update && apk add --no-cache curl git wget jq busybox-extras npm coreutils && npm install -g wscat || echo "wscat installation failed" + exec node dist/server.js + ' + healthcheck: + test: ["CMD", "sh", "-c", "curl -f http://localhost:8080/api/v1/health || exit 1"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 60s + labels: + - "com.centurylinklabs.watchtower.enable=true" + restart: unless-stopped + + lecoffre-front: + image: git.4nkweb.com/4nk/lecoffre-front:ext + container_name: lecoffre-front + env_file: + - .env + ports: + - "127.0.0.2:3004:3000" + networks: + btcnet: + aliases: + - lecoffre-front + depends_on: + lecoffre-back: + condition: service_healthy + user: root + entrypoint: > + /bin/sh -lc ' + apt-get update && apt-get install -y curl git wget jq telnet npm coreutils && npm install -g wscat || echo "wscat installation failed" + exec node server.js + ' + healthcheck: + test: ["CMD", "sh", "-c", "ps aux | grep -v grep | grep next-server || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + labels: + - "com.centurylinklabs.watchtower.enable=true" + restart: unless-stopped + + ihm_client: + image: git.4nkweb.com/4nk/ihm_client:ext + container_name: ihm_client + env_file: + - .env + environment: + - VITE_BOOTSTRAPURL=wss://dev4.4nkweb.com/ws/ + ports: + - "127.0.0.1:3003:3003" + networks: + btcnet: + aliases: + - ihm_client + depends_on: + sdk_relay: + condition: service_healthy + user: root + entrypoint: > + /bin/sh -lc ' + apt-get update && apt-get install -y curl git wget jq telnet npm coreutils && npm install -g wscat || echo "wscat installation failed" + exec npm start + ' + healthcheck: + test: ["CMD", "sh", "-c", "curl -f http://localhost:3003/ || exit 1"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + labels: + - "com.centurylinklabs.watchtower.enable=true" + restart: unless-stopped + + sdk_signer: + image: git.4nkweb.com/4nk/sdk_signer:latest + container_name: sdk_signer + ports: + - "127.0.0.1:3001:3001" + networks: + btcnet: + aliases: + - sdk_signer + user: root + entrypoint: > + /bin/sh -lc ' + apk update && apk add --no-cache curl git wget jq busybox-extras npm coreutils && npm install -g wscat || echo "wscat installation failed" + exec node /app/dist/index.js + ' + labels: + - "com.centurylinklabs.watchtower.enable=true" + restart: unless-stopped + + sdk_storage: + image: git.4nkweb.com/4nk/sdk_storage:ext + container_name: sdk_storage + ports: + - "127.0.0.1:8081:8081" + networks: + btcnet: + aliases: + - sdk_storage + labels: + - "com.centurylinklabs.watchtower.enable=true" + restart: unless-stopped + + watchtower: + image: containrrr/watchtower + container_name: watchtower + volumes: + - /var/run/docker.sock:/var/run/docker.sock + command: --interval 30 --label-enable + networks: + - btcnet + restart: unless-stopped + + signet_miner: + build: + context: ./miner + container_name: signet_miner + depends_on: + bitcoin: + condition: service_healthy + env_file: + - ./miner/.env + volumes: + - bitcoin_data:/bitcoin:ro + networks: + btcnet: + aliases: + - signet_miner + profiles: ["miner"] + restart: unless-stopped + +volumes: + bitcoin_data: + name: 4nk_node_bitcoin_data + blindbit_data: + sdk_data: + +networks: + btcnet: + name: 4nk_node_btcnet + driver: bridge + ipam: + config: + - subnet: 172.20.0.0/16 diff --git a/scripts/funds/auto_transfer_funds.sh b/scripts/funds/auto_transfer_funds.sh index cafe245..7da4916 100755 --- a/scripts/funds/auto_transfer_funds.sh +++ b/scripts/funds/auto_transfer_funds.sh @@ -40,12 +40,12 @@ log_error() { # Fonction pour vérifier la connectivité Bitcoin check_bitcoin_connectivity() { log_info "Vérification de la connectivité Bitcoin..." - + if ! docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="$COOKIE_FILE" getblockchaininfo > /dev/null 2>&1; then log_error "Impossible de se connecter au nœud Bitcoin" return 1 fi - + log_success "Connexion Bitcoin OK" return 0 } @@ -53,14 +53,14 @@ check_bitcoin_connectivity() { # Fonction pour vérifier le solde du wallet mining check_mining_balance() { log_info "Vérification du solde du wallet mining..." - + local balance=$(docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="$COOKIE_FILE" -rpcwallet="$MINING_WALLET" getbalance 2>/dev/null || echo "0") - + if [ "$balance" = "0" ]; then log_error "Wallet mining vide ou inaccessible" return 1 fi - + log_success "Solde wallet mining: $balance BTC" echo "$balance" return 0 @@ -69,12 +69,12 @@ check_mining_balance() { # Fonction pour vérifier le solde du wallet relay check_relay_balance() { log_info "Vérification du solde du wallet relay..." - + # Charger le wallet relay s'il n'est pas déjà chargé docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="$COOKIE_FILE" loadwallet "$RELAY_WALLET" > /dev/null 2>&1 || true - + local balance=$(docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="$COOKIE_FILE" -rpcwallet="$RELAY_WALLET" getbalance 2>/dev/null || echo "0") - + log_info "Solde wallet relay: $balance BTC" echo "$balance" return 0 @@ -83,17 +83,17 @@ check_relay_balance() { # Fonction pour générer une adresse pour le relay generate_relay_address() { log_info "Génération d'une adresse pour le relay..." - + # Charger le wallet relay docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="$COOKIE_FILE" loadwallet "$RELAY_WALLET" > /dev/null 2>&1 || true - + local address=$(docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="$COOKIE_FILE" -rpcwallet="$RELAY_WALLET" getnewaddress "relay_funding" 2>/dev/null) - + if [ -z "$address" ]; then log_error "Impossible de générer une adresse pour le relay" return 1 fi - + log_success "Adresse générée: $address" echo "$address" return 0 @@ -103,16 +103,16 @@ generate_relay_address() { transfer_funds() { local amount=$1 local address=$2 - + log_info "Transfert de $amount BTC vers $address..." - + local txid=$(docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="$COOKIE_FILE" -rpcwallet="$MINING_WALLET" sendtoaddress "$address" "$amount" 2>/dev/null) - + if [ -z "$txid" ]; then log_error "Échec du transfert de fonds" return 1 fi - + log_success "Transfert effectué. TXID: $txid" echo "$txid" return 0 @@ -122,15 +122,15 @@ transfer_funds() { confirm_transaction() { local txid=$1 local address=$2 - + log_info "Confirmation de la transaction $txid..." - + # Générer des blocs pour confirmer la transaction docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="$COOKIE_FILE" -rpcwallet="$MINING_WALLET" generatetoaddress 6 "$address" > /dev/null 2>&1 - + # Vérifier les confirmations local confirmations=$(docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="$COOKIE_FILE" -rpcwallet="$MINING_WALLET" gettransaction "$txid" 2>/dev/null | jq -r '.confirmations // 0') - + if [ "$confirmations" -gt 0 ]; then log_success "Transaction confirmée ($confirmations confirmations)" return 0 @@ -143,9 +143,9 @@ confirm_transaction() { # Fonction pour vérifier les fonds du relay dans le fichier de configuration check_relay_funds_in_config() { log_info "Vérification des fonds du relay dans la configuration..." - + local outputs_count=$(docker exec sdk_relay cat /home/bitcoin/.4nk/default 2>/dev/null | jq -r '.outputs | length // 0' 2>/dev/null || echo "0") - + log_info "Nombre d'outputs du relay: $outputs_count" echo "$outputs_count" return 0 @@ -155,40 +155,40 @@ check_relay_funds_in_config() { main() { local amount=${1:-$DEFAULT_AMOUNT} local relay_address=${2:-""} - + log_info "=== TRANSFERT AUTOMATIQUE DE FONDS ===" log_info "Montant: $amount BTC" - + # Vérifications préliminaires if ! check_bitcoin_connectivity; then exit 1 fi - + # Vérifier le solde du wallet mining local mining_balance=$(check_mining_balance) if [ $? -ne 0 ]; then exit 1 fi - + # Vérifier si le montant demandé est disponible if (( $(echo "$mining_balance < $amount" | bc -l) )); then log_error "Solde insuffisant dans le wallet mining ($mining_balance BTC < $amount BTC)" exit 1 fi - + # Vérifier le solde actuel du relay local relay_balance=$(check_relay_balance) - + # Vérifier les fonds dans la configuration du relay local outputs_count=$(check_relay_funds_in_config) - + # Si le relay a déjà des fonds, ne pas transférer if (( $(echo "$relay_balance > 0" | bc -l) )) || [ "$outputs_count" -gt 0 ]; then log_info "Le relay a déjà des fonds (balance: $relay_balance BTC, outputs: $outputs_count)" log_success "Aucun transfert nécessaire" exit 0 fi - + # Générer une adresse pour le relay si non fournie if [ -z "$relay_address" ]; then relay_address=$(generate_relay_address) @@ -196,26 +196,26 @@ main() { exit 1 fi fi - + # Effectuer le transfert local txid=$(transfer_funds "$amount" "$relay_address") if [ $? -ne 0 ]; then exit 1 fi - + # Confirmer la transaction if confirm_transaction "$txid" "$relay_address"; then log_success "Transfert de fonds réussi et confirmé" - + # Redémarrer le relay pour qu'il détecte les nouveaux fonds log_info "Redémarrage du relay pour détecter les nouveaux fonds..." docker compose restart sdk_relay - + log_success "Relay redémarré. Les fonds devraient être détectés dans quelques secondes." else log_warning "Transfert effectué mais non confirmé. Le relay pourrait ne pas détecter les fonds immédiatement." fi - + log_success "=== TRANSFERT AUTOMATIQUE TERMINÉ ===" } diff --git a/scripts/funds/funds_detector_service.js b/scripts/funds/funds_detector_service.js new file mode 100755 index 0000000..b32db7c --- /dev/null +++ b/scripts/funds/funds_detector_service.js @@ -0,0 +1,171 @@ +#!/usr/bin/env node + +/** + * Service de détection et transfert automatique de fonds + * Ce service surveille les applications et transfère automatiquement des fonds + * quand un manque de fonds est détecté + */ + +const { spawn, exec } = require('child_process'); +const fs = require('fs'); +const path = require('path'); + +class FundsDetectorService { + constructor() { + this.isRunning = false; + this.checkInterval = 30000; // 30 secondes + this.minFundsThreshold = 0.001; // 0.001 BTC = 100,000 sats + this.transferAmount = 0.01; // 0.01 BTC = 1,000,000 sats + this.logFile = '/tmp/funds_detector.log'; + } + + log(message) { + const timestamp = new Date().toISOString(); + const logMessage = `[${timestamp}] ${message}\n`; + console.log(logMessage.trim()); + fs.appendFileSync(this.logFile, logMessage); + } + + async checkRelayFunds() { + try { + // Vérifier les fonds du relay dans la configuration + const outputsCount = await this.getRelayOutputsCount(); + this.log(`Relay outputs count: ${outputsCount}`); + + // Vérifier le solde du wallet relay dans Bitcoin Core + const relayBalance = await this.getRelayBalance(); + this.log(`Relay balance: ${relayBalance} BTC`); + + // Si le relay n'a pas de fonds, déclencher le transfert + if (outputsCount === 0 && parseFloat(relayBalance) < this.minFundsThreshold) { + this.log(`⚠️ Fonds insuffisants détectés. Lancement du transfert automatique...`); + await this.transferFunds(); + return true; + } + + this.log(`✅ Fonds suffisants (outputs: ${outputsCount}, balance: ${relayBalance} BTC)`); + return false; + } catch (error) { + this.log(`❌ Erreur lors de la vérification des fonds: ${error.message}`); + return false; + } + } + + async getRelayOutputsCount() { + return new Promise((resolve, reject) => { + exec('docker exec sdk_relay cat /home/bitcoin/.4nk/default 2>/dev/null | jq -r \'.outputs | length // 0\' 2>/dev/null || echo "0"', (error, stdout, stderr) => { + if (error) { + reject(error); + } else { + resolve(parseInt(stdout.trim()) || 0); + } + }); + }); + } + + async getRelayBalance() { + return new Promise((resolve, reject) => { + exec('docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="default" getbalance 2>/dev/null || echo "0"', (error, stdout, stderr) => { + if (error) { + reject(error); + } else { + resolve(parseFloat(stdout.trim()) || 0); + } + }); + }); + } + + async transferFunds() { + try { + this.log(`🔄 Transfert de ${this.transferAmount} BTC...`); + + // Charger le wallet relay + await this.execCommand('docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" loadwallet "default" > /dev/null 2>&1 || true'); + + // Générer une adresse pour le relay + const relayAddress = await this.execCommand('docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="default" getnewaddress "relay_funding" 2>/dev/null'); + this.log(`Adresse générée: ${relayAddress}`); + + // Effectuer le transfert + const txid = await this.execCommand(`docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="mining_mnemonic" sendtoaddress "${relayAddress}" "${this.transferAmount}" 2>/dev/null`); + this.log(`Transaction ID: ${txid}`); + + // Générer des blocs pour confirmer + await this.execCommand(`docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="mining_mnemonic" generatetoaddress 6 "${relayAddress}" > /dev/null 2>&1`); + + // Redémarrer le relay + this.log(`🔄 Redémarrage du relay...`); + await this.execCommand('docker compose restart sdk_relay'); + + this.log(`✅ Transfert de fonds réussi et relay redémarré`); + return true; + } catch (error) { + this.log(`❌ Erreur lors du transfert: ${error.message}`); + return false; + } + } + + async execCommand(command) { + return new Promise((resolve, reject) => { + exec(command, (error, stdout, stderr) => { + if (error) { + reject(error); + } else { + resolve(stdout.trim()); + } + }); + }); + } + + async start() { + if (this.isRunning) { + this.log('Service déjà en cours d\'exécution'); + return; + } + + this.isRunning = true; + this.log('🚀 Démarrage du service de détection des fonds'); + this.log(`Seuil minimum: ${this.minFundsThreshold} BTC`); + this.log(`Montant de transfert: ${this.transferAmount} BTC`); + this.log(`Intervalle de vérification: ${this.checkInterval / 1000} secondes`); + + const checkLoop = async () => { + if (!this.isRunning) return; + + try { + await this.checkRelayFunds(); + } catch (error) { + this.log(`❌ Erreur dans la boucle de vérification: ${error.message}`); + } + + setTimeout(checkLoop, this.checkInterval); + }; + + // Démarrer la boucle de vérification + checkLoop(); + } + + stop() { + this.isRunning = false; + this.log('🛑 Arrêt du service de détection des fonds'); + } +} + +// Gestion des signaux pour un arrêt propre +process.on('SIGINT', () => { + console.log('\n🛑 Arrêt du service...'); + process.exit(0); +}); + +process.on('SIGTERM', () => { + console.log('\n🛑 Arrêt du service...'); + process.exit(0); +}); + +// Démarrer le service si ce script est exécuté directement +if (require.main === module) { + const service = new FundsDetectorService(); + service.start(); +} + +module.exports = FundsDetectorService; diff --git a/scripts/startup-with-funds-check.sh b/scripts/startup-with-funds-check.sh new file mode 100755 index 0000000..7ccfb21 --- /dev/null +++ b/scripts/startup-with-funds-check.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Script de démarrage avec vérification automatique des fonds +# Usage: ./startup-with-funds-check.sh + +set -e + +echo "=== DÉMARRAGE AVEC VÉRIFICATION DES FONDS ===" + +# Démarrer les services +echo "Démarrage des services..." +docker compose up -d + +# Attendre que les services soient prêts +echo "Attente du démarrage des services..." +sleep 60 + +# Vérifier et transférer les fonds si nécessaire +echo "Vérification des fonds..." +./scripts/funds/check_and_transfer_funds.sh 0.001 + +echo "=== DÉMARRAGE TERMINÉ ===" +echo "Services démarrés avec vérification des fonds automatique"