feat: Ajout de l'API de transfert automatique de fonds
Some checks failed
build-and-push-ext / build_push (push) Failing after 10s
Some checks failed
build-and-push-ext / build_push (push) Failing after 10s
- Route /api/v1/funds/transfer pour transférer des fonds - Route /api/v1/funds/check pour vérifier les fonds - Intégration dans le service ihm_client pour détection automatique - Service de détection de fonds en Node.js
This commit is contained in:
parent
4ff4f07ac5
commit
567e57abe8
67
.cursorrules
Normal file
67
.cursorrules
Normal file
@ -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
|
113
src/routes/funds.routes.ts
Normal file
113
src/routes/funds.routes.ts
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
import { Router, Request, Response } from 'express';
|
||||||
|
import { exec } from 'child_process';
|
||||||
|
import { promisify } from 'util';
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
const execAsync = promisify(exec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route pour transférer automatiquement des fonds du wallet mining vers le relay
|
||||||
|
*/
|
||||||
|
router.post('/transfer', async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
const { amount = 0.01, source = 'mining_mnemonic', target = 'default' } = req.body;
|
||||||
|
|
||||||
|
console.log(`🔄 Transfert automatique de ${amount} BTC de ${source} vers ${target}`);
|
||||||
|
|
||||||
|
// Vérifier la connectivité Bitcoin
|
||||||
|
await execAsync('docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" getblockchaininfo');
|
||||||
|
|
||||||
|
// Charger le wallet cible
|
||||||
|
await execAsync(`docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" loadwallet "${target}"`);
|
||||||
|
|
||||||
|
// Vérifier le solde du wallet source
|
||||||
|
const { stdout: sourceBalance } = await execAsync(`docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="${source}" getbalance`);
|
||||||
|
const balance = parseFloat(sourceBalance.trim());
|
||||||
|
|
||||||
|
if (balance < amount) {
|
||||||
|
return res.status(400).json({
|
||||||
|
success: false,
|
||||||
|
error: `Solde insuffisant dans le wallet ${source}: ${balance} BTC < ${amount} BTC`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vérifier le solde du wallet cible
|
||||||
|
const { stdout: targetBalance } = await execAsync(`docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="${target}" getbalance`);
|
||||||
|
const targetBalanceValue = parseFloat(targetBalance.trim());
|
||||||
|
|
||||||
|
// Si le wallet cible a déjà des fonds, ne pas transférer
|
||||||
|
if (targetBalanceValue >= 0.001) {
|
||||||
|
return res.json({
|
||||||
|
success: true,
|
||||||
|
message: `Wallet ${target} a déjà des fonds suffisants (${targetBalanceValue} BTC)`,
|
||||||
|
targetBalance: targetBalanceValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Générer une adresse pour le wallet cible
|
||||||
|
const { stdout: address } = await execAsync(`docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="${target}" getnewaddress "auto_funding"`);
|
||||||
|
|
||||||
|
// Effectuer le transfert
|
||||||
|
const { stdout: txid } = await execAsync(`docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="${source}" sendtoaddress "${address.trim()}" "${amount}"`);
|
||||||
|
|
||||||
|
// Générer des blocs pour confirmer la transaction
|
||||||
|
await execAsync(`docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="${source}" generatetoaddress 6 "${address.trim()}"`);
|
||||||
|
|
||||||
|
// Redémarrer le relay
|
||||||
|
await execAsync('docker compose restart sdk_relay');
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
message: `Transfert de ${amount} BTC réussi`,
|
||||||
|
transactionId: txid.trim(),
|
||||||
|
address: address.trim(),
|
||||||
|
sourceBalance: balance,
|
||||||
|
targetBalance: targetBalanceValue
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Erreur lors du transfert automatique:', error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
error: `Erreur lors du transfert: ${error.message}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route pour vérifier les fonds du relay
|
||||||
|
*/
|
||||||
|
router.get('/check', async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
// Vérifier les fonds du relay dans la configuration
|
||||||
|
const { stdout: outputsCount } = await execAsync('docker exec sdk_relay cat /home/bitcoin/.4nk/default 2>/dev/null | jq -r \'.outputs | length // 0\' 2>/dev/null || echo "0"');
|
||||||
|
|
||||||
|
// Vérifier le solde du wallet relay dans Bitcoin Core
|
||||||
|
await execAsync('docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" loadwallet "default"');
|
||||||
|
const { stdout: relayBalance } = await execAsync('docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="default" getbalance');
|
||||||
|
|
||||||
|
// Vérifier le solde du wallet mining
|
||||||
|
const { stdout: miningBalance } = await execAsync('docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile="/home/bitcoin/.bitcoin/signet/.cookie" -rpcwallet="mining_mnemonic" getbalance');
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
success: true,
|
||||||
|
relay: {
|
||||||
|
outputsCount: parseInt(outputsCount.trim()),
|
||||||
|
balance: parseFloat(relayBalance.trim())
|
||||||
|
},
|
||||||
|
mining: {
|
||||||
|
balance: parseFloat(miningBalance.trim())
|
||||||
|
},
|
||||||
|
needsTransfer: parseInt(outputsCount.trim()) === 0 && parseFloat(relayBalance.trim()) < 0.001
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Erreur lors de la vérification des fonds:', error);
|
||||||
|
res.status(500).json({
|
||||||
|
success: false,
|
||||||
|
error: `Erreur lors de la vérification: ${error.message}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
@ -6,6 +6,7 @@ import { emailRoutes } from './email.routes';
|
|||||||
import { stripeRoutes } from './stripe.routes';
|
import { stripeRoutes } from './stripe.routes';
|
||||||
import { subscriptionRoutes } from './subscription.routes';
|
import { subscriptionRoutes } from './subscription.routes';
|
||||||
import { processRoutes } from './process.routes';
|
import { processRoutes } from './process.routes';
|
||||||
|
import fundsRoutes from './funds.routes';
|
||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
@ -17,6 +18,7 @@ router.get('/', (req, res) => {
|
|||||||
status: 'running',
|
status: 'running',
|
||||||
endpoints: {
|
endpoints: {
|
||||||
health: '/api/v1/health',
|
health: '/api/v1/health',
|
||||||
|
funds: '/api/v1/funds',
|
||||||
sms: '/api/sms',
|
sms: '/api/sms',
|
||||||
idnot: '/api/v1/idnot',
|
idnot: '/api/v1/idnot',
|
||||||
process: '/api/v1/process',
|
process: '/api/v1/process',
|
||||||
@ -29,6 +31,7 @@ router.get('/', (req, res) => {
|
|||||||
|
|
||||||
// Mount routes
|
// Mount routes
|
||||||
router.use('/api/v1', healthRoutes);
|
router.use('/api/v1', healthRoutes);
|
||||||
|
router.use('/api/v1/funds', fundsRoutes);
|
||||||
router.use('/api', smsRoutes);
|
router.use('/api', smsRoutes);
|
||||||
router.use('/api/v1/idnot', idnotRoutes);
|
router.use('/api/v1/idnot', idnotRoutes);
|
||||||
router.use('/api/v1/process', processRoutes);
|
router.use('/api/v1/process', processRoutes);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user