Compare commits

..

2 Commits
v0.1.1 ... main

Author SHA1 Message Date
9d79891ce6 Merge branch 'dev' into 'main'
sdk_common = { git = "https://git.4nkweb.com/4nk/sdk_common.git", branch = "dev" }

See merge request 4nk/sdk_client!1
2024-05-31 15:58:27 +00:00
e7e02dfa8a sdk_common = { git = "https://git.4nkweb.com/4nk/sdk_common.git", branch = "dev" } 2024-05-31 15:57:12 +00:00
73 changed files with 8502 additions and 12739 deletions

View File

@ -1,11 +0,0 @@
# Ignorer les sorties volumineuses ou non pertinentes pour le contexte IA
archive/**
tests/logs/**
tests/reports/**
node_modules/**
dist/**
build/**
.tmp/**
.cache/**#
.env
.env.*

View File

@ -1,59 +0,0 @@
---
alwaysApply: true
---
# Fondations de rédaction et de comportement
[portée]
Sapplique à tout le dépôt 4NK/4NK_node pour toute génération, refactorisation, édition inline ou discussion dans Cursor.
[objectifs]
- Garantir lusage exclusif du français.
- Proscrire linjection dexemples de code applicatif dans la base de code.
- Assurer une cohérence stricte de terminologie et de ton.
- Exiger une introduction et/ou une conclusion dans toute proposition de texte.
[directives]
- Toujours répondre et documenter en français.
- Ne pas inclure dexemples exécutables ou de quickstarts dans la base ; préférer des descriptions prescriptives.
- Tout contenu produit doit mentionner explicitement les artefacts à mettre à jour lorsquil impacte docs/ et tests/.
- Préserver la typographie française (capitaliser uniquement le premier mot dun titre et les noms propres).
[validations]
- Relecture linguistique et technique systématique.
- Refuser toute sortie avec exemples de code applicatif.
- Vérifier que lissue traitée se conclut par un rappel des fichiers à mettre à jour.
[artefacts concernés]
- README.md, docs/**, tests/**, CHANGELOG.md, .gitea/**.# Fondations de rédaction et de comportement
[portée]
Sapplique à tout le dépôt 4NK/4NK_node pour toute génération, refactorisation, édition inline ou discussion dans Cursor.
[objectifs]
- Garantir lusage exclusif du français.
- Proscrire linjection dexemples de code applicatif dans la base de code.
- Assurer une cohérence stricte de terminologie et de ton.
- Exiger une introduction et/ou une conclusion dans toute proposition de texte.
[directives]
- Toujours répondre et documenter en français.
- Ne pas inclure dexemples exécutables ou de quickstarts dans la base ; préférer des descriptions prescriptives.
- Tout contenu produit doit mentionner explicitement les artefacts à mettre à jour lorsquil impacte docs/ et tests/.
- Préserver la typographie française (capitaliser uniquement le premier mot dun titre et les noms propres).
[validations]
- Relecture linguistique et technique systématique.
- Refuser toute sortie avec exemples de code applicatif.
- Vérifier que lissue traitée se conclut par un rappel des fichiers à mettre à jour.
[artefacts concernés]
- README.md, docs/**, tests/**, CHANGELOG.md, .gitea/**.

View File

@ -1,139 +0,0 @@
---
alwaysApply: true
---
# Structure projet 4NK_node
[portée]
Maintenance de larborescence canonique, création/mise à jour/suppression de fichiers et répertoires.
[objectifs]
- Garantir lalignement strict avec larborescence 4NK_node.
- Prévenir toute dérive structurelle.
[directives]
- Sassurer que larborescence suivante existe et reste conforme :
4NK/4NK_node
├── archive
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── docker-compose.yml
├── docs
│ ├── API.md
│ ├── ARCHITECTURE.md
│ ├── COMMUNITY_GUIDE.md
│ ├── CONFIGURATION.md
│ ├── GITEA_SETUP.md
│ ├── INDEX.md
│ ├── INSTALLATION.md
│ ├── MIGRATION.md
│ ├── OPEN_SOURCE_CHECKLIST.md
│ ├── QUICK_REFERENCE.md
│ ├── RELEASE_PLAN.md
│ ├── ROADMAP.md
│ ├── SECURITY_AUDIT.md
│ ├── TESTING.md
│ └── USAGE.md
├── LICENSE
├── README.md
├── tests
│ ├── cleanup.sh
│ ├── connectivity
│ ├── external
│ ├── integration
│ ├── logs
│ ├── performance
│ ├── README.md
│ ├── reports
│ └── unit
└── .gitea
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
└── ci.yml
- Tout document obsolète est déplacé vers archive/ avec métadonnées (date, raison).
- Interdire la suppression brute de fichiers sans archivage et note dans CHANGELOG.md.
[validations]
- Diff structurel comparé à cette référence.
- Erreur bloquante si un fichier « requis » manque.
[artefacts concernés]
- archive/**, docs/**, tests/**, .gitea/**, CHANGELOG.md.
# Structure projet 4NK_node
[portée]
Maintenance de larborescence canonique, création/mise à jour/suppression de fichiers et répertoires.
[objectifs]
- Garantir lalignement strict avec larborescence 4NK_node.
- Prévenir toute dérive structurelle.
[directives]
- Sassurer que larborescence suivante existe et reste conforme :
4NK/4NK_node
├── archive
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── docker-compose.yml
├── docs
│ ├── API.md
│ ├── ARCHITECTURE.md
│ ├── COMMUNITY_GUIDE.md
│ ├── CONFIGURATION.md
│ ├── GITEA_SETUP.md
│ ├── INDEX.md
│ ├── INSTALLATION.md
│ ├── MIGRATION.md
│ ├── OPEN_SOURCE_CHECKLIST.md
│ ├── QUICK_REFERENCE.md
│ ├── RELEASE_PLAN.md
│ ├── ROADMAP.md
│ ├── SECURITY_AUDIT.md
│ ├── TESTING.md
│ └── USAGE.md
├── LICENSE
├── README.md
├── tests
│ ├── cleanup.sh
│ ├── connectivity
│ ├── external
│ ├── integration
│ ├── logs
│ ├── performance
│ ├── README.md
│ ├── reports
│ └── unit
└── .gitea
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
└── ci.yml
- Tout document obsolète est déplacé vers archive/ avec métadonnées (date, raison).
- Interdire la suppression brute de fichiers sans archivage et note dans CHANGELOG.md.
[validations]
- Diff structurel comparé à cette référence.
- Erreur bloquante si un fichier « requis » manque.
[artefacts concernés]
- archive/**, docs/**, tests/**, .gitea/**, CHANGELOG.md.

View File

@ -1,62 +0,0 @@
---
alwaysApply: true
---
# Documentation continue
[portée]
Mises à jour de docs/** corrélées à tout changement de code, configuration, dépendance, données ou CI.
[objectifs]
- Remplacer toute section générique « RESUME » par des mises à jour ciblées dans les fichiers appropriés.
- Tenir INDEX.md comme table des matières de référence.
[directives]
- À chaque changement, mettre à jour :
- API.md (spécifications, contrats, schémas, invariants).
- ARCHITECTURE.md (décisions, diagrammes, couplages, performances).
- CONFIGURATION.md (paramètres, formats, valeurs par défaut).
- INSTALLATION.md (pré-requis, étapes, vérifications).
- MIGRATION.md (chemins de migration, scripts, compatibilités).
- USAGE.md (parcours fonctionnels, contraintes).
- TESTING.md (pyramide, critères dacceptation).
- SECURITY_AUDIT.md (menaces, contrôles, dettes résiduelles).
- RELEASE_PLAN.md, ROADMAP.md (planification), OPEN_SOURCE_CHECKLIST.md, COMMUNITY_GUIDE.md, GITEA_SETUP.md.
- Maintenir QUICK_REFERENCE.md pour les référentiels synthétiques utilisés par léquipe.
- Ajouter un REX technique en cas dhypothèses multiples avant résolution dans archive/.
[validations]
- Cohérence croisée entre README.md et INDEX.md.
- Refus si une modification de code na pas de trace dans docs/** correspondants.
[artefacts concernés]
- docs/**, README.md, archive/**.
# Documentation continue
[portée]
Mises à jour de docs/** corrélées à tout changement de code, configuration, dépendance, données ou CI.
[objectifs]
- Remplacer toute section générique « RESUME » par des mises à jour ciblées dans les fichiers appropriés.
- Tenir INDEX.md comme table des matières de référence.
[directives]
- À chaque changement, mettre à jour :
- API.md (spécifications, contrats, schémas, invariants).
- ARCHITECTURE.md (décisions, diagrammes, couplages, performances).
- CONFIGURATION.md (paramètres, formats, valeurs par défaut).
- INSTALLATION.md (pré-requis, étapes, vérifications).
- MIGRATION.md (chemins de migration, scripts, compatibilités).
- USAGE.md (parcours fonctionnels, contraintes).
- TESTING.md (pyramide, critères dacceptation).
- SECURITY_AUDIT.md (menaces, contrôles, dettes résiduelles).
- RELEASE_PLAN.md, ROADMAP.md (planification), OPEN_SOURCE_CHECKLIST.md, COMMUNITY_GUIDE.md, GITEA_SETUP.md.
- Maintenir QUICK_REFERENCE.md pour les référentiels synthétiques utilisés par léquipe.
- Ajouter un REX technique en cas dhypothèses multiples avant résolution dans archive/.
[validations]
- Cohérence croisée entre README.md et INDEX.md.
- Refus si une modification de code na pas de trace dans docs/** correspondants.
[artefacts concernés]
- docs/**, README.md, archive/**.

View File

@ -1,57 +0,0 @@
---
alwaysApply: true
---
# Tests et qualité
[portée]
Stratégie de tests, exécution locale, stabilité, non-régression.
[objectifs]
- Exiger des tests verts avant tout commit.
- Couvrir les axes unit, integration, connectivity, performance, external.
[directives]
- Ajouter/mettre à jour des tests dans tests/unit, tests/integration, tests/connectivity, tests/performance, tests/external selon limpact.
- Consigner les journaux dans tests/logs et les rapports dans tests/reports.
- Maintenir tests/README.md (stratégie, outillage, seuils).
- Fournir un nettoyage reproductible via tests/cleanup.sh.
- Bloquer lédition si des tests échouent tant que la correction nest pas appliquée.
[validations]
- Refus dun commit si tests en échec.
- Exiger justification et plan de test dans docs/TESTING.md pour toute refonte majeure.
[artefacts concernés]
- tests/**, docs/TESTING.md, CHANGELOG.md.
# Tests et qualité
[portée]
Stratégie de tests, exécution locale, stabilité, non-régression.
[objectifs]
- Exiger des tests verts avant tout commit.
- Couvrir les axes unit, integration, connectivity, performance, external.
[directives]
- Ajouter/mettre à jour des tests dans tests/unit, tests/integration, tests/connectivity, tests/performance, tests/external selon limpact.
- Consigner les journaux dans tests/logs et les rapports dans tests/reports.
- Maintenir tests/README.md (stratégie, outillage, seuils).
- Fournir un nettoyage reproductible via tests/cleanup.sh.
- Bloquer lédition si des tests échouent tant que la correction nest pas appliquée.
[validations]
- Refus dun commit si tests en échec.
- Exiger justification et plan de test dans docs/TESTING.md pour toute refonte majeure.
[artefacts concernés]
- tests/**, docs/TESTING.md, CHANGELOG.md.

View File

@ -1,55 +0,0 @@
---
alwaysApply: true
---
# Dépendances, compilation et build
[portée]
Gestion des dépendances, compilation fréquente, politique de versions.
[objectifs]
- Ajouter automatiquement les dépendances manquantes si justifié.
- Rechercher systématiquement les dernières versions stables.
[directives]
- Lorsquune fonctionnalité nécessite une dépendance, lajouter et la documenter (nom, version, portée, impact) dans docs/ARCHITECTURE.md et docs/CONFIGURATION.md si nécessaire.
- Compiler très régulièrement et « quand nécessaire » (avant refactor, avant push, après mise à jour de dépendances).
- Corriger toute erreur de compilation/exécution avant de poursuivre.
- Documenter tout changement de dépendances (raison, risques, rollback).
[validations]
- Interdire la progression si la compilation échoue.
- Vérifier la présence dune note de changement dans CHANGELOG.md en cas de dépendance ajoutée/retirée.
[artefacts concernés]
- docs/ARCHITECTURE.md, docs/CONFIGURATION.md, CHANGELOG.md.
# Dépendances, compilation et build
[portée]
Gestion des dépendances, compilation fréquente, politique de versions.
[objectifs]
- Ajouter automatiquement les dépendances manquantes si justifié.
- Rechercher systématiquement les dernières versions stables.
[directives]
- Lorsquune fonctionnalité nécessite une dépendance, lajouter et la documenter (nom, version, portée, impact) dans docs/ARCHITECTURE.md et docs/CONFIGURATION.md si nécessaire.
- Compiler très régulièrement et « quand nécessaire » (avant refactor, avant push, après mise à jour de dépendances).
- Corriger toute erreur de compilation/exécution avant de poursuivre.
- Documenter tout changement de dépendances (raison, risques, rollback).
[validations]
- Interdire la progression si la compilation échoue.
- Vérifier la présence dune note de changement dans CHANGELOG.md en cas de dépendance ajoutée/retirée.
[artefacts concernés]
- docs/ARCHITECTURE.md, docs/CONFIGURATION.md, CHANGELOG.md.

View File

@ -1,54 +0,0 @@
---
alwaysApply: false
---
# Modélisation des données à partir de CSV
[portée]
Utilisation des CSV comme base des modèles de données, y compris en-têtes multi-lignes.
[objectifs]
- Confirmer la structure inférée pour chaque CSV.
- Demander une définition formelle de toutes les colonnes.
[directives]
- Gérer explicitement les en-têtes multi-lignes (titre principal + sous-colonnes).
- Confirmer par écrit dans docs/API.md ou docs/ARCHITECTURE.md : nombre de lignes den-tête, mapping colonnes→types, unités, domaines de valeurs, nullabilité, contraintes.
- Poser des questions si ambiguïtés ; proposer une normalisation temporaire documentée.
- Corriger automatiquement les incohérences de types si une règle de mapping est établie ailleurs et documenter la transformation.
[validations]
- Aucune ingestion sans spécification de colonnes validée.
- Traçabilité des corrections de types (avant/après) dans docs/ARCHITECTURE.md.
[artefacts concernés]
- docs/API.md, docs/ARCHITECTURE.md, docs/USAGE.md.
# Modélisation des données à partir de CSV
[portée]
Utilisation des CSV comme base des modèles de données, y compris en-têtes multi-lignes.
[objectifs]
- Confirmer la structure inférée pour chaque CSV.
- Demander une définition formelle de toutes les colonnes.
[directives]
- Gérer explicitement les en-têtes multi-lignes (titre principal + sous-colonnes).
- Confirmer par écrit dans docs/API.md ou docs/ARCHITECTURE.md : nombre de lignes den-tête, mapping colonnes→types, unités, domaines de valeurs, nullabilité, contraintes.
- Poser des questions si ambiguïtés ; proposer une normalisation temporaire documentée.
- Corriger automatiquement les incohérences de types si une règle de mapping est établie ailleurs et documenter la transformation.
[validations]
- Aucune ingestion sans spécification de colonnes validée.
- Traçabilité des corrections de types (avant/après) dans docs/ARCHITECTURE.md.
[artefacts concernés]
- docs/API.md, docs/ARCHITECTURE.md, docs/USAGE.md.

View File

@ -1,41 +0,0 @@
---
alwaysApply: false
---
# Lecture des documents bureautiques
[portée]
Lecture des fichiers .docx et alternatives.
[objectifs]
- Utiliser docx2txt par défaut.
- Proposer des solutions de repli si lecture impossible.
[directives]
- Lire les .docx avec docx2txt.
- En cas déchec, proposer : conversion via pandoc, demande dune source alternative, ou extraction textuelle.
- Documenter dans docs/INDEX.md la provenance et le statut des documents importés.
[validations]
- Vérification que les contenus extraits sont intégrés aux fichiers docs/ concernés.
[artefacts concernés]
- docs/**, archive/**.
# Lecture des documents bureautiques
[portée]
Lecture des fichiers .docx et alternatives.
[objectifs]
- Utiliser docx2txt par défaut.
- Proposer des solutions de repli si lecture impossible.
[directives]
- Lire les .docx avec docx2txt.
- En cas déchec, proposer : conversion via pandoc, demande dune source alternative, ou extraction textuelle.
- Documenter dans docs/INDEX.md la provenance et le statut des documents importés.
[validations]
- Vérification que les contenus extraits sont intégrés aux fichiers docs/ concernés.
[artefacts concernés]
- docs/**, archive/**.

View File

@ -1,56 +0,0 @@
---
alwaysApply: false
---
# Architecture frontend
[portée]
Qualité du bundle, découpage, état global et couche de services.
[objectifs]
- Réduire la taille du bundle initial via code splitting.
- Éviter le prop drilling via Redux ou Context API.
- Abstraire les services de données pour testabilité et maintenance.
[directives]
- Mettre en place React.lazy et Suspense pour le chargement différé des vues/segments.
- Centraliser létat global via Redux ou Context API.
- Isoler les appels « data » derrière une couche dabstraction à interface stable.
- Interdire lajout dexemples front dans la base de code.
[validations]
- Vérifier que les points dentrée sont minimes et que les segments non critiques sont chargés à la demande.
- Sassurer que docs/ARCHITECTURE.md décrit les décisions et les points dextension.
[artefacts concernés]
- docs/ARCHITECTURE.md, docs/TESTING.md.
# Architecture frontend
[portée]
Qualité du bundle, découpage, état global et couche de services.
[objectifs]
- Réduire la taille du bundle initial via code splitting.
- Éviter le prop drilling via Redux ou Context API.
- Abstraire les services de données pour testabilité et maintenance.
[directives]
- Mettre en place React.lazy et Suspense pour le chargement différé des vues/segments.
- Centraliser létat global via Redux ou Context API.
- Isoler les appels « data » derrière une couche dabstraction à interface stable.
- Interdire lajout dexemples front dans la base de code.
[validations]
- Vérifier que les points dentrée sont minimes et que les segments non critiques sont chargés à la demande.
- Sassurer que docs/ARCHITECTURE.md décrit les décisions et les points dextension.
[artefacts concernés]
- docs/ARCHITECTURE.md, docs/TESTING.md.

View File

@ -1,53 +0,0 @@
---
alwaysApply: false
---
# Versionnage et publication
[portée]
Gestion sémantique des versions, CHANGELOG, confirmation push/tag.
[objectifs]
- Tenir CHANGELOG.md comme source unique de vérité.
- Demander confirmation avant push et tag.
[directives]
- À chaque changement significatif, mettre à jour CHANGELOG.md (ajouts, changements, corrections, ruptures).
- Proposer un bump semver (major/minor/patch) motivé par limpact.
- Avant tout push ou tag, demander confirmation explicite.
[validations]
- Refus si modification sans entrée correspondante dans CHANGELOG.md.
- Cohérence entre CHANGELOG.md, docs/RELEASE_PLAN.md et docs/ROADMAP.md.
[artefacts concernés]
- CHANGELOG.md, docs/RELEASE_PLAN.md, docs/ROADMAP.md.
# Versionnage et publication
[portée]
Gestion sémantique des versions, CHANGELOG, confirmation push/tag.
[objectifs]
- Tenir CHANGELOG.md comme source unique de vérité.
- Demander confirmation avant push et tag.
[directives]
- À chaque changement significatif, mettre à jour CHANGELOG.md (ajouts, changements, corrections, ruptures).
- Proposer un bump semver (major/minor/patch) motivé par limpact.
- Avant tout push ou tag, demander confirmation explicite.
[validations]
- Refus si modification sans entrée correspondante dans CHANGELOG.md.
- Cohérence entre CHANGELOG.md, docs/RELEASE_PLAN.md et docs/ROADMAP.md.
[artefacts concernés]
- CHANGELOG.md, docs/RELEASE_PLAN.md, docs/ROADMAP.md.

View File

@ -1,59 +0,0 @@
---
alwaysApply: true
---
# Open source et Gitea
[portée]
Conformité open source, templates Gitea, CI.
[objectifs]
- Préparer chaque projet pour un dépôt Gitea (git.4nkweb.com).
- Maintenir les fichiers de gouvernance et la CI.
[directives]
- Vérifier la présence et lactualité de : LICENSE, CONTRIBUTING.md, CODE_OF_CONDUCT.md, OPEN_SOURCE_CHECKLIST.md.
- Maintenir .gitea/ :
- ISSUE_TEMPLATE/bug_report.md, feature_request.md
- PULL_REQUEST_TEMPLATE.md
- workflows/ci.yml
- Documenter dans docs/GITEA_SETUP.md la configuration distante et les permissions.
[validations]
- Refus si un des fichiers « gouvernance/CI » manque.
- Cohérence entre docs/OPEN_SOURCE_CHECKLIST.md et létat du repo.
[artefacts concernés]
- .gitea/**, docs/GITEA_SETUP.md, docs/OPEN_SOURCE_CHECKLIST.md.
# Open source et Gitea
[portée]
Conformité open source, templates Gitea, CI.
[objectifs]
- Préparer chaque projet pour un dépôt Gitea (git.4nkweb.com).
- Maintenir les fichiers de gouvernance et la CI.
[directives]
- Vérifier la présence et lactualité de : LICENSE, CONTRIBUTING.md, CODE_OF_CONDUCT.md, OPEN_SOURCE_CHECKLIST.md.
- Maintenir .gitea/ :
- ISSUE_TEMPLATE/bug_report.md, feature_request.md
- PULL_REQUEST_TEMPLATE.md
- workflows/ci.yml
- Documenter dans docs/GITEA_SETUP.md la configuration distante et les permissions.
[validations]
- Refus si un des fichiers « gouvernance/CI » manque.
- Cohérence entre docs/OPEN_SOURCE_CHECKLIST.md et létat du repo.
[artefacts concernés]
- .gitea/**, docs/GITEA_SETUP.md, docs/OPEN_SOURCE_CHECKLIST.md.

View File

@ -1,53 +0,0 @@
---
alwaysApply: true
---
# Tri, diagnostic et résolution de problèmes
[portée]
Boucle de triage : reproduction, diagnostic, correctif, non-régression.
[objectifs]
- Exécuter automatiquement les étapes de résolution.
- Bloquer lavancement tant que les erreurs ne sont pas corrigées.
[directives]
- Étapes obligatoires : reproduction minimale, inspection des logs, bissection des changements, formulation dhypothèses, tests ciblés, correctif, test de non-régression.
- Lorsque plusieurs hypothèses ont été testées, produire un REX dans archive/ avec liens vers les commits.
- Poser des questions de cohérence fonctionnelle si des ambiguïtés subsistent (contrats dAPI, invariants, SLA).
[validations]
- Interdiction de clore une tâche si un test échoue ou si une alerte critique subsiste.
- Traçabilité du REX si investigations multiples.
[artefacts concernés]
- tests/**, archive/**, docs/TESTING.md, docs/ARCHITECTURE.md.
# Tri, diagnostic et résolution de problèmes
[portée]
Boucle de triage : reproduction, diagnostic, correctif, non-régression.
[objectifs]
- Exécuter automatiquement les étapes de résolution.
- Bloquer lavancement tant que les erreurs ne sont pas corrigées.
[directives]
- Étapes obligatoires : reproduction minimale, inspection des logs, bissection des changements, formulation dhypothèses, tests ciblés, correctif, test de non-régression.
- Lorsque plusieurs hypothèses ont été testées, produire un REX dans archive/ avec liens vers les commits.
- Poser des questions de cohérence fonctionnelle si des ambiguïtés subsistent (contrats dAPI, invariants, SLA).
[validations]
- Interdiction de clore une tâche si un test échoue ou si une alerte critique subsiste.
- Traçabilité du REX si investigations multiples.
[artefacts concernés]
- tests/**, archive/**, docs/TESTING.md, docs/ARCHITECTURE.md.

View File

@ -1,15 +0,0 @@
# Index des règles .cursor/rules
- 00-foundations.mdc : règles linguistiques et éditoriales (français, pas dexemples en base, introduction/conclusion).
- 10-project-structure.mdc : arborescence canonique 4NK_node et garde-fous.
- 20-documentation.mdc : documentation continue, remplacement de « RESUME », INDEX.md.
- 30-testing.mdc : tests (unit, integration, connectivity, performance, external), logs/reports.
- 40-dependencies-and-build.mdc : dépendances, compilation, corrections bloquantes.
- 50-data-csv-models.mdc : CSV avec en-têtes multi-lignes, définition des colonnes.
- 60-office-docs.mdc : lecture .docx via docx2txt + repli.
- 70-frontend-architecture.mdc : React.lazy/Suspense, état global, couche de services.
- 80-versioning-and-release.mdc : CHANGELOG, semver, confirmation push/tag.
- 90-gitea-and-oss.mdc : fichiers open source, .gitea, CI, Gitea remote.
- 95-triage-and-problem-solving.mdc : boucle de diagnostic, REX, non-régression.
Ces règles sont conçues pour être ajoutées au contexte de Cursor depuis linterface (@Cursor Rules) et sappuient sur le mécanisme de règles projet stockées dans `.cursor/rules/`. :contentReference[oaicite:3]{index=3}

View File

@ -1,97 +0,0 @@
---
name: Bug Report
about: Signaler un bug pour nous aider à améliorer 4NK Node
title: '[BUG] '
labels: ['bug', 'needs-triage']
assignees: ''
---
## 🐛 Description du Bug
Description claire et concise du problème.
## 🔄 Étapes pour Reproduire
1. Aller à '...'
2. Cliquer sur '...'
3. Faire défiler jusqu'à '...'
4. Voir l'erreur
## ✅ Comportement Attendu
Description de ce qui devrait se passer.
## ❌ Comportement Actuel
Description de ce qui se passe actuellement.
## 📸 Capture d'Écran
Si applicable, ajoutez une capture d'écran pour expliquer votre problème.
## 💻 Informations Système
- **OS** : [ex: Ubuntu 20.04, macOS 12.0, Windows 11]
- **Docker** : [ex: 20.10.0]
- **Docker Compose** : [ex: 2.0.0]
- **Version 4NK Node** : [ex: v1.0.0]
- **Architecture** : [ex: x86_64, ARM64]
## 📋 Configuration
### Services Actifs
```bash
docker ps
```
### Variables d'Environnement
```bash
# Bitcoin Core
BITCOIN_NETWORK=signet
BITCOIN_RPC_PORT=18443
# Blindbit
BLINDBIT_PORT=8000
# SDK Relay
SDK_RELAY_PORTS=8090-8095
```
## 📝 Logs
### Logs Pertinents
```
Logs pertinents ici
```
### Logs d'Erreur
```
Logs d'erreur ici
```
### Logs de Debug
```
Logs de debug ici (si RUST_LOG=debug)
```
## 🔧 Tentatives de Résolution
- [ ] Redémarrage des services
- [ ] Nettoyage des volumes Docker
- [ ] Vérification de la connectivité réseau
- [ ] Mise à jour des dépendances
- [ ] Vérification de la configuration
## 📚 Contexte Supplémentaire
Toute autre information pertinente sur le problème.
## 🔗 Liens Utiles
- [Documentation](docs/)
- [Guide de Dépannage](docs/TROUBLESHOOTING.md)
- [Issues Similaires](https://git.4nkweb.com/4nk/4NK_node/issues?q=is%3Aissue+is%3Aopen+label%3Abug)
---
**Merci de votre contribution !** 🙏

View File

@ -1,156 +0,0 @@
---
name: Feature Request
about: Proposer une nouvelle fonctionnalité pour 4NK Node
title: '[FEATURE] '
labels: ['enhancement', 'needs-triage']
assignees: ''
---
## 🚀 Résumé
Description claire et concise de la fonctionnalité souhaitée.
## 💡 Motivation
Pourquoi cette fonctionnalité est-elle nécessaire ? Quels problèmes résout-elle ?
### Problèmes Actuels
- Problème 1
- Problème 2
- Problème 3
### Avantages de la Solution
- Avantage 1
- Avantage 2
- Avantage 3
## 🎯 Proposition
Description détaillée de la fonctionnalité proposée.
### Fonctionnalités Principales
- [ ] Fonctionnalité 1
- [ ] Fonctionnalité 2
- [ ] Fonctionnalité 3
### Interface Utilisateur
Description de l'interface utilisateur si applicable.
### API Changes
Description des changements d'API si applicable.
## 🔄 Alternatives Considérées
Autres solutions envisagées et pourquoi elles n'ont pas été choisies.
### Alternative 1
- **Description** : ...
- **Pourquoi rejetée** : ...
### Alternative 2
- **Description** : ...
- **Pourquoi rejetée** : ...
## 📊 Impact
### Impact sur les Utilisateurs
- Impact positif 1
- Impact positif 2
- Impact négatif potentiel (si applicable)
### Impact sur l'Architecture
- Changements nécessaires
- Compatibilité avec l'existant
- Performance
### Impact sur la Maintenance
- Complexité ajoutée
- Tests nécessaires
- Documentation requise
## 💻 Exemples d'Utilisation
### Cas d'Usage 1
```bash
# Exemple de commande ou configuration
```
### Cas d'Usage 2
```python
# Exemple de code Python
```
### Cas d'Usage 3
```javascript
// Exemple de code JavaScript
```
## 🧪 Tests
### Tests Nécessaires
- [ ] Tests unitaires
- [ ] Tests d'intégration
- [ ] Tests de performance
- [ ] Tests de sécurité
- [ ] Tests de compatibilité
### Scénarios de Test
- Scénario 1
- Scénario 2
- Scénario 3
## 📚 Documentation
### Documentation Requise
- [ ] Guide d'utilisation
- [ ] Documentation API
- [ ] Exemples de code
- [ ] Guide de migration
- [ ] FAQ
## 🔧 Implémentation
### Étapes Proposées
1. **Phase 1** : [Description]
2. **Phase 2** : [Description]
3. **Phase 3** : [Description]
### Estimation de Temps
- **Développement** : X jours/semaines
- **Tests** : X jours/semaines
- **Documentation** : X jours/semaines
- **Total** : X jours/semaines
### Ressources Nécessaires
- Développeur(s)
- Testeur(s)
- Documentateur(s)
- Infrastructure
## 🎯 Critères de Succès
Comment mesurer le succès de cette fonctionnalité ?
- [ ] Critère 1
- [ ] Critère 2
- [ ] Critère 3
## 🔗 Liens Utiles
- [Documentation existante](docs/)
- [Issues similaires](https://git.4nkweb.com/4nk/4NK_node/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement)
- [Roadmap](https://git.4nkweb.com/4nk/4NK_node/projects)
- [Discussions](https://git.4nkweb.com/4nk/4NK_node/issues)
## 📋 Checklist
- [ ] J'ai vérifié que cette fonctionnalité n'existe pas déjà
- [ ] J'ai lu la documentation existante
- [ ] J'ai vérifié les issues similaires
- [ ] J'ai fourni des exemples d'utilisation
- [ ] J'ai considéré l'impact sur l'existant
- [ ] J'ai proposé des tests
---
**Merci de votre contribution à l'amélioration de 4NK Node !** 🌟

View File

@ -1,180 +0,0 @@
# Pull Request - 4NK Node
## 📋 Description
Description claire et concise des changements apportés.
### Type de Changement
- [ ] 🐛 Bug fix
- [ ] ✨ Nouvelle fonctionnalité
- [ ] 📚 Documentation
- [ ] 🧪 Tests
- [ ] 🔧 Refactoring
- [ ] 🚀 Performance
- [ ] 🔒 Sécurité
- [ ] 🎨 Style/UI
- [ ] 🏗️ Architecture
- [ ] 📦 Build/CI
### Composants Affectés
- [ ] Bitcoin Core
- [ ] Blindbit
- [ ] SDK Relay
- [ ] Tor
- [ ] Docker/Infrastructure
- [ ] Tests
- [ ] Documentation
- [ ] Scripts
## 🔗 Issue(s) Liée(s)
Fixes #(issue)
Relates to #(issue)
## 🧪 Tests
### Tests Exécutés
- [ ] Tests unitaires
- [ ] Tests d'intégration
- [ ] Tests de connectivité
- [ ] Tests externes
- [ ] Tests de performance
### Commandes de Test
```bash
# Tests complets
./tests/run_all_tests.sh
# Tests spécifiques
./tests/run_unit_tests.sh
./tests/run_integration_tests.sh
```
### Résultats des Tests
```
Résultats des tests ici
```
## 📸 Captures d'Écran
Si applicable, ajoutez des captures d'écran pour les changements visuels.
## 🔧 Changements Techniques
### Fichiers Modifiés
- `fichier1.rs` - Description des changements
- `fichier2.py` - Description des changements
- `docker-compose.yml` - Description des changements
### Nouveaux Fichiers
- `nouveau_fichier.rs` - Description
- `nouveau_script.sh` - Description
### Fichiers Supprimés
- `ancien_fichier.rs` - Raison de la suppression
### Changements de Configuration
```yaml
# Exemple de changement de configuration
service:
new_option: value
```
## 📚 Documentation
### Documentation Mise à Jour
- [ ] README.md
- [ ] docs/INSTALLATION.md
- [ ] docs/USAGE.md
- [ ] docs/API.md
- [ ] docs/ARCHITECTURE.md
### Nouvelle Documentation
- [ ] Nouveau guide créé
- [ ] Exemples ajoutés
- [ ] API documentée
## 🔍 Code Review Checklist
### Code Quality
- [ ] Le code suit les standards du projet
- [ ] Les noms de variables/fonctions sont clairs
- [ ] Les commentaires sont appropriés
- [ ] Pas de code mort ou commenté
- [ ] Gestion d'erreurs appropriée
### Performance
- [ ] Pas de régression de performance
- [ ] Optimisations appliquées si nécessaire
- [ ] Tests de performance ajoutés
### Sécurité
- [ ] Pas de vulnérabilités introduites
- [ ] Validation des entrées utilisateur
- [ ] Gestion sécurisée des secrets
### Tests
- [ ] Couverture de tests suffisante
- [ ] Tests pour les cas d'erreur
- [ ] Tests d'intégration si nécessaire
### Documentation
- [ ] Code auto-documenté
- [ ] Documentation mise à jour
- [ ] Exemples fournis
## 🚀 Déploiement
### Impact sur le Déploiement
- [ ] Aucun impact
- [ ] Migration de données requise
- [ ] Changement de configuration
- [ ] Redémarrage des services
### Étapes de Déploiement
```bash
# Étapes pour déployer les changements
```
## 📊 Métriques
### Impact sur les Performances
- Temps de réponse : +/- X%
- Utilisation mémoire : +/- X%
- Utilisation CPU : +/- X%
### Impact sur la Stabilité
- Taux d'erreur : +/- X%
- Disponibilité : +/- X%
## 🔄 Compatibilité
### Compatibilité Ascendante
- [ ] Compatible avec les versions précédentes
- [ ] Migration automatique
- [ ] Migration manuelle requise
### Compatibilité Descendante
- [ ] Compatible avec les futures versions
- [ ] API stable
- [ ] Configuration stable
## 🎯 Critères de Succès
- [ ] Critère 1
- [ ] Critère 2
- [ ] Critère 3
## 📝 Notes Supplémentaires
Informations supplémentaires importantes pour les reviewers.
## 🔗 Liens Utiles
- [Documentation](docs/)
- [Tests](tests/)
- [Issues liées](https://git.4nkweb.com/4nk/4NK_node/issues)
---
**Merci pour votre contribution !** 🙏

View File

@ -1,313 +0,0 @@
name: CI - 4NK Node
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
env:
RUST_VERSION: '1.70'
DOCKER_COMPOSE_VERSION: '2.20.0'
jobs:
# Job de vérification du code
code-quality:
name: Code Quality
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_VERSION }}
override: true
- name: Cache Rust dependencies
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Run clippy
run: |
cd sdk_relay
cargo clippy --all-targets --all-features -- -D warnings
- name: Run rustfmt
run: |
cd sdk_relay
cargo fmt --all -- --check
- name: Check documentation
run: |
cd sdk_relay
cargo doc --no-deps
- name: Check for TODO/FIXME
run: |
if grep -r "TODO\|FIXME" . --exclude-dir=.git --exclude-dir=target; then
echo "Found TODO/FIXME comments. Please address them."
exit 1
fi
# Job de tests unitaires
unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_VERSION }}
override: true
- name: Cache Rust dependencies
uses: actions/cache@v3
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Run unit tests
run: |
cd sdk_relay
cargo test --lib --bins
- name: Run integration tests
run: |
cd sdk_relay
cargo test --tests
# Job de tests d'intégration
integration-tests:
name: Integration Tests
runs-on: ubuntu-latest
services:
docker:
image: docker:24.0.5
options: >-
--health-cmd "docker info"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 2375:2375
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build Docker images
run: |
docker build -t 4nk-node-bitcoin ./bitcoin
docker build -t 4nk-node-blindbit ./blindbit
docker build -t 4nk-node-sdk-relay -f ./sdk_relay/Dockerfile ..
- name: Run integration tests
run: |
# Tests de connectivité de base
./tests/run_connectivity_tests.sh || true
# Tests d'intégration
./tests/run_integration_tests.sh || true
- name: Upload test results
uses: actions/upload-artifact@v3
if: always()
with:
name: test-results
path: |
tests/logs/
tests/reports/
retention-days: 7
# Job de tests de sécurité
security-tests:
name: Security Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_VERSION }}
override: true
- name: Run cargo audit
run: |
cd sdk_relay
cargo audit --deny warnings
- name: Check for secrets
run: |
# Vérifier les secrets potentiels
if grep -r "password\|secret\|key\|token" . --exclude-dir=.git --exclude-dir=target --exclude=*.md; then
echo "Potential secrets found. Please review."
exit 1
fi
- name: Check file permissions
run: |
# Vérifier les permissions sensibles
find . -type f -perm /0111 -name "*.conf" -o -name "*.key" -o -name "*.pem" | while read file; do
if [[ $(stat -c %a "$file") != "600" ]]; then
echo "Warning: $file has insecure permissions"
fi
done
# Job de build et test Docker
docker-build:
name: Docker Build & Test
runs-on: ubuntu-latest
services:
docker:
image: docker:24.0.5
options: >-
--health-cmd "docker info"
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 2375:2375
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and test Bitcoin Core
run: |
docker build -t 4nk-node-bitcoin:test ./bitcoin
docker run --rm 4nk-node-bitcoin:test bitcoin-cli --version
- name: Build and test Blindbit
run: |
docker build -t 4nk-node-blindbit:test ./blindbit
docker run --rm 4nk-node-blindbit:test --version || true
- name: Build and test SDK Relay
run: |
docker build -t 4nk-node-sdk-relay:test -f ./sdk_relay/Dockerfile ..
docker run --rm 4nk-node-sdk-relay:test --version || true
- name: Test Docker Compose
run: |
docker-compose config
docker-compose build --no-cache
# Job de tests de documentation
documentation-tests:
name: Documentation Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Check markdown links
run: |
# Vérification basique des liens markdown
find . -name "*.md" -exec grep -l "\[.*\](" {} \; | while read file; do
echo "Checking links in $file"
done
- name: Check documentation structure
run: |
# Vérifier la présence des fichiers de documentation essentiels
required_files=(
"README.md"
"LICENSE"
"CONTRIBUTING.md"
"CHANGELOG.md"
"CODE_OF_CONDUCT.md"
"SECURITY.md"
"docs/INDEX.md"
"docs/INSTALLATION.md"
"docs/USAGE.md"
)
for file in "${required_files[@]}"; do
if [[ ! -f "$file" ]]; then
echo "Missing required documentation file: $file"
exit 1
fi
done
- name: Validate documentation
run: |
# Vérifier la cohérence de la documentation
if ! grep -q "4NK Node" README.md; then
echo "README.md should mention '4NK Node'"
exit 1
fi
# Job de tests de performance
performance-tests:
name: Performance Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: ${{ env.RUST_VERSION }}
override: true
- name: Run performance tests
run: |
cd sdk_relay
cargo test --release --test performance_tests || true
- name: Check memory usage
run: |
# Tests de base de consommation mémoire
echo "Performance tests completed"
# Job de notification
notify:
name: Notify
runs-on: ubuntu-latest
needs: [code-quality, unit-tests, integration-tests, security-tests, docker-build, documentation-tests]
if: always()
steps:
- name: Notify success
if: needs.code-quality.result == 'success' && needs.unit-tests.result == 'success' && needs.integration-tests.result == 'success' && needs.security-tests.result == 'success' && needs.docker-build.result == 'success' && needs.documentation-tests.result == 'success'
run: |
echo "✅ All tests passed successfully!"
- name: Notify failure
if: needs.code-quality.result == 'failure' || needs.unit-tests.result == 'failure' || needs.integration-tests.result == 'failure' || needs.security-tests.result == 'failure' || needs.docker-build.result == 'failure' || needs.documentation-tests.result == 'failure'
run: |
echo "❌ Some tests failed!"
exit 1

3
.gitignore vendored
View File

@ -1,3 +1,6 @@
target/
pkg/
Cargo.lock
node_modules/
dist/
.vscode

258
AGENTS.md
View File

@ -1,258 +0,0 @@
# AGENTS.md
## Table des matières
- [Introduction](#introduction)
- [Agents fondamentaux](#agents-fondamentaux)
- [Agents spécialisés documentation](#agents-spécialisés-documentation)
- [Agents spécialisés tests](#agents-spécialisés-tests)
- [Agents techniques](#agents-techniques)
- [Agents frontend](#agents-frontend)
- [Agents open source et CI](#agents-open-source-et-ci)
- [Agents complémentaires](#agents-complémentaires)
- [Matrice de coordination](#matrice-de-coordination)
- [Conclusion](#conclusion)
---
## Introduction
Ce document définit les agents, leurs rôles et leurs responsabilités dans le projet `4NK/4NK_node`.
Chaque agent est assigné à un périmètre clair (documentation, tests, dépendances, données, CI, gouvernance open source).
Lobjectif est dassurer une maintenance cohérente de larborescence, une traçabilité complète et une exécution fiable des bonnes pratiques.
Les règles détaillées de réalisation et de contrôle sont précisées dans `.cursor/rules/`.
---
## Agents fondamentaux
### Agent Fondation
**Rôle (Responsable)** :
- Garantir que toute production est en français.
- Vérifier labsence dexemples de code applicatif dans la base de code.
- Imposer lintroduction et/ou conclusion dans chaque contenu.
**Artefacts :**
- Tous fichiers.
---
### Agent Structure
**Rôle (Responsable)** :
- Maintenir larborescence canonique du projet.
- Déplacer les documents obsolètes vers `archive/`.
- Bloquer toute suppression non documentée.
**Artefacts :**
- `archive/`, `docs/`, `tests/`, `.gitea/`, `CHANGELOG.md`.
---
## Agents spécialisés documentation
### Agent Documentation
**Rôle (Responsable)** :
- Mettre à jour les fichiers de `docs/` selon limpact des changements.
- Maintenir `INDEX.md` comme table des matières centrale.
- Produire des REX techniques dans `archive/`.
---
### Agent Données CSV
**Rôle (Responsable)** :
- Considérer les CSV comme source de vérité des modèles de données.
- Confirmer la structure et exiger une définition des colonnes.
- Corriger automatiquement les incohérences de type documentées.
---
### Agent Documents bureautiques
**Rôle (Consulté)** :
- Lire les `.docx` via `docx2txt`.
- Proposer des alternatives en cas déchec.
- Documenter les imports dans `INDEX.md`.
---
## Agents spécialisés tests
### Agent Tests
**Rôle (Responsable)** :
- Maintenir la couverture : `unit`, `integration`, `connectivity`, `performance`, `external`.
- Gérer `tests/logs` et `tests/reports`.
- Exiger des tests verts avant commit.
---
### Agent Performance
**Rôle (Consulté)** :
- Conduire des benchmarks reproductibles.
- Vérifier limpact performance avant toute fusion.
---
## Agents techniques
### Agent Dépendances
**Rôle (Responsable)** :
- Ajouter automatiquement les dépendances manquantes.
- Vérifier les dernières versions stables.
- Documenter les changements dans `ARCHITECTURE.md`, `CONFIGURATION.md` et `CHANGELOG.md`.
---
### Agent Compilation
**Rôle (Responsable)** :
- Compiler très régulièrement et à chaque étape critique.
- Bloquer toute progression en présence derreurs.
---
### Agent Résolution
**Rôle (Responsable)** :
- Exécuter systématiquement la boucle de diagnostic (reproduction, logs, bissection, hypothèses, correctif, non-régression).
- Produire un REX en cas dhypothèses multiples.
---
## Agents frontend
### Agent Frontend
**Rôle (Responsable)** :
- Implémenter le code splitting (`React.lazy`, `Suspense`).
- Centraliser létat via Redux ou Context API.
- Créer une couche dabstraction pour les services de données.
---
## Agents open source et CI
### Agent Open Source
**Rôle (Responsable)** :
- Maintenir à jour : `LICENSE`, `CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `OPEN_SOURCE_CHECKLIST.md`.
- Vérifier lalignement continu avec `4NK_node`.
---
### Agent Gitea
**Rôle (Responsable)** :
- Vérifier la présence et lactualité de `.gitea/ISSUE_TEMPLATE/*`, `PULL_REQUEST_TEMPLATE.md`, `.gitea/workflows/ci.yml`.
- Documenter la configuration dans `docs/GITEA_SETUP.md`.
---
### Agent Versionnage
**Rôle (Responsable)** :
- Maintenir `CHANGELOG.md` comme source unique de vérité.
- Proposer un bump semver justifié.
- Demander confirmation avant push et tag.
---
## Agents complémentaires
### Agent Coordination
**Rôle (Accountable)** :
- Vérifier que tous les agents concernés ont bien agi lors dun changement complexe.
- Consolider les validations avant merge.
---
### Agent Qualité / Linting
**Rôle (Responsable)** :
- Appliquer les règles de style, lint et sécurité statique.
- Surveiller la dette technique et laccessibilité.
---
### Agent Release Manager
**Rôle (Responsable)** :
- Superviser le passage dune version à lautre.
- Vérifier la cohérence entre `CHANGELOG.md`, `ROADMAP.md` et les tags Git.
- Déclencher les workflows CI/CD de release.
---
### Agent Sécurité proactive
**Rôle (Responsable)** :
- Surveiller les dépendances vulnérables (CVE, advisories).
- Mettre à jour `SECURITY_AUDIT.md` et notifier lagent Dépendances.
---
### Agent Contributeurs externes
**Rôle (Consulté)** :
- Encadrer la réception de PRs et issues communautaires.
- Veiller au respect de `CODE_OF_CONDUCT.md`.
---
### Agent Documentation communautaire
**Rôle (Responsable)** :
- Sassurer que `COMMUNITY_GUIDE.md` et `OPEN_SOURCE_CHECKLIST.md` sont accessibles, clairs et alignés avec lexpérience contributeurs.
---
## Matrice de coordination
| Type de changement | Agents impliqués | Artefacts principaux | Validation obligatoire |
|--------------------------------|----------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|------------------------|
| Ajout de fonctionnalité | Documentation, Tests, Dépendances, Frontend | API.md, USAGE.md, ARCHITECTURE.md, tests/unit, tests/integration, CHANGELOG.md (*Added*), README.md | Oui |
| Correction de bug | Résolution, Tests, Documentation | tests/unit, TESTING.md, archive/, CHANGELOG.md (*Fixed*) | Oui |
| Refactorisation / amélioration | Structure, Documentation, Compilation | ARCHITECTURE.md, archive/, CHANGELOG.md (*Changed*) | Oui |
| Dépendance ajoutée/mise à jour | Dépendances, Compilation, Documentation | ARCHITECTURE.md, CONFIGURATION.md, CHANGELOG.md (*Dependencies*) | Oui |
| Données CSV modifiées | Données CSV, Documentation, Tests | API.md, ARCHITECTURE.md, USAGE.md, tests/unit, CHANGELOG.md (*Data model update*) | Oui |
| Migration / breaking change | Documentation, Tests, Résolution, Versionnage | MIGRATION.md, INSTALLATION.md, RELEASE_PLAN.md, ROADMAP.md, tests/integration, CHANGELOG.md (*Breaking*)| Oui |
| Sécurité / audit | Documentation, Tests, Open Source, Sécurité proactive | SECURITY_AUDIT.md, tests/external, tests/connectivity, CHANGELOG.md (*Security*) | Oui |
| Préparation open source / CI | Open Source, Gitea, Versionnage, Documentation communautaire, Contributeurs externes | .gitea/**, GITEA_SETUP.md, OPEN_SOURCE_CHECKLIST.md, CHANGELOG.md (*CI/CD* / *Governance*) | Oui |
| Optimisation performance | Performance, Tests, Documentation | tests/performance, tests/reports, ARCHITECTURE.md, CHANGELOG.md (*Performance*) | Oui |
| Évolution frontend | Frontend, Documentation, Tests | ARCHITECTURE.md, USAGE.md, tests/integration, CHANGELOG.md (*Frontend*) | Oui |
---
## Conclusion
Le présent `AGENTS.md` formalise non seulement les rôles et responsabilités, mais également la coordination opérationnelle entre agents pour chaque type de changement.
Grâce à la table des matières, aux agents complémentaires et à la matrice structurée, ce fichier constitue une référence vivante garantissant la cohérence entre code, documentation, tests, dépendances, CI/CD et gouvernance open source.

View File

@ -1,236 +0,0 @@
# Changelog - 4NK Node
Tous les changements notables de ce projet seront documentés dans ce fichier.
Le format est basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/),
et ce projet adhère au [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Infrastructure de tests complète avec organisation par catégorie
- Scripts d'exécution automatisés pour les tests
- Documentation technique complète (Architecture, API)
- Guide de contribution et code de conduite
- Scripts de maintenance et nettoyage automatique
### Changed
- Documentation `sdk_client` alignée au code: API, Architecture, Usage, Testing, Security Audit, README, INDEX
- Réorganisation complète de la structure des tests
- Amélioration de la documentation avec guides détaillés
- Optimisation des scripts de démarrage et redémarrage
### Fixed
- Correction des problèmes de connectivité entre services
- Amélioration de la gestion des erreurs dans les tests
- Correction des configurations Docker
## [0.1.1] - 2025-08-26
### Changed
- Documentation `sdk_client`: révision complète, recentrage périmètre SDK (API, Architecture, Usage, Testing, Security Audit, README, INDEX)
- Build: correction imports `js_sys` et nettoyage dimports orphelins
### Fixed
- Compilation locale validée
## [1.0.0] - 2024-12-19
### Added
- Infrastructure Docker complète pour 4NK Node
- Support des paiements silencieux (Silent Payments) Bitcoin
- Nœud Bitcoin Core configuré en mode signet
- Service Blindbit pour les filtres de paiements silencieux
- Service SDK Relay avec synchronisation mesh
- Service Tor pour l'anonymat
- Configuration multi-relais (3 instances)
- Synchronisation automatique entre relais
- Cache de déduplication des messages
- Healthchecks pour tous les services
- Scripts d'automatisation (démarrage, redémarrage, monitoring)
- Tests de connectivité et d'intégration
- Documentation complète en français
### Features
- **Bitcoin Core** : Nœud signet avec RPC et ZMQ
- **Blindbit** : Service de filtres pour les paiements silencieux
- **SDK Relay** : Relais avec interface WebSocket et synchronisation mesh
- **Tor** : Proxy anonyme pour Bitcoin Core
- **Synchronisation** : Système de synchronisation entre relais
- **Monitoring** : Scripts de monitoring et surveillance
- **Tests** : Suite de tests complète
### Technical
- Architecture Docker avec orchestration via Docker Compose
- Réseau privé `btcnet` pour la communication inter-services
- Volumes persistants pour les données
- Configuration externalisée via fichiers .conf
- Logging structuré avec rotation
- Gestion des erreurs et retry automatique
## [0.9.0] - 2024-12-15
### Added
- Version initiale de l'infrastructure
- Configuration de base des services
- Tests de connectivité simples
- Documentation de base
### Changed
- Configuration initiale des services Docker
- Premiers tests d'intégration
### Fixed
- Problèmes de connectivité initiale
- Configuration des ports et réseaux
## [0.8.0] - 2024-12-10
### Added
- Support de la synchronisation entre relais
- Implémentation du cache de déduplication
- Types de messages de synchronisation
- Gestionnaire de synchronisation (SyncManager)
### Changed
- Amélioration de l'architecture de synchronisation
- Optimisation des performances de synchronisation
### Fixed
- Correction des problèmes de synchronisation
- Amélioration de la stabilité des connexions mesh
## [0.7.0] - 2024-12-05
### Added
- Support des paiements silencieux
- Intégration avec le service Blindbit
- Tests de paiements silencieux
- Documentation des APIs
### Changed
- Amélioration de l'intégration Bitcoin Core
- Optimisation du scan des blocs
### Fixed
- Correction des problèmes de détection des paiements
- Amélioration de la performance du scan
## [0.6.0] - 2024-11-30
### Added
- Interface WebSocket pour SDK Relay
- Support des messages temps réel
- Tests WebSocket
- Documentation de l'API WebSocket
### Changed
- Amélioration de l'interface WebSocket
- Optimisation des performances de communication
### Fixed
- Correction des problèmes de connexion WebSocket
- Amélioration de la gestion des erreurs
## [0.5.0] - 2024-11-25
### Added
- Support de Tor pour l'anonymat
- Configuration du proxy Tor
- Tests de connectivité Tor
- Documentation de la configuration Tor
### Changed
- Amélioration de la configuration réseau
- Optimisation de la connectivité anonyme
### Fixed
- Correction des problèmes de connectivité Tor
- Amélioration de la stabilité du proxy
## [0.4.0] - 2024-11-20
### Added
- Configuration multi-relais
- Support de 3 instances SDK Relay
- Tests multi-relais
- Documentation de la configuration multi-relais
### Changed
- Amélioration de l'orchestration Docker
- Optimisation de la configuration multi-relais
### Fixed
- Correction des problèmes de configuration multi-relais
- Amélioration de la stabilité des instances multiples
## [0.3.0] - 2024-11-15
### Added
- Healthchecks pour tous les services
- Scripts de monitoring
- Tests de santé des services
- Documentation des healthchecks
### Changed
- Amélioration de la surveillance des services
- Optimisation des healthchecks
### Fixed
- Correction des problèmes de healthchecks
- Amélioration de la détection des problèmes
## [0.2.0] - 2024-11-10
### Added
- Service Blindbit
- Intégration avec Bitcoin Core
- Tests d'intégration Blindbit
- Documentation du service Blindbit
### Changed
- Amélioration de l'intégration des services
- Optimisation de la communication inter-services
### Fixed
- Correction des problèmes d'intégration
- Amélioration de la stabilité des services
## [0.1.0] - 2024-11-05
### Added
- Infrastructure Docker de base
- Service Bitcoin Core
- Configuration de base
- Tests de connectivité simples
- Documentation initiale
### Changed
- Configuration initiale des services
- Premiers tests d'intégration
### Fixed
- Problèmes de configuration initiale
- Correction des problèmes de connectivité de base
---
## Types de Changements
- **Added** : Nouvelles fonctionnalités
- **Changed** : Changements dans les fonctionnalités existantes
- **Deprecated** : Fonctionnalités qui seront supprimées
- **Removed** : Fonctionnalités supprimées
- **Fixed** : Corrections de bugs
- **Security** : Améliorations de sécurité
## Contribution
Pour contribuer au changelog, suivez le format existant et ajoutez vos changements dans la section appropriée.
## Liens
- [Documentation](docs/)
- [Guide de Contribution](CONTRIBUTING.md)
- [Issues](https://git.4nkweb.com/4nk/4NK_node/issues)
- [Releases](https://git.4nkweb.com/4nk/4NK_node/releases)

View File

@ -1,93 +0,0 @@
# Code de Conduite - 4NK Node
## Notre Engagement
Dans l'intérêt de favoriser un environnement ouvert et accueillant, nous, en tant que contributeurs et mainteneurs, nous engageons à faire de la participation à notre projet et à notre communauté une expérience sans harcèlement pour tous, peu importe l'âge, la taille, le handicap, l'ethnicité, les caractéristiques sexuelles, l'identité et l'expression de genre, le niveau d'expérience, l'éducation, le statut socio-économique, la nationalité, l'apparence personnelle, la race, la religion ou l'identité et l'orientation sexuelles.
## Nos Standards
Exemples de comportements qui contribuent à créer un environnement positif :
* Utiliser un langage accueillant et inclusif
* Respecter les différents points de vue et expériences
* Accepter gracieusement les critiques constructives
* Se concentrer sur ce qui est le mieux pour la communauté
* Faire preuve d'empathie envers les autres membres de la communauté
Exemples de comportements inacceptables :
* L'utilisation de langage ou d'imagerie sexualisés et d'attention ou d'avances sexuelles non désirées
* Le trolling, les commentaires insultants/désobligeants et les attaques personnelles ou politiques
* Le harcèlement public ou privé
* Publier les informations privées d'autres personnes, telles que des adresses physiques ou électroniques, sans permission explicite
* Autres comportements qui pourraient raisonnablement être considérés comme inappropriés dans un contexte professionnel
## Nos Responsabilités
Les mainteneurs du projet sont responsables de clarifier les standards de comportement acceptable et sont censés prendre des mesures correctives appropriées et équitables en réponse à tout cas de comportement inacceptable.
Les mainteneurs du projet ont le droit et la responsabilité de supprimer, modifier ou rejeter les commentaires, commits, code, modifications de wiki, questions et autres contributions qui ne sont pas alignés avec ce Code de Conduite, et de bannir temporairement ou définitivement tout contributeur pour d'autres comportements qu'ils jugent inappropriés, menaçants, offensants ou nuisibles.
## Portée
Ce Code de Conduite s'applique à la fois dans les espaces du projet et dans les espaces publics lorsqu'un individu représente le projet ou sa communauté. Des exemples de représentation du projet ou de la communauté incluent l'utilisation d'une adresse email officielle du projet, la publication via un compte de média social officiel, ou l'action en tant que représentant désigné lors d'un événement en ligne ou hors ligne. La représentation du projet peut être davantage définie et clarifiée par les mainteneurs du projet.
## Application
Les cas de comportement abusif, harcelant ou autrement inacceptable peuvent être signalés en contactant l'équipe du projet à contact@4nkweb5.com. Toutes les plaintes seront examinées et enquêtées et se traduiront par une réponse jugée nécessaire et appropriée aux circonstances. L'équipe du projet est obligée de maintenir la confidentialité concernant le rapporteur d'un incident. Plus de détails sur les politiques d'application spécifiques peuvent être publiés séparément.
Les mainteneurs du projet qui ne suivent pas ou n'appliquent pas le Code de Conduite de bonne foi peuvent faire face à des répercussions temporaires ou permanentes déterminées par d'autres membres de la direction du projet.
## Attribution
Ce Code de Conduite est adapté du [Contributor Covenant](https://www.contributor-covenant.org), version 2.0, disponible à https://www.contributor-covenant.org/fr/version/2/0/code_of_conduct.html.
## Contact
Pour signaler un problème ou poser des questions concernant ce Code de Conduite, vous pouvez :
* Créer une issue privée sur le repository
* Contacter l'équipe de maintenance via les canaux officiels
* Utiliser les canaux de discussion du projet
## Équipe de Modération
L'équipe de modération est composée des mainteneurs principaux du projet qui s'engagent à :
* Traiter tous les signalements avec impartialité
* Maintenir la confidentialité des rapports
* Prendre des mesures appropriées et équitables
* Documenter les décisions prises
* Améliorer continuellement le processus
## Processus de Signalement
1. **Signalement** : Contactez l'équipe via les canaux appropriés
2. **Accusé de réception** : Vous recevrez une confirmation dans les 48h
3. **Enquête** : L'équipe examinera le signalement
4. **Décision** : Une décision sera prise et communiquée
5. **Appel** : Possibilité de faire appel de la décision
## Mesures Correctives
Les mesures correctives peuvent inclure :
* Avertissement privé
* Avertissement public
* Suspension temporaire
* Bannissement permanent
* Suppression de contenu inapproprié
## Engagement envers l'Amélioration
Nous nous engageons à :
* Réviser régulièrement ce Code de Conduite
* Solliciter les retours de la communauté
* Améliorer les processus de modération
* Former l'équipe de modération
* Maintenir un environnement sain et inclusif
---
**Merci de contribuer à maintenir 4NK Node comme un projet accueillant et inclusif !** 🌟

View File

@ -1,372 +0,0 @@
# Guide de Contribution - 4NK Node
Merci de votre intérêt pour contribuer au projet 4NK Node ! Ce guide vous aidera à comprendre comment participer au développement de cette infrastructure pour les paiements silencieux Bitcoin.
## 📋 Table des Matières
- [🎯 Comment Contribuer](#-comment-contribuer)
- [🚀 Premiers Pas](#-premiers-pas)
- [🔧 Environnement de Développement](#-environnement-de-développement)
- [📝 Processus de Contribution](#-processus-de-contribution)
- [🧪 Tests](#-tests)
- [📚 Documentation](#-documentation)
- [🐛 Signaler un Bug](#-signaler-un-bug)
- [💡 Proposer une Fonctionnalité](#-proposer-une-fonctionnalité)
- [🔍 Code Review](#-code-review)
- [📦 Release](#-release)
## 🎯 Comment Contribuer
### Types de Contributions
Nous accueillons différents types de contributions :
- **🐛 Bug fixes** - Correction de bugs et problèmes
- **✨ Nouvelles fonctionnalités** - Ajout de nouvelles capacités
- **📚 Documentation** - Amélioration de la documentation
- **🧪 Tests** - Ajout ou amélioration des tests
- **🔧 Outils** - Amélioration des scripts et outils
- **🌐 Traductions** - Traduction de la documentation
- **📊 Performance** - Optimisations de performance
- **🔒 Sécurité** - Améliorations de sécurité
### Niveaux de Contribution
- **Débutant** - Documentation, tests, petits bugs
- **Intermédiaire** - Nouvelles fonctionnalités, améliorations
- **Avancé** - Architecture, optimisations majeures
## 🚀 Premiers Pas
### Prérequis
- **Docker** et **Docker Compose** installés
- **Git** configuré
- **Python 3.8+** (pour les tests)
- **Rust** (pour le développement sdk_relay)
- **Connexion Internet** stable
### Fork et Clone
```bash
# 1. Fork le repository sur Gitea
# 2. Clone votre fork
git clone https://git.4nkweb.com/votre-username/4NK_node.git
cd 4NK_node
# 3. Ajouter le repository original comme upstream
git remote add upstream https://git.4nkweb.com/4nk/4NK_node.git
```
### Branches
```bash
# Créer une branche pour votre contribution
git checkout -b feature/nom-de-votre-feature
# ou
git checkout -b fix/nom-du-bug
```
## 🔧 Environnement de Développement
### Installation Locale
```bash
# 1. Cloner le repository
git clone https://git.4nkweb.com/4nk/4NK_node.git
cd 4NK_node
# 2. Démarrer l'infrastructure
./restart_4nk_node.sh
# 3. Vérifier que tout fonctionne
docker ps
```
### Configuration de Développement
```bash
# Variables d'environnement pour le développement
export RUST_LOG=debug
export ENABLE_SYNC_TEST=1
export BITCOIN_NETWORK=signet
```
### Outils de Développement
```bash
# Tests
./tests/run_all_tests.sh
# Linting (si configuré)
cargo clippy
rustfmt src/
# Build
docker-compose build
```
## 📝 Processus de Contribution
### 1. Planifier Votre Contribution
- [ ] Vérifier les issues existantes
- [ ] Créer une issue si nécessaire
- [ ] Discuter de l'approche avec l'équipe
- [ ] Planifier les tests et la documentation
### 2. Développer
- [ ] Créer une branche depuis `main`
- [ ] Développer votre fonctionnalité
- [ ] Ajouter des tests
- [ ] Mettre à jour la documentation
- [ ] Vérifier que les tests passent
### 3. Soumettre
- [ ] Commiter avec des messages clairs
- [ ] Pousser vers votre fork
- [ ] Créer une Pull Request
- [ ] Remplir le template de PR
### Messages de Commit
Utilisez le format conventionnel :
```bash
# Format
type(scope): description
# Exemples
feat(sdk_relay): add new sync type for metrics
fix(bitcoin): resolve connection timeout issue
docs(api): update WebSocket message format
test(integration): add multi-relay sync tests
```
**Types :**
- `feat` - Nouvelle fonctionnalité
- `fix` - Correction de bug
- `docs` - Documentation
- `style` - Formatage
- `refactor` - Refactoring
- `test` - Tests
- `chore` - Maintenance
## 🧪 Tests
### Exécuter les Tests
```bash
# Tous les tests
./tests/run_all_tests.sh
# Tests par catégorie
./tests/run_unit_tests.sh
./tests/run_integration_tests.sh
./tests/run_connectivity_tests.sh
./tests/run_external_tests.sh
# Tests avec debug
./tests/run_all_tests.sh --debug
```
### Ajouter des Tests
```bash
# Structure recommandée
tests/
├── unit/ # Tests unitaires
├── integration/ # Tests d'intégration
├── connectivity/ # Tests de connectivité
├── external/ # Tests externes
└── performance/ # Tests de performance
```
### Bonnes Pratiques
- Testez tous les cas d'usage
- Incluez des tests d'erreur
- Maintenez une couverture > 80%
- Utilisez des données de test réalistes
## 📚 Documentation
### Mise à Jour de la Documentation
```bash
# Structure de la documentation
docs/
├── INSTALLATION.md # Guide d'installation
├── USAGE.md # Guide d'utilisation
├── CONFIGURATION.md # Guide de configuration
├── ARCHITECTURE.md # Architecture technique
├── API.md # Référence API
├── TESTING.md # Guide des tests
└── INDEX.md # Index principal
```
### Standards de Documentation
- Utilisez le Markdown
- Incluez des exemples de code
- Ajoutez des diagrammes si nécessaire
- Maintenez la cohérence du style
- Traduisez en anglais si possible
## 🐛 Signaler un Bug
### Template de Bug Report
```markdown
## Description du Bug
Description claire et concise du problème.
## Étapes pour Reproduire
1. Aller à '...'
2. Cliquer sur '...'
3. Faire défiler jusqu'à '...'
4. Voir l'erreur
## Comportement Attendu
Description de ce qui devrait se passer.
## Comportement Actuel
Description de ce qui se passe actuellement.
## Informations Système
- OS: [ex: Ubuntu 20.04]
- Docker: [ex: 20.10.0]
- Version: [ex: v1.0.0]
## Logs
```
Logs pertinents ici
```
## Capture d'Écran
Si applicable, ajoutez une capture d'écran.
## Contexte Supplémentaire
Toute autre information pertinente.
```
## 💡 Proposer une Fonctionnalité
### Template de Feature Request
```markdown
## Résumé
Description claire et concise de la fonctionnalité souhaitée.
## Motivation
Pourquoi cette fonctionnalité est-elle nécessaire ?
## Proposition
Description détaillée de la fonctionnalité proposée.
## Alternatives Considérées
Autres solutions envisagées.
## Impact
Impact sur les utilisateurs et l'architecture.
## Exemples d'Utilisation
Comment cette fonctionnalité serait-elle utilisée ?
```
## 🔍 Code Review
### Processus de Review
1. **Automatique** - Tests et linting
2. **Review par l'équipe** - Code review manuel
3. **Tests d'intégration** - Validation complète
4. **Approbation** - Merge dans main
### Critères de Review
- [ ] Code fonctionnel et testé
- [ ] Tests ajoutés/modifiés
- [ ] Documentation mise à jour
- [ ] Pas de régression
- [ ] Performance acceptable
- [ ] Sécurité vérifiée
### Répondre aux Reviews
- Répondez poliment aux commentaires
- Apportez les modifications demandées
- Demandez des clarifications si nécessaire
- Re-merguez après les corrections
## 📦 Release
### Processus de Release
1. **Préparation** - Finaliser les fonctionnalités
2. **Tests** - Tests complets
3. **Documentation** - Mise à jour des docs
4. **Tag** - Créer un tag de version
5. **Release** - Publier sur GitHub/GitLab
6. **Annonce** - Communiquer la release
### Numérotation des Versions
Utilisez le [Semantic Versioning](https://semver.org/) :
- **MAJOR** - Changements incompatibles
- **MINOR** - Nouvelles fonctionnalités compatibles
- **PATCH** - Corrections de bugs compatibles
## 🤝 Communauté
### Communication
- **Issues** - Pour les bugs et fonctionnalités
- **Discussions** - Pour les questions générales (via les issues)
- **Pull Requests** - Pour les contributions
- **Wiki** - Pour la documentation collaborative (si activé sur Gitea)
### Code de Conduite
- Soyez respectueux et inclusif
- Écoutez les autres points de vue
- Contribuez de manière constructive
- Respectez les standards du projet
### Reconnaissance
- Les contributeurs sont listés dans le README
- Les contributions significatives sont reconnues
- Les releases mentionnent les contributeurs
## 🆘 Besoin d'Aide ?
- Consultez la [documentation](docs/)
- Vérifiez les [issues existantes](https://git.4nkweb.com/4nk/4NK_node/issues)
- Posez une question via les [issues](https://git.4nkweb.com/4nk/4NK_node/issues/new)
- Contactez l'équipe de maintenance
## 📄 Licence
En contribuant, vous acceptez que vos contributions soient sous la même licence que le projet (MIT).
---
Merci de contribuer à 4NK Node ! 🚀

View File

@ -1,25 +1,5 @@
[package]
name = "sdk_client"
version = "0.1.1"
edition = "2021"
[lib]
name = "sdk_client"
crate-type = ["lib", "cdylib"]
[dependencies]
anyhow = "1.0"
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0"
wasm-bindgen = "0.2.91"
getrandom = { version="0.2.12", features = ["js"] }
wasm-logger = "0.2.0"
rand = "0.8.5"
tsify = { git = "https://github.com/Sosthene00/tsify", branch = "next" }
# sdk_common = { path = "../sdk_common" }
sdk_common = { git = "https://git.4nkweb.com/4nk/sdk_common.git", branch = "dev" }
serde-wasm-bindgen = "0.6.5"
js-sys = "0.3.77"
[dev-dependencies]
wasm-bindgen-test = "0.3"
[workspace]
resolver = "2"
members = [
"crates/sp_client"
]

21
LICENSE
View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2024 4NK Team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

338
README.md
View File

@ -1,317 +1,93 @@
## sdk_client — bibliothèque cliente Silent Payments (WASM)
# sdk_client
Ce dépôt fournit une bibliothèque cliente visant lintégration WebAssembly pour gérer appareil, portefeuille, processus et échanges chiffrés associés aux Silent Payments. Cette documentation renvoie vers `docs/` pour les spécifications détaillées, sans exemples exécutables.
## 📋 Table des Matières
- [🏗️ Architecture](#-architecture)
- [🚀 Démarrage Rapide](#-démarrage-rapide)
- [📚 Documentation](#-documentation)
- [🔧 Configuration](#-configuration)
- [🧪 Tests et Monitoring](#-tests-et-monitoring)
- [🌐 Réseau de Relais](#-réseau-de-relais)
- [🛠️ Développement](#-développement)
- [🚨 Dépannage](#-dépannage)
## Getting started
## 🏗️ Architecture
To make it easy for you to get started with GitLab, here's a list of recommended next steps.
4NK Node est composé de plusieurs services orchestrés via Docker :
Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)!
| Service | Port | Description | Statut |
|---------|------|-------------|---------|
| **Tor** | 9050, 9051 | Proxy anonyme pour Bitcoin Core | ✅ Stable |
| **Bitcoin Core** | 18443 (RPC), 29000 (ZMQ) | Nœud Bitcoin en mode signet | ✅ Stable |
| **Blindbit** | 8000 | Service de filtres pour les paiements silencieux | ✅ Stable |
| **sdk_relay** | 8090-8095 | Services de relais (3 instances) | ✅ Stable |
## Add your files
### 🔄 Flux de Données
- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files
- [ ] [Add files using the command line](https://docs.gitlab.com/ee/gitlab-basics/add-file.html#add-a-file-using-the-command-line) or push an existing Git repository with the following command:
```
Client → sdk_relay → Bitcoin Core
Blindbit → Bitcoin Core
Tor (anonymat)
cd existing_repo
git remote add origin https://git.4nkweb.com/4nk/sdk_client.git
git branch -M main
git push -uf origin main
```
## 🚀 Démarrage Rapide
## Integrate with your tools
### Prérequis
- [ ] [Set up project integrations](https://git.4nkweb.com/4nk/sdk_client/-/settings/integrations)
- **Docker** et **Docker Compose** installés
- **10 Go** d'espace disque minimum
- **Connexion Internet** stable
- **Clé SSH** configurée pour GitLab (recommandé)
## Collaborate with your team
### Installation
- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/)
- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html)
- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically)
- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/)
- [ ] [Set auto-merge](https://docs.gitlab.com/ee/user/project/merge_requests/merge_when_pipeline_succeeds.html)
```bash
# 1. Cloner le repository (SSH recommandé)
git clone git@git.4nkweb.com:4nk/4NK_node.git
cd 4NK_node
## Test and Deploy
# 2. Démarrer tous les services
./restart_4nk_node.sh
Use the built-in continuous integration in GitLab.
# 3. Vérifier le statut
docker ps
```
- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/index.html)
- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/)
- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html)
- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/)
- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html)
### Configuration SSH (Recommandé)
***
```bash
# Générer une clé SSH
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_4nk -C "4nk-automation"
# Editing this README
# Ajouter à l'agent SSH
ssh-add ~/.ssh/id_ed25519_4nk
When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template.
# Configurer Git
git config --global core.sshCommand "ssh -i ~/.ssh/id_ed25519_4nk"
## Suggestions for a good README
# Ajouter la clé publique à GitLab
cat ~/.ssh/id_ed25519_4nk.pub
```
Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information.
## 📚 Documentation
## Name
Choose a self-explaining name for your project.
### 📖 Guides Principaux
## Description
Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors.
- **[Guide d'installation](docs/INSTALLATION.md)**
- **[Guide d'utilisation](docs/USAGE.md)**
- **[Guide de configuration](docs/CONFIGURATION.md)**
- **[Architecture](docs/ARCHITECTURE.md)**
- **[Référence API](docs/API.md)**
## Badges
On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge.
### 🔧 Guides Techniques
## Visuals
Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method.
- **[Architecture Technique](docs/ARCHITECTURE.md)** - Architecture détaillée
- **[API Reference](docs/API.md)** - Documentation des APIs
- **[Sécurité](docs/SECURITY.md)** - Sécurité et bonnes pratiques
- **[Performance](docs/PERFORMANCE.md)** - Optimisation et monitoring
## Installation
Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection.
### 🧪 Guides de Test
## Usage
Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README.
- **[Tests de Base](docs/TESTING.md)** - Tests de connectivité et fonctionnalité
- **[Tests de Synchronisation](docs/SYNC_TESTING.md)** - Tests de synchronisation entre relais
- **[Tests de Performance](docs/PERFORMANCE_TESTING.md)** - Tests de charge et performance
## Support
Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc.
### 🌐 Guides Réseau
## Roadmap
If you have ideas for releases in the future, it is a good idea to list them in the README.
- **[Réseau de Relais](docs/RELAY_NETWORK.md)** - Configuration du réseau mesh
- **[Nœuds Externes](docs/EXTERNAL_NODES.md)** - Ajout et gestion de nœuds externes
- **[Synchronisation](docs/SYNCHRONIZATION.md)** - Protocole de synchronisation
## Contributing
State if you are open to contributions and what your requirements are for accepting them.
## 🔧 Configuration
For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self.
### Services Disponibles
You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser.
| Service | Configuration | Volume | Description |
|---------|---------------|---------|-------------|
| **Bitcoin Core** | `bitcoin/bitcoin.conf` | `bitcoin_data` | Nœud Bitcoin signet avec RPC et ZMQ |
| **Blindbit** | `blindbit/blindbit.toml` | `blindbit_data` | Service de filtres Silent Payments |
| **sdk_relay** | `sdk_relay/.conf.docker.*` | `sdk_relay_*_data` | Relais avec synchronisation mesh |
| **Tor** | `tor/torrc` | - | Proxy anonyme |
## Authors and acknowledgment
Show your appreciation to those who have contributed to the project.
### Variables d'Environnement
## License
For open source projects, say how it is licensed.
```bash
# Logs
RUST_LOG=debug,bitcoincore_rpc=trace
# Bitcoin
BITCOIN_COOKIE_PATH=/home/bitcoin/.bitcoin/signet/.cookie
# Synchronisation
ENABLE_SYNC_TEST=1
```
## 🧪 Tests et Monitoring
### Tests de Base
```bash
# Test de connectivité
./test_final_sync.sh
# Test de synchronisation
./test_sync_logs.sh
# Test des messages WebSocket
python3 test_websocket_messages.py
```
### Monitoring
```bash
# Surveillance de la synchronisation
./monitor_sync.sh
# Logs en temps réel
docker-compose logs -f
# Statut des services
docker ps
```
### Tests de Performance
```bash
# Test de charge WebSocket
python3 test_websocket_messages.py --load-test
# Test de synchronisation
./test_sync_logs.sh continuous
```
## 🌐 Réseau de Relais
### Architecture Mesh
L'infrastructure supporte un réseau mesh de relais avec :
- **3 relais locaux** : `sdk_relay_1`, `sdk_relay_2`, `sdk_relay_3`
- **Nœuds externes** : Configuration via `external_nodes.conf`
- **Synchronisation automatique** : Partage de données entre relais
- **Découverte automatique** : Découverte des relais voisins
### Ajout de Nœuds Externes
```bash
# Ajouter un nœud externe
./add_external_node.sh add external-relay-1 external-relay-1.example.com:8090
# Lister les nœuds configurés
./add_external_node.sh list
# Tester la connectivité
./add_external_node.sh test external-relay-1
```
### Configuration Externe
```toml
# external_nodes.conf
[relays]
external-relay-1 = "external-relay-1.example.com:8090"
dev3-relay = "dev3.4nkweb.com:443"
[discovery]
auto_discover = true
bootstrap_nodes = []
```
## 🛠️ Développement
La surface de code est centrée sur `src/` (Rust) avec export WASM. Les parcours et invariants sont décrits dans `docs/ARCHITECTURE.md` et `docs/API.md`.
### Ajout d'un Nouveau Service
1. Créer le Dockerfile dans un sous-répertoire
2. Ajouter le service dans `docker-compose.yml`
3. Configurer les dépendances et le réseau
4. Ajouter les healthchecks si nécessaire
5. Documenter dans la section appropriée
### Modification de la Configuration
```bash
# Modifier la configuration Bitcoin Core
sudo docker-compose down
# Éditer bitcoin/bitcoin.conf
sudo docker-compose up -d bitcoin
# Modifier la configuration Blindbit
# Éditer blindbit/blindbit.toml
sudo docker-compose restart blindbit
```
## 🚨 Dépannage
### Problèmes Courants
#### 1. Ports Déjà Utilisés
```bash
# Vérifier les ports utilisés
sudo netstat -tlnp | grep -E "(18443|8000|9050|8090)"
# Arrêter les services conflictuels
sudo docker-compose down
```
#### 2. Problèmes de Synchronisation Bitcoin
```bash
# Vérifier les logs Bitcoin Core
sudo docker-compose logs bitcoin
# Redémarrer Bitcoin Core
sudo docker-compose restart bitcoin
```
#### 3. Problèmes de Connectivité sdk_relay
```bash
# Tester la connectivité
cd sdk_relay
./test_final.sh
# Vérifier la configuration
./debug_container.sh
```
### Logs Détaillés
```bash
# Logs avec timestamps
sudo docker-compose logs -t
# Logs des 100 dernières lignes
sudo docker-compose logs --tail=100
# Logs depuis une date
sudo docker-compose logs --since="2024-01-01T00:00:00"
```
### Healthchecks
```bash
# Vérifier l'état des healthchecks
sudo docker-compose ps
# Logs des healthchecks
sudo docker-compose logs | grep health
# Test manuel du healthcheck sdk_relay
sudo docker exec sdk_relay /usr/local/bin/healthcheck.sh
```
## 📈 Performance
Les bonnes pratiques doptimisation, dobservabilité et de limites à la frontière WASM sont présentes dans `docs/ARCHITECTURE.md`.
## 🤝 Contribution
1. Fork le repository
2. Créer une branche feature (`git checkout -b feature/nouvelle-fonctionnalite`)
3. Commit les changements (`git commit -am 'Ajout de nouvelle fonctionnalité'`)
4. Push la branche (`git push origin feature/nouvelle-fonctionnalite`)
5. Créer une Pull Request
## 📄 Licence
Ce projet est sous licence MIT. Voir le fichier LICENSE pour plus de détails.
## 🆘 Support
Pour obtenir de l'aide :
1. Consulter la [documentation](docs/)
2. Vérifier les [issues existantes](https://git.4nkweb.com/4nk/4NK_node/issues)
3. Créer une nouvelle issue avec les détails du problème
4. Inclure les logs et la configuration utilisée
---
**Documentation de référence: voir `docs/` pour la table des matières.**
## Project status
If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers.

View File

@ -1,232 +0,0 @@
# Politique de Sécurité - 4NK Node
## 🛡️ Signalement de Vulnérabilités
Nous prenons la sécurité très au sérieux. Si vous découvrez une vulnérabilité de sécurité, nous vous demandons de la signaler de manière responsable.
### Comment Signaler une Vulnérabilité
**NE PAS** créer d'issue publique pour les vulnérabilités de sécurité.
**À la place :**
1. Envoyez un email à [security@4nkweb.com](mailto:security@4nkweb.com)
2. Incluez "SECURITY VULNERABILITY" dans l'objet
3. Décrivez la vulnérabilité de manière détaillée
4. Incluez les étapes pour reproduire le problème
5. Proposez une solution si possible
### Ce que nous attendons
- **Confidentialité** : Ne divulguez pas la vulnérabilité publiquement
- **Détails** : Fournissez suffisamment d'informations pour reproduire le problème
- **Patience** : Nous examinerons et répondrons dans les 48h
- **Coopération** : Nous pouvons avoir besoin de clarifications
### Ce que vous pouvez attendre
- **Réponse rapide** : Accusé de réception dans les 48h
- **Évaluation** : Analyse de la vulnérabilité
- **Mise à jour** : Statut de la correction
- **Reconnaissance** : Mention dans les remerciements (si souhaité)
## 🔒 Bonnes Pratiques de Sécurité
### Pour les Contributeurs
#### Code
- Validez toutes les entrées utilisateur
- Utilisez des requêtes préparées pour les bases de données
- Évitez les injections de code
- Implémentez l'authentification appropriée
- Utilisez HTTPS pour toutes les communications
#### Configuration
- Ne committez jamais de secrets
- Utilisez des variables d'environnement pour les données sensibles
- Vérifiez les permissions des fichiers
- Maintenez les dépendances à jour
#### Tests
- Incluez des tests de sécurité
- Testez les cas limites
- Validez les entrées malveillantes
- Vérifiez les fuites de mémoire
### Pour les Utilisateurs
#### Installation
- Utilisez des sources officielles
- Vérifiez les checksums
- Maintenez le système à jour
- Utilisez un pare-feu
#### Configuration
- Changez les mots de passe par défaut
- Utilisez des clés SSH fortes
- Limitez l'accès réseau
- Surveillez les logs
#### Opération
- Surveillez les connexions
- Sauvegardez régulièrement
- Testez les sauvegardes
- Documentez les incidents
## 🔍 Audit de Sécurité
### Composants Principaux
#### Bitcoin Core
- **RPC Interface** : Authentification requise
- **ZMQ** : Communication locale uniquement
- **P2P** : Validation des blocs
- **Wallet** : Chiffrement des clés
#### Blindbit
- **API HTTP** : Validation des entrées
- **Filtres** : Vérification des signatures
- **Cache** : Protection contre les attaques DoS
- **Logs** : Pas d'informations sensibles
#### SDK Relay
- **WebSocket** : Validation des messages
- **Synchronisation** : Authentification des pairs
- **Cache** : Protection contre les attaques
- **Configuration** : Validation des paramètres
#### Tor
- **Proxy** : Configuration sécurisée
- **Contrôle** : Accès restreint
- **Logs** : Anonymisation
- **Mise à jour** : Versions récentes
### Tests de Sécurité
#### Tests Automatisés
```bash
# Tests de sécurité
./tests/run_security_tests.sh
# Vérification des vulnérabilités
./tests/check_vulnerabilities.sh
# Audit des dépendances
./tests/audit_dependencies.sh
```
#### Tests Manuels
- Tests de pénétration
- Audit de code
- Tests de configuration
- Tests de performance sous charge
## 🚨 Réponse aux Incidents
### Procédure d'Urgence
1. **Détection** : Identifier l'incident
2. **Containment** : Limiter l'impact
3. **Éradication** : Supprimer la cause
4. **Récupération** : Restaurer les services
5. **Post-mortem** : Analyser et améliorer
### Communication
- **Interne** : Équipe de sécurité
- **Utilisateurs** : Notification appropriée
- **Communauté** : Disclosure responsable
- **Autorités** : Si nécessaire
### Documentation
- **Incident Report** : Détails de l'incident
- **Timeline** : Chronologie des événements
- **Actions** : Mesures prises
- **Lessons Learned** : Améliorations
## 📋 Checklist de Sécurité
### Avant le Déploiement
- [ ] Audit de code de sécurité
- [ ] Tests de vulnérabilités
- [ ] Vérification des dépendances
- [ ] Configuration sécurisée
- [ ] Tests de charge
### Pendant l'Opération
- [ ] Monitoring de sécurité
- [ ] Surveillance des logs
- [ ] Mise à jour des composants
- [ ] Sauvegarde des données
- [ ] Tests de récupération
### Après un Incident
- [ ] Analyse post-mortem
- [ ] Mise à jour des procédures
- [ ] Formation de l'équipe
- [ ] Amélioration des outils
- [ ] Communication à la communauté
## 🔧 Outils de Sécurité
### Monitoring
- **Logs** : Centralisation et analyse
- **Métriques** : Surveillance en temps réel
- **Alertes** : Notification automatique
- **Tableaux de bord** : Vue d'ensemble
### Tests
- **SAST** : Analyse statique
- **DAST** : Tests dynamiques
- **IAST** : Tests interactifs
- **Fuzzing** : Tests de robustesse
### Protection
- **WAF** : Pare-feu applicatif
- **IDS/IPS** : Détection d'intrusion
- **Antivirus** : Protection des endpoints
- **Chiffrement** : Protection des données
## 📚 Ressources
### Documentation
- [Guide de Sécurité Bitcoin](https://bitcoin.org/en/security)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [CWE/SANS Top 25](https://cwe.mitre.org/top25/)
- [NIST Cybersecurity Framework](https://www.nist.gov/cyberframework)
### Outils
- [Bandit](https://bandit.readthedocs.io/) - Analyse Python
- [Clang Static Analyzer](https://clang-analyzer.llvm.org/) - Analyse C/C++
- [SonarQube](https://www.sonarqube.org/) - Qualité du code
- [OpenVAS](https://www.openvas.org/) - Scan de vulnérabilités
### Formation
- Cours de sécurité applicative
- Formation aux tests de pénétration
- Certification en cybersécurité
- Participation à des CTF
## 🤝 Collaboration
### Bug Bounty
- Programme de récompenses pour les vulnérabilités
- Critères d'éligibilité
- Montants des récompenses
- Processus de validation
### Responsible Disclosure
- Timeline de divulgation
- Coordination avec les chercheurs
- Communication publique
- Remerciements
### Communauté
- Groupe de sécurité
- Discussions techniques
- Partage d'informations
- Collaboration avec d'autres projets
---
**La sécurité est une responsabilité partagée. Merci de contribuer à maintenir 4NK Node sécurisé !** 🔒

View File

@ -0,0 +1,27 @@
[package]
name = "sdk_client"
version = "0.1.0"
edition = "2021"
[lib]
name = "sdk_client"
crate-type = ["cdylib"]
[dependencies]
anyhow = "1.0"
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0"
wasm-bindgen = "0.2.91"
getrandom = { version="0.2.12", features = ["js"] }
wasm-logger = "0.2.0"
rand = "0.8.5"
log = "0.4.6"
tsify = { git = "https://github.com/Sosthene00/tsify", branch = "next" }
# sdk_common = { path = "../../../sdk_common" }
# sdk_common = { git = "https://git.4nkweb.com/4nk/sdk_common.git", branch = "demo" }
sdk_common = { git = "https://git.4nkweb.com/4nk/sdk_common.git", branch = "dev" }
shamir = { git = "https://github.com/Sosthene00/shamir", branch = "master" }
img-parts = "0.3.0"
[dev-dependencies]
wasm-bindgen-test = "0.3"

1033
crates/sp_client/src/api.rs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,38 @@
use anyhow::{Error, Result};
use img_parts::{jpeg::Jpeg, Bytes, ImageEXIF};
use sdk_common::sp_client::bitcoin::secp256k1::SecretKey;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BackUpImage(Vec<u8>);
impl BackUpImage {
pub fn new_recover(image: Vec<u8>, data: &[u8]) -> Result<Self> {
// TODO: sanity check on data
let img = write_exif(image, data)?;
Ok(Self(img))
}
pub fn new_revoke(image: Vec<u8>, data: &[u8]) -> Result<Self> {
// TODO: sanity check on data
let img = write_exif(image, data)?;
Ok(Self(img))
}
pub fn to_inner(&self) -> Vec<u8> {
self.0.clone()
}
pub fn as_inner(&self) -> &[u8] {
&self.0
}
}
fn write_exif(image: Vec<u8>, data: &[u8]) -> Result<Vec<u8>> {
let mut jpeg = Jpeg::from_bytes(Bytes::from(image))?;
let data_bytes = Bytes::from(data.to_owned());
jpeg.set_exif(Some(data_bytes));
let output_image_bytes = jpeg.encoder().bytes();
let output_image = output_image_bytes.to_vec();
Ok(output_image)
}

View File

@ -0,0 +1,34 @@
#![allow(warnings)]
use anyhow::Error;
use sdk_common::crypto::AnkSharedSecret;
use sdk_common::network::CachedMessage;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::fmt::Debug;
use std::sync::{Mutex, MutexGuard, OnceLock};
use tsify::Tsify;
pub mod api;
mod images;
mod peers;
mod process;
mod user;
pub static CACHEDMESSAGES: OnceLock<Mutex<Vec<CachedMessage>>> = OnceLock::new();
pub fn lock_messages() -> Result<MutexGuard<'static, Vec<CachedMessage>>, Error> {
CACHEDMESSAGES
.get_or_init(|| Mutex::new(vec![]))
.lock_anyhow()
}
pub(crate) trait MutexExt<T> {
fn lock_anyhow(&self) -> Result<MutexGuard<T>, Error>;
}
impl<T: Debug> MutexExt<T> for Mutex<T> {
fn lock_anyhow(&self) -> Result<MutexGuard<T>, Error> {
self.lock()
.map_err(|e| Error::msg(format!("Failed to lock: {}", e)))
}
}

View File

@ -0,0 +1,405 @@
use std::fmt::DebugStruct;
use sdk_common::sp_client::silentpayments::sending::SilentPaymentAddress;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use tsify::Tsify;
use wasm_bindgen::prelude::*;
pub const HTML_KOTPART: &str = "
<div class='card'>
<div class='side-by-side'>
<h3>Send encrypted messages</h3>
<div>
<a href='#' id='send messages'>Send Messages</a>
</div>
</div>
<form id='form4nk' action='#'>
<label for='sp_address'>Send to:</label>
<input type='text' id='sp_address' />
<hr/>
<label for='message'>Message:</label>
<input type='message' id='message' />
<hr/>
<button type='submit' id='submitButton' class='recover bg-primary'>Send</button>
</form>
</div>
";
pub const HTML_STORAGE: &str = "
<div class='card'>
<div class='side-by-side'>
<h3>Send encrypted messages</h3>
<div>
<a href='#' id='send messages'>Send Messages</a>
</div>
</div>
<form id='form4nk' action='#'>
<label for='sp_address'>Send to:</label>
<input type='text' id='sp_address' />
<hr/>
<label for='message'>Message:</label>
<input type='message' id='message' />
<hr/>
<button type='submit' id='submitButton' class='recover bg-primary'>Send</button>
</form>
</div>
";
pub const HTML_MESSAGING: &str = "
<div class='card'>
<div class='side-by-side'>
<h3>Send encrypted messages</h3>
<div>
<a href='#' id='send messages'>Send Messages</a>
</div>
</div>
<form id='form4nk' action='#'>
<div id='our_address' class='our_address'></div>
<label for='sp_address'>Send to:</label>
<input type='text' id='sp_address' />
<hr/>
<label for='message'>Message:</label>
<input type='message' id='message' />
<hr/>
<button type='submit' id='submitButton' class='recover bg-primary'>Send</button>
</form>
</div>
";
pub const CSS: &str = "
body {
margin: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f4f4f4;
font-family: 'Arial', sans-serif;
}
.container {
text-align: center;
}
.card {
max-width: 400px;
width: 100%;
padding: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background-color: #ffffff;
border-radius: 8px;
text-align: left;
overflow: hidden;
}
form {
display: flex;
flex-direction: column;
/* flex-wrap: wrap; */
}
label {
font-weight: bold;
margin-bottom: 8px;
}
hr {
border: 0;
height: 1px;
background-color: #ddd;
margin: 10px 0;
}
input, select {
width: 100%;
padding: 10px;
margin: 8px 0;
box-sizing: border-box;
}
select {
padding: 10px;
background-color: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
}
button {
display: inline-block;
background-color: #4caf50;
color: #fff;
border: none;
padding: 12px 17px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
.side-by-side {
display: flex;
align-items: center;
justify-content: space-between;
}
.side-by-side>* {
display: inline-block;
}
button.recover {
display: inline-block;
text-align: center;
text-decoration: none;
display: inline-block;
background-color: #4caf50;
color: #fff;
border: none;
padding: 12px 17px;
border-radius: 4px;
cursor: pointer;
}
button.recover:hover {
background-color: #45a049;
}
a.btn {
display: inline-block;
text-align: center;
text-decoration: none;
display: inline-block;
background-color: #4caf50;
color: #fff;
border: none;
padding: 12px 17px;
border-radius: 4px;
cursor: pointer;
}
a.btn:hover {
background-color: #45a049;
}
a {
text-decoration: none;
color: #78a6de;
}
.bg-secondary {
background-color: #2b81ed;
}
.bg-primary {
background-color: #1A61ED;
}
.bg-primary:hover {
background-color: #457be8;
}
.card-revoke {
display: flex;
flex-direction: column;
max-width: 400px;
width: 100%;
padding: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background-color: #ffffff;
border-radius: 8px;
text-align: center;
align-items: center;
overflow: hidden;
}
.card-revoke a {
max-width: 50px;
width: 100%;
background: none;
border: none;
cursor: pointer;
}
.card-revoke button {
max-width: 200px;
width: 100%;
background: none;
border: none;
cursor: pointer;
color: #78a6de;
}
.card-revoke svg {
width: 100%;
height: auto;
fill: #333;
}
.image-label {
display: block;
color: #fff;
padding: 5px;
margin-top: 10px;
}
.image-container {
width: 400px;
height: 300px;
overflow: hidden;
}
.image-container img {
text-align: center;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center center;
}
.passwordalert {
color: #FF0000;
}
";
pub const CSSUPDATE: &str = "
<style>
body {
margin: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f4f4f4;
font-family: 'Arial', sans-serif;
}
.container {
max-width: 400px;
width: 100%;
padding: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background-color: #ffffff;
border-radius: 8px;
text-align: left;
overflow: hidden;
}
form {
display: grid;
grid-template-columns: repeat(1fr, 2fr);
gap: 10px;
max-width: 400px;
margin: auto;
}
.bg-primary {
background-color: #1a61ed;
}
.bg-primary:hover {
background-color: #457be8;
}
.bg-secondary {
background-color: #2b81ed;
}
.bg-secondary:hover {
background-color: #5f9bff;
}
label {
text-align: left;
padding-right: 10px;
line-height: 2;
}
input {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
button {
grid-column: span 2;
display: inline-block;
color: #fff;
border: none;
padding: 12px 17px;
border-radius: 4px;
cursor: pointer;
}
.div-text-area {
grid-column: span 2;
}
textarea {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
.side-by-side {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
margin-bottom: 5px;
}
.circle-btn {
width: 25px;
height: 25px;
border-radius: 50%;
border: none;
color: white;
padding: 0px;
text-align: center;
}
#fileInput {
width: 100%;
padding: 8px;
padding-left: 0px;
box-sizing: border-box;
}
</style>
";
pub const JSUPDATE: &str = "
var addSpAddressBtn = document.getElementById('add-sp-address-btn');
var removeSpAddressBtn = document.querySelectorAll('.minus-sp-address-btn');
addSpAddressBtn.addEventListener('click', function (event) {
addDynamicField(this);
});
function addDynamicField(element) {
var addSpAddressBlock = document.getElementById('sp-address-block');
var spAddress = addSpAddressBlock.querySelector('#sp-address').value;
addSpAddressBlock.querySelector('#sp-address').value = '';
spAddress = spAddress.trim();
if (spAddress != '') {
var sideBySideDiv = document.createElement('div');
sideBySideDiv.className = 'side-by-side';
var inputElement = document.createElement('input');
inputElement.type = 'text';
inputElement.name = 'spAddresses[]';
inputElement.setAttribute('form', 'no-form');
inputElement.value = spAddress;
inputElement.disabled = true;
var buttonElement = document.createElement('button');
buttonElement.type = 'button';
buttonElement.className =
'circle-btn bg-secondary minus-sp-address-btn';
buttonElement.innerHTML = '-';
buttonElement.addEventListener('click', function (event) {
removeDynamicField(this.parentElement);
});
sideBySideDiv.appendChild(inputElement);
sideBySideDiv.appendChild(buttonElement);
addSpAddressBlock.appendChild(sideBySideDiv);
}
function removeDynamicField(element) {
element.remove();
}
}
";
#[derive(Debug, Serialize, Deserialize, Default, Tsify)]
#[tsify(into_wasm_abi, from_wasm_abi)]
pub struct Process {
pub id: u32,
pub name: String,
pub version: String,
pub members: Vec<String>,
pub html: String,
pub style: String,
pub script: String,
// Add conditions : process, member, peer, artefact
}

View File

@ -0,0 +1,544 @@
use anyhow::{Error, Result};
use rand::{self, thread_rng, Rng, RngCore};
use sdk_common::sp_client::bitcoin::hashes::Hash;
use sdk_common::sp_client::bitcoin::hashes::HashEngine;
use sdk_common::sp_client::bitcoin::hex::{DisplayHex, FromHex};
use sdk_common::sp_client::bitcoin::secp256k1::SecretKey;
use sdk_common::sp_client::bitcoin::secp256k1::ThirtyTwoByteHash;
use sdk_common::sp_client::spclient::SpClient;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use tsify::Tsify;
use wasm_bindgen::prelude::*;
use shamir::SecretData;
use std::collections::HashMap;
use std::fs::File;
use std::io::{Cursor, Read, Write};
use std::str::FromStr;
use std::sync::{Mutex, MutexGuard, OnceLock};
use sdk_common::sp_client::bitcoin::secp256k1::constants::SECRET_KEY_SIZE;
use sdk_common::sp_client::silentpayments::bitcoin_hashes::sha256;
use sdk_common::sp_client::silentpayments::sending::SilentPaymentAddress;
use sdk_common::sp_client::spclient::SpendKey;
use sdk_common::sp_client::spclient::{OutputList, SpWallet};
use crate::peers::Peer;
use crate::user;
use crate::MutexExt;
use sdk_common::crypto::{
AeadCore, Aes256Decryption, Aes256Encryption, Aes256Gcm, HalfKey, KeyInit, Purpose,
};
type PreId = String;
const MANAGERS_NUMBER: u8 = 10;
const QUORUM_SHARD: f32 = 0.8;
pub static CONNECTED_USER: OnceLock<Mutex<UserWallets>> = OnceLock::new();
pub fn lock_connected_user() -> Result<MutexGuard<'static, UserWallets>> {
CONNECTED_USER
.get_or_init(|| Mutex::new(UserWallets::default()))
.lock_anyhow()
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct UserWallets {
main: Option<SpWallet>,
recover: Option<SpWallet>,
revoke: Option<SpWallet>,
}
impl UserWallets {
pub fn new(
main: Option<SpWallet>,
recover: Option<SpWallet>,
revoke: Option<SpWallet>,
) -> Self {
Self {
main,
recover,
revoke,
}
}
pub fn try_get_revoke(&self) -> Result<&SpWallet> {
if let Some(revoke) = &self.revoke {
Ok(revoke)
} else {
Err(Error::msg("No revoke wallet available"))
}
}
pub fn try_get_recover(&self) -> Result<&SpWallet> {
if let Some(recover) = &self.recover {
Ok(recover)
} else {
Err(Error::msg("No recover wallet available"))
}
}
pub fn try_get_main(&self) -> Result<&SpWallet> {
if let Some(main) = &self.main {
Ok(main)
} else {
Err(Error::msg("No main wallet available"))
}
}
pub fn try_get_mut_revoke(&mut self) -> Result<&mut SpWallet> {
if let Some(revoke) = &mut self.revoke {
Ok(revoke)
} else {
Err(Error::msg("No revoke wallet available"))
}
}
pub fn try_get_mut_recover(&mut self) -> Result<&mut SpWallet> {
if let Some(recover) = &mut self.recover {
Ok(recover)
} else {
Err(Error::msg("No recover wallet available"))
}
}
pub fn try_get_mut_main(&mut self) -> Result<&mut SpWallet> {
if let Some(main) = &mut self.main {
Ok(main)
} else {
Err(Error::msg("No main wallet available"))
}
}
pub(crate) fn is_not_empty(&self) -> bool {
self.get_all_outputs().len() > 0
}
pub(crate) fn get_all_outputs(&self) -> Vec<OutputList> {
let mut res = Vec::<OutputList>::new();
if let Some(main) = &self.main {
res.push(main.get_outputs().clone());
}
if let Some(revoke) = &self.revoke {
res.push(revoke.get_outputs().clone());
}
if let Some(recover) = &self.recover {
res.push(recover.get_outputs().clone());
}
res
}
}
#[derive(Debug, Serialize, Deserialize, Clone, Tsify)]
#[tsify(into_wasm_abi, from_wasm_abi)]
pub struct User {
pub pre_id: PreId,
pub processes: Vec<String>,
pub peers: Vec<Peer>,
recover_data: Vec<u8>,
revoke_data: Option<Vec<u8>>,
shares: Vec<Vec<u8>>,
outputs: Vec<OutputList>,
}
impl User {
pub fn new(user_wallets: UserWallets, user_password: String, process: String) -> Result<Self> {
// if we are already logged in, abort
if lock_connected_user()?.is_not_empty() {
return Err(Error::msg("User already logged in"));
}
let mut rng = thread_rng();
// image revoke
// We just take the 2 revoke keys
let mut revoke_data = Vec::with_capacity(64);
let revoke = user_wallets.try_get_revoke()?;
revoke_data.extend_from_slice(revoke.get_client().get_scan_key().as_ref());
revoke_data.extend_from_slice(revoke.get_client().try_get_secret_spend_key()?.as_ref());
// Take the 2 recover keys
// split recover spend key
let recover_spend_key = user_wallets
.try_get_recover()?
.get_client()
.try_get_secret_spend_key()?
.clone();
let (part1_key, part2_key) = recover_spend_key.as_ref().split_at(SECRET_KEY_SIZE / 2);
let mut recover_data = Vec::<u8>::with_capacity(180); // 32 * 3 + (12+16)*3
// generate 3 tokens of 32B entropy
let mut entropy_1: [u8; 32] = Aes256Gcm::generate_key(&mut rng).into();
let mut entropy_2: [u8; 32] = Aes256Gcm::generate_key(&mut rng).into();
let mut entropy_3: [u8; 32] = Aes256Gcm::generate_key(&mut rng).into();
recover_data.extend_from_slice(&entropy_1);
recover_data.extend_from_slice(&entropy_2);
recover_data.extend_from_slice(&entropy_3);
// hash the concatenation
let mut engine = sha256::HashEngine::default();
engine.write_all(&user_password.as_bytes());
engine.write_all(&entropy_1);
let hash1 = sha256::Hash::from_engine(engine);
// take it as a AES key
let part1_encryption = Aes256Encryption::import_key(
Purpose::Login,
part1_key.to_vec(),
hash1.to_byte_array(),
Aes256Gcm::generate_nonce(&mut rng).into(),
)?;
// encrypt the part1 of the key
let cipher_recover_part1 = part1_encryption.encrypt_with_aes_key()?;
recover_data.extend_from_slice(&cipher_recover_part1);
//Pre ID
let pre_id: PreId = Self::compute_pre_id(&user_password, &cipher_recover_part1);
// encrypt the part 2 of the key
let mut engine = sha256::HashEngine::default();
engine.write_all(&user_password.as_bytes());
engine.write_all(&entropy_2);
let hash2 = sha256::Hash::from_engine(engine);
// take it as a AES key
let part2_encryption = Aes256Encryption::import_key(
Purpose::Login,
part2_key.to_vec(),
hash2.to_byte_array(),
Aes256Gcm::generate_nonce(&mut rng).into(),
)?;
// encrypt the part2 of the key
let cipher_recover_part2 = part2_encryption.encrypt_with_aes_key()?;
//create shardings
let threshold = (MANAGERS_NUMBER as f32 * QUORUM_SHARD).floor();
debug_assert!(threshold > 0.0 && threshold <= u8::MAX as f32);
let sharding = shamir::SecretData::with_secret(
&cipher_recover_part2.to_lower_hex_string(),
threshold as u8,
);
let shares: Vec<Vec<u8>> = (1..MANAGERS_NUMBER)
.map(|x| {
sharding.get_share(x).unwrap() // Let's trust it for now
})
.collect();
//scan key:
let mut engine = sha256::HashEngine::default();
engine.write_all(&user_password.as_bytes());
engine.write_all(&entropy_3);
let hash3 = sha256::Hash::from_engine(engine);
let scan_key_encryption = Aes256Encryption::import_key(
Purpose::ThirtyTwoBytes,
user_wallets
.try_get_recover()?
.get_client()
.get_scan_key()
.secret_bytes()
.to_vec(),
hash3.to_byte_array(),
Aes256Gcm::generate_nonce(&mut rng).into(),
)?;
// encrypt the scan key
let cipher_scan_key = scan_key_encryption.encrypt_with_aes_key()?;
recover_data.extend_from_slice(&cipher_scan_key);
let all_outputs = user_wallets.get_all_outputs();
Ok(User {
pre_id: pre_id.to_string(),
processes: vec![process],
peers: vec![],
recover_data,
revoke_data: Some(revoke_data),
shares,
outputs: all_outputs,
})
}
pub fn logout() -> Result<()> {
if let Ok(mut user) = lock_connected_user() {
*user = UserWallets::default();
Ok(())
} else {
Err(Error::msg("Failed to lock CONNECTED_USER"))
}
}
pub fn login(
pre_id: PreId,
user_password: String,
recover_data: &[u8],
shares: &[Vec<u8>],
outputs: &[OutputList],
) -> Result<()> {
// if we are already logged in, abort
if lock_connected_user()?.is_not_empty() {
return Err(Error::msg("User already logged in"));
}
let mut retrieved_spend_key = [0u8; 32];
let mut retrieved_scan_key = [0u8; 32];
let mut entropy1 = [0u8; 32];
let mut entropy2 = [0u8; 32];
let mut entropy3 = [0u8; 32];
let mut cipher_scan_key = [0u8; 60]; // cipher length == plain.len() + 16 + nonce.len()
let mut part1_ciphertext = [0u8; 44];
let mut reader = Cursor::new(recover_data);
reader.read_exact(&mut entropy1)?;
reader.read_exact(&mut entropy2)?;
reader.read_exact(&mut entropy3)?;
reader.read_exact(&mut part1_ciphertext)?;
reader.read_exact(&mut cipher_scan_key)?;
// We can retrieve the pre_id and check that it matches
let retrieved_pre_id = Self::compute_pre_id(&user_password, &part1_ciphertext);
// If pre_id is not the same, password is probably false, or the client is feeding us garbage
if retrieved_pre_id != pre_id {
return Err(Error::msg("pre_id and recover_data don't match"));
}
retrieved_spend_key[..16].copy_from_slice(&Self::recover_part1(
&user_password,
&entropy1,
part1_ciphertext.to_vec(),
)?);
retrieved_spend_key[16..].copy_from_slice(&Self::recover_part2(
&user_password,
&entropy2,
shares,
)?);
retrieved_scan_key.copy_from_slice(&Self::recover_key_slice(
&user_password,
&entropy3,
cipher_scan_key.to_vec(),
)?);
// we can create the recover sp_client
let recover_client = SpClient::new(
"".to_owned(),
SecretKey::from_slice(&retrieved_scan_key)?,
SpendKey::Secret(SecretKey::from_slice(&retrieved_spend_key)?),
None,
true,
)?;
let recover_outputs = outputs
.iter()
.find(|o| o.check_fingerprint(&recover_client))
.cloned();
let recover_wallet = SpWallet::new(recover_client, recover_outputs)?;
let user_wallets = UserWallets::new(None, Some(recover_wallet), None);
if let Ok(mut user) = lock_connected_user() {
*user = user_wallets;
} else {
return Err(Error::msg("Failed to lock CONNECTED_USER"));
}
Ok(())
}
fn recover_key_slice(password: &str, entropy: &[u8], ciphertext: Vec<u8>) -> Result<Vec<u8>> {
let mut engine = sha256::HashEngine::default();
engine.write_all(&password.as_bytes());
engine.write_all(&entropy);
let hash = sha256::Hash::from_engine(engine);
let aes_dec =
Aes256Decryption::new(Purpose::ThirtyTwoBytes, ciphertext, hash.to_byte_array())?;
aes_dec.decrypt_with_key()
}
fn recover_part1(password: &str, entropy: &[u8], ciphertext: Vec<u8>) -> Result<Vec<u8>> {
let mut engine = sha256::HashEngine::default();
engine.write_all(&password.as_bytes());
engine.write_all(&entropy);
let hash = sha256::Hash::from_engine(engine);
let aes_dec = Aes256Decryption::new(Purpose::Login, ciphertext, hash.to_byte_array())?;
aes_dec.decrypt_with_key()
}
fn recover_part2(password: &str, entropy: &[u8], shares: &[Vec<u8>]) -> Result<Vec<u8>> {
let mut engine = sha256::HashEngine::default();
engine.write_all(&password.as_bytes());
engine.write_all(&entropy);
let hash = sha256::Hash::from_engine(engine);
let threshold = (MANAGERS_NUMBER as f32 * QUORUM_SHARD).floor();
debug_assert!(threshold > 0.0 && threshold <= u8::MAX as f32);
let part2_key_enc = Vec::from_hex(
&SecretData::recover_secret(threshold as u8, shares.to_vec())
.ok_or_else(|| anyhow::Error::msg("Failed to retrieve the sharded secret"))?,
)?;
let aes_dec = Aes256Decryption::new(Purpose::Login, part2_key_enc, hash.to_byte_array())?;
aes_dec.decrypt_with_key()
}
fn compute_pre_id(user_password: &str, cipher_recover_part1: &[u8]) -> PreId {
let mut engine = sha256::HashEngine::default();
engine.write_all(&user_password.as_bytes());
engine.write_all(&cipher_recover_part1);
let pre_id = sha256::Hash::from_engine(engine);
pre_id.to_string()
}
//not used
// pub fn pbkdf2(password: &str, data: &str) -> String {
// let data_salt = data.trim_end_matches('=');
// let salt = SaltString::from_b64(data_salt)
// .map(|s| s)
// .unwrap_or_else(|_| panic!("Failed to parse salt value from base64 string"));
// let mut password_hash = String::new();
// if let Ok(pwd) = Scrypt.hash_password(password.as_bytes(), &salt) {
// password_hash.push_str(&pwd.to_string());
// }
// sha_256(&password_hash)
// }
// // Test sharing JS side
// pub fn get_shares(&self) -> Vec<String> {
// self.sharding.shares_format_str.clone()
// }
// //Test sharing Js side
// pub fn get_secret(&self, shardings: Vec<String>) -> String {
// let mut shares_vec = Vec::new();
// for s in shardings.iter() {
// let bytes_vec: Vec<u8> = s
// .trim_matches(|c| c == '[' || c == ']')
// .split(',')
// .filter_map(|s| s.trim().parse().ok())
// .collect();
// shares_vec.push(bytes_vec);
// }
// self.sharding.recover_secrete(shares_vec.clone())
// }
}
#[cfg(test)]
mod tests {
use super::*; // Import everything from the outer module
const RECOVER_SPEND: &str = "394ef7757f5bc8cd692337c62abf6fa0ce9932fd4ec6676daddfbe3c1b3b9d11";
const RECOVER_SCAN: &str = "3aa8cc570d17ec3a4dc4136e50151cc6de26052d968abfe02a5fea724ce38205";
const REVOKE_SPEND: &str = "821c1a84fa9ee718c02005505fb8315bd479c7b9a878b1eff45929c48dfcaf28";
const REVOKE_SCAN: &str = "a0f36cbc380624fa7eef022f39cab2716333451649dd8eb78e86d2e76bdb3f47";
const MAIN_SPEND: &str = "b9098a6598ac55d8dd0e6b7aab0d1f63eb8792d06143f3c0fb6f5b80476a1c0d";
const MAIN_SCAN: &str = "79dda4031663ac2cb250c46d896dc92b3c027a48a761b2342fabf1e441ea2857";
const USER_PASSWORD: &str = "correct horse battery staple";
const PROCESS: &str = "example";
fn helper_create_user_wallets() -> UserWallets {
let label = "default".to_owned();
let sp_main = SpClient::new(
label.clone(),
SecretKey::from_str(MAIN_SCAN).unwrap(),
SpendKey::Secret(SecretKey::from_str(MAIN_SPEND).unwrap()),
None,
true,
)
.unwrap();
let sp_recover = SpClient::new(
label.clone(),
SecretKey::from_str(RECOVER_SCAN).unwrap(),
SpendKey::Secret(SecretKey::from_str(RECOVER_SPEND).unwrap()),
None,
true,
)
.unwrap();
let sp_revoke = SpClient::new(
label.clone(),
SecretKey::from_str(REVOKE_SCAN).unwrap(),
SpendKey::Secret(SecretKey::from_str(REVOKE_SPEND).unwrap()),
None,
true,
)
.unwrap();
let user_wallets = UserWallets::new(
Some(SpWallet::new(sp_main, None).unwrap()),
Some(SpWallet::new(sp_recover, None).unwrap()),
Some(SpWallet::new(sp_revoke, None).unwrap()),
);
user_wallets
}
#[test]
fn test_successful_creation() {
let user_wallets = helper_create_user_wallets();
let result = User::new(user_wallets, USER_PASSWORD.to_owned(), PROCESS.to_owned());
assert!(result.is_ok());
}
#[test]
fn test_logout() {
let res = User::logout();
assert!(res.is_ok());
}
#[test]
fn test_login() {
let user_wallets = helper_create_user_wallets();
let user = User::new(
user_wallets.clone(),
USER_PASSWORD.to_owned(),
PROCESS.to_owned(),
)
.unwrap();
let res = User::login(
user.pre_id.clone(),
USER_PASSWORD.to_owned(),
&user.recover_data,
&user.shares,
&user_wallets.get_all_outputs(),
);
assert!(res.is_ok());
let connected = lock_connected_user().unwrap();
let recover = connected.try_get_recover().unwrap();
assert!(
format!(
"{}",
recover
.get_client()
.try_get_secret_spend_key()
.unwrap()
.display_secret()
) == RECOVER_SPEND
)
}
}

View File

@ -1,888 +0,0 @@
## Référence API — sdk_client
Ce document spécifie les interfaces publiques du module `sdk_client` exposées aux consommateurs via WebAssembly et, de manière secondaire, via lAPI Rust. Il décrit le périmètre fonctionnel, les structures de données échangées, les erreurs et les invariants, sans inclure dexemples exécutables.
### Portée
- Cible: bibliothèque cliente pour Silent Payments, intégrée côté navigateur ou environnement compatible WASM.
- Interfaces: fonctions exportées via `wasm_bindgen` et types sérialisables via `tsify`/`serde`.
- Hors périmètre: APIs dinfrastructure (RPC Bitcoin, services HTTP, WebSocket relais) qui relèvent dautres composants.
### Interfaces
- Interface WASM: fonctions exportées pour un usage JavaScript/TypeScript. Les types transitent en JSON/JsValue selon `tsify` et `serde_wasm_bindgen`.
- Interface Rust: accès direct aux mêmes primitives lorsquintégré en Rust natif. Cette intégration suit les mêmes contrats mais nest pas linterface principale.
---
## Domaines fonctionnels et fonctions exportées
Les fonctions suivantes sont regroupées par domaine. Sauf mention contraire, les fonctions retournent soit un type de résultat propre (`ApiResult<T>`), soit des structures sérialisables définies cidessous.
### 1) Gestion dappareil et portefeuille
- setup
- create_new_device(birthday, network)
- create_device_from_sp_wallet(sp_wallet_json)
- restore_device(device)
- dump_device / dump_neutered_device
- reset_device
- dump_wallet
- get_address
- get_member
- is_paired
- pair_device(process_id, sp_addresses)
- unpair_device
Prérequis usuels: certaines opérations nécessitent un appareil initialisé et/ou appairé.
### 2) Cache de processus et état local
- reset_process_cache
- dump_process_cache / set_process_cache / add_to_process_cache
- get_pairing_process_id
Invariants: le cache en mémoire ne doit pas être écrasé sil contient déjà des données actives.
### 3) Transactions et fonds
- get_txid(transaction_hex)
- get_outputs
- get_available_amount
- create_transaction(addresses, fee_rate)
- sign_transaction(partial_tx)
Notes: la création de transaction déduit des UTXOs disponibles et peut marquer certains UTXOs comme dépensés (prévention dun doublespend local pendant la signature/envoi).
### 4) Détection et traitement dévénements réseau
- parse_new_tx(new_tx_message, block_height, members_list)
- parse_cipher(cipher_message, members_list)
Comportements principaux: création/actualisation de processus, génération de diffs utilisateurs, collecte de secrets partagés et préparation dartefacts à persister et/ou à transmettre.
### 5) Processus, états et échanges PRD
- create_new_process(private_data, roles, public_data, relay_address, fee_rate, members_list)
- update_process(process, new_attributes, roles, new_public_data, members_list)
- evaluate_state(process, state_id, members_list)
- validate_state(process, state_id, members_list)
- refuse_state(process, state_id, members_list)
- create_update_message(process, state_id, members_list)
- create_response_prd(process, state_id, members_list)
- request_data(process_id, state_ids, roles, members_list)
Garantie fonctionnelle: les rôles et règles de validation associés aux états déterminent les champs visibles/validables par chaque membre.
### 6) Chiffrement, preuves et utilitaires
- reset_shared_secrets / set_shared_secrets
- create_faucet_msg
- get_storages(process_outpoint)
- is_child_role(parent_roles, child_roles)
- decrypt_data(key, data)
- encode_binary / encode_json / decode_value
- hash_value(value, commited_in, label)
- get_merkle_proof(process_state, attribute_name)
- validate_merkle_proof(proof_result, hash)
Contraintes: tailles maximales de messages, formats hexadécimaux pour les preuves et empreintes, et cohérence des clés/indices de Merkle.
---
## Structures de données principales
Les noms de champs listés cidessous sont fournis à titre de référence contractuelle. Le format concret dépend de la sérialisation (`serde`) et du passage de frontières WASM.
- ApiReturn: regroupe les retours multicanaux (secrets mis à jour, processus à persister, messages à diffuser, transactions partielles, etc.).
- ApiError: erreur normalisée (conversion depuis diverses erreurs internes, notamment de parsing, cryptographie, hex, PSBT, etc.).
- DiffStatus: indicateur détat dun diff (None/Rejected/Validated).
- UserDiff: proposition dévolution dattribut (process_id, state_id, valeur engagée, champ, rôles, besoin de validation, notification, statut de validation).
- UpdatedProcess: cliché de processus actualisé (process_id, état courant, diffs, données chiffrées, éventuel state validé).
- MerkleProofResult: résultat de preuve Merkle (preuve, racine, attribut, index, nombre total de feuilles).
Les types membres, rôles, clés, engagements PCD et transactions sappuient sur `sdk_common` (Silent Payments, PSBT, Merkle, signature, etc.).
---
## Erreurs et gestion des échecs
- Normalisation: `ApiError` unifie les erreurs en surface (parsing JSON/hex, erreurs réseau/cryptographie, formats PSBT, conversions sérielles WASM, etc.).
- Messages: volontairement explicites et destinés au diagnostic applicatif, sans fuite déléments secrets.
- Bonnes pratiques: valider en amont formats, tailles et prérequis (appareil initialisé/appairé, états existants, rôles cohérents).
---
## Invariants et contrats
- Appairage: requis pour certaines opérations (validation détat, envoi de réponses, filtrage de champs par rôle).
- Secrets partagés: stockés et confirmés par adresse; jamais exposés en clair au consommateur.
- États de processus: identifiés par racine Merkle; les preuves et validations manipulent exclusivement des engagements.
- Tailles: les charges utiles et messages sont bornés pour éviter abus et surconsommation mémoire côté WASM.
---
## Limitations actuelles et compatibilité
- Réseau de test: certaines constantes sont orientées test (ex. réseau par défaut, montants par défaut). Adapter côté intégration selon les besoins.
- Environnement: linterface prioritaire est WASM (navigateurs/JS runtimes compatibles). LAPI Rust est de niveau bibliothèque.
---
## Traçabilité documentaire
- Toute évolution de signature ou dinvariant doit être répercutée ici et dans `docs/ARCHITECTURE.md`.
- Les impacts sur les parcours doivent être décrits dans `docs/USAGE.md`.
- Les risques/contrôles associés doivent être référencés dans `docs/SECURITY_AUDIT.md`.
## 1. API Bitcoin Core RPC
### Informations Générales
- **Protocole :** JSON-RPC
- **Port :** 18443
- **Authentification :** Cookie ou credentials
- **Réseau :** Signet
- **Base URL :** `http://localhost:18443`
### Authentification
#### Méthode Cookie (Recommandée)
```bash
# Le cookie est automatiquement utilisé par Bitcoin Core
curl -X POST http://localhost:18443 \
-H "Content-Type: application/json" \
--data '{"jsonrpc": "1.0", "id": "test", "method": "getblockchaininfo", "params": []}'
```
#### Méthode Credentials
```bash
curl -X POST http://localhost:18443 \
-H "Content-Type: application/json" \
-u "username:password" \
--data '{"jsonrpc": "1.0", "id": "test", "method": "getblockchaininfo", "params": []}'
```
### Endpoints Principaux
#### getblockchaininfo
Récupère les informations sur la blockchain.
**Requête :**
```json
{
"jsonrpc": "1.0",
"id": "test",
"method": "getblockchaininfo",
"params": []
}
```
**Réponse :**
```json
{
"result": {
"chain": "signet",
"blocks": 12345,
"headers": 12345,
"bestblockhash": "0000000000000000000000000000000000000000000000000000000000000000",
"difficulty": 1.0,
"mediantime": 1234567890,
"verificationprogress": 1.0,
"initialblockdownload": false,
"chainwork": "0000000000000000000000000000000000000000000000000000000000000000",
"size_on_disk": 123456789,
"pruned": false,
"pruneheight": null,
"automatic_pruning": false,
"prune_target_size": null,
"warnings": ""
},
"error": null,
"id": "test"
}
```
#### getblock
Récupère les informations d'un bloc spécifique.
**Requête :**
```json
{
"jsonrpc": "1.0",
"id": "test",
"method": "getblock",
"params": ["blockhash", 2]
}
```
**Paramètres :**
- `blockhash` : Hash du bloc
- `verbosity` : Niveau de détail (0, 1, 2)
#### getrawtransaction
Récupère une transaction brute.
**Requête :**
```json
{
"jsonrpc": "1.0",
"id": "test",
"method": "getrawtransaction",
"params": ["txid", true]
}
```
#### sendrawtransaction
Envoie une transaction brute au réseau.
**Requête :**
```json
{
"jsonrpc": "1.0",
"id": "test",
"method": "sendrawtransaction",
"params": ["hexstring"]
}
```
#### getwalletinfo
Récupère les informations du wallet.
**Requête :**
```json
{
"jsonrpc": "1.0",
"id": "test",
"method": "getwalletinfo",
"params": []
}
```
### Gestion des Erreurs
**Erreur typique :**
```json
{
"result": null,
"error": {
"code": -32601,
"message": "Method not found"
},
"id": "test"
}
```
**Codes d'erreur courants :**
- `-32601` : Méthode non trouvée
- `-32602` : Paramètres invalides
- `-32603` : Erreur interne
- `-1` : Erreur d'authentification
## 2. API Blindbit HTTP
### Informations Générales
- **Protocole :** HTTP REST
- **Port :** 8000
- **Base URL :** `http://localhost:8000`
- **Content-Type :** `application/json`
### Endpoints
#### GET /health
Vérifie la santé du service.
**Requête :**
```bash
curl -X GET http://localhost:8000/health
```
**Réponse :**
```json
{
"status": "healthy",
"timestamp": "2024-12-19T14:30:00Z",
"version": "1.0.0"
}
```
#### POST /generate-address
Génère une adresse de paiement silencieux.
**Requête :**
```json
{
"label": "payment_001",
"amount": 0.001
}
```
**Réponse :**
```json
{
"address": "bc1p...",
"label": "payment_001",
"amount": 0.001,
"created_at": "2024-12-19T14:30:00Z"
}
```
#### GET /payments
Liste les paiements reçus.
**Requête :**
```bash
curl -X GET "http://localhost:8000/payments?limit=10&offset=0"
```
**Paramètres de requête :**
- `limit` : Nombre maximum de résultats (défaut: 10)
- `offset` : Décalage pour la pagination (défaut: 0)
**Réponse :**
```json
{
"payments": [
{
"id": "payment_001",
"address": "bc1p...",
"amount": 0.001,
"txid": "txid...",
"block_height": 12345,
"created_at": "2024-12-19T14:30:00Z"
}
],
"total": 1,
"limit": 10,
"offset": 0
}
```
#### GET /payments/{id}
Récupère les détails d'un paiement spécifique.
**Requête :**
```bash
curl -X GET http://localhost:8000/payments/payment_001
```
**Réponse :**
```json
{
"id": "payment_001",
"address": "bc1p...",
"amount": 0.001,
"txid": "txid...",
"block_height": 12345,
"confirmations": 6,
"created_at": "2024-12-19T14:30:00Z",
"status": "confirmed"
}
```
### Codes de Statut HTTP
- `200` : Succès
- `201` : Créé
- `400` : Requête invalide
- `404` : Ressource non trouvée
- `500` : Erreur serveur
## 3. API SDK Relay WebSocket
### Informations Générales
- **Protocole :** WebSocket/WSS
- **Port :** 8090
- **URL :** `ws://localhost:8090` ou `wss://localhost:8090`
- **Format :** JSON
### Connexion
```javascript
const ws = new WebSocket('ws://localhost:8090');
ws.onopen = function() {
console.log('Connexion WebSocket établie');
};
ws.onmessage = function(event) {
const message = JSON.parse(event.data);
console.log('Message reçu:', message);
};
ws.onerror = function(error) {
console.error('Erreur WebSocket:', error);
};
ws.onclose = function() {
console.log('Connexion WebSocket fermée');
};
```
### Format des Messages
Tous les messages suivent le format JSON suivant :
```json
{
"type": "message_type",
"id": "unique_message_id",
"timestamp": 1234567890,
"data": {
// Données spécifiques au type de message
}
}
```
### Types de Messages
#### Messages de Synchronisation
**StateSync :**
```json
{
"type": "StateSync",
"id": "state_001",
"timestamp": 1234567890,
"data": {
"relay_id": "relay-1",
"state": "running",
"version": "1.0.0",
"uptime": 3600
}
}
```
**HealthSync :**
```json
{
"type": "HealthSync",
"id": "health_001",
"timestamp": 1234567890,
"data": {
"relay_id": "relay-1",
"status": "healthy",
"uptime": 3600,
"cpu_usage": 15.5,
"memory_usage": 45.2
}
}
```
**MetricsSync :**
```json
{
"type": "MetricsSync",
"id": "metrics_001",
"timestamp": 1234567890,
"data": {
"relay_id": "relay-1",
"messages_sent": 1000,
"messages_received": 950,
"sync_errors": 5,
"connected_relays": 3
}
}
```
#### Messages de Transaction
**TransactionReceived :**
```json
{
"type": "TransactionReceived",
"id": "tx_001",
"timestamp": 1234567890,
"data": {
"txid": "txid...",
"amount": 0.001,
"address": "bc1p...",
"block_height": 12345,
"confirmations": 1
}
}
```
**BlockScanned :**
```json
{
"type": "BlockScanned",
"id": "block_001",
"timestamp": 1234567890,
"data": {
"block_height": 12345,
"block_hash": "hash...",
"transactions_count": 150,
"silent_payments_found": 2
}
}
```
### Commandes Client
#### Ping
```json
{
"type": "ping",
"id": "ping_001",
"timestamp": 1234567890,
"data": {}
}
```
**Réponse :**
```json
{
"type": "pong",
"id": "ping_001",
"timestamp": 1234567890,
"data": {
"relay_id": "relay-1"
}
}
```
#### GetStatus
```json
{
"type": "get_status",
"id": "status_001",
"timestamp": 1234567890,
"data": {}
}
```
**Réponse :**
```json
{
"type": "status",
"id": "status_001",
"timestamp": 1234567890,
"data": {
"relay_id": "relay-1",
"status": "running",
"uptime": 3600,
"connected_relays": 3,
"last_block_height": 12345
}
}
```
## 4. API SDK Relay HTTP
### Informations Générales
- **Protocole :** HTTP REST
- **Port :** 8091
- **Base URL :** `http://localhost:8091`
- **Content-Type :** `application/json`
### Endpoints
#### GET /health
Vérifie la santé du relais.
**Requête :**
```bash
curl -X GET http://localhost:8091/health
```
**Réponse :**
```json
{
"status": "healthy",
"relay_id": "relay-1",
"uptime": 3600,
"version": "1.0.0",
"connected_relays": 3
}
```
#### GET /status
Récupère le statut détaillé du relais.
**Requête :**
```bash
curl -X GET http://localhost:8091/status
```
**Réponse :**
```json
{
"relay_id": "relay-1",
"status": "running",
"uptime": 3600,
"version": "1.0.0",
"connected_relays": 3,
"last_block_height": 12345,
"sync_metrics": {
"messages_sent": 1000,
"messages_received": 950,
"sync_errors": 5
}
}
```
#### GET /relays
Liste les relais connectés.
**Requête :**
```bash
curl -X GET http://localhost:8091/relays
```
**Réponse :**
```json
{
"relays": [
{
"relay_id": "relay-2",
"address": "sdk_relay_2:8090",
"status": "connected",
"connected_since": 1234567890,
"last_heartbeat": 1234567890
},
{
"relay_id": "relay-3",
"address": "sdk_relay_3:8090",
"status": "connected",
"connected_since": 1234567890,
"last_heartbeat": 1234567890
}
]
}
```
#### GET /metrics
Récupère les métriques de synchronisation.
**Requête :**
```bash
curl -X GET http://localhost:8091/metrics
```
**Réponse :**
```json
{
"messages_sent": 1000,
"messages_received": 950,
"sync_errors": 5,
"last_sync_timestamp": 1234567890,
"connected_relays": 3,
"mesh_health": 0.95
}
```
#### POST /sync
Force une synchronisation manuelle.
**Requête :**
```json
{
"sync_type": "StateSync",
"target_relay": "relay-2"
}
```
**Réponse :**
```json
{
"success": true,
"message": "Synchronisation initiée",
"sync_id": "sync_001"
}
```
## 5. Gestion des Erreurs
### Erreurs WebSocket
**Erreur de connexion :**
```json
{
"type": "error",
"id": "error_001",
"timestamp": 1234567890,
"data": {
"code": "CONNECTION_ERROR",
"message": "Impossible de se connecter au relais",
"details": "Connection refused"
}
}
```
**Erreur de message :**
```json
{
"type": "error",
"id": "error_002",
"timestamp": 1234567890,
"data": {
"code": "INVALID_MESSAGE",
"message": "Format de message invalide",
"details": "Missing required field 'type'"
}
}
```
### Erreurs HTTP
**Erreur 400 :**
```json
{
"error": {
"code": "INVALID_REQUEST",
"message": "Requête invalide",
"details": "Missing required parameter 'relay_id'"
}
}
```
**Erreur 500 :**
```json
{
"error": {
"code": "INTERNAL_ERROR",
"message": "Erreur interne du serveur",
"details": "Database connection failed"
}
}
```
## 6. Exemples d'Utilisation
### Exemple Python - WebSocket
```python
import asyncio
import websockets
import json
async def connect_to_relay():
uri = "ws://localhost:8090"
async with websockets.connect(uri) as websocket:
# Envoyer un ping
ping_message = {
"type": "ping",
"id": "ping_001",
"timestamp": int(time.time()),
"data": {}
}
await websocket.send(json.dumps(ping_message))
# Écouter les messages
async for message in websocket:
data = json.loads(message)
print(f"Message reçu: {data}")
asyncio.run(connect_to_relay())
```
### Exemple JavaScript - WebSocket
```javascript
const ws = new WebSocket('ws://localhost:8090');
ws.onopen = function() {
// Envoyer un ping
const pingMessage = {
type: 'ping',
id: 'ping_001',
timestamp: Date.now(),
data: {}
};
ws.send(JSON.stringify(pingMessage));
};
ws.onmessage = function(event) {
const message = JSON.parse(event.data);
console.log('Message reçu:', message);
};
```
### Exemple cURL - Bitcoin Core RPC
```bash
# Récupérer les informations de la blockchain
curl -X POST http://localhost:18443 \
-H "Content-Type: application/json" \
--data '{
"jsonrpc": "1.0",
"id": "test",
"method": "getblockchaininfo",
"params": []
}'
# Récupérer un bloc spécifique
curl -X POST http://localhost:18443 \
-H "Content-Type: application/json" \
--data '{
"jsonrpc": "1.0",
"id": "test",
"method": "getblock",
"params": ["blockhash", 2]
}'
```
## 7. Limites et Quotas
### Bitcoin Core RPC
- **Taux limite :** 1000 requêtes/minute par défaut
- **Taille des requêtes :** 32MB maximum
- **Connexions simultanées :** 125 par défaut
### Blindbit HTTP
- **Taux limite :** 100 requêtes/minute
- **Taille des requêtes :** 10MB maximum
- **Connexions simultanées :** 50
### SDK Relay WebSocket
- **Connexions simultanées :** 1000 par relais
- **Taille des messages :** 1MB maximum
- **Heartbeat :** 30 secondes
### SDK Relay HTTP
- **Taux limite :** 200 requêtes/minute
- **Taille des requêtes :** 5MB maximum
- **Connexions simultanées :** 100
## 8. Sécurité
### Authentification
- **Bitcoin Core :** Cookie d'authentification
- **Blindbit :** À définir selon les besoins
- **SDK Relay :** Authentification WebSocket (optionnelle)
### Chiffrement
- **RPC Bitcoin :** HTTP (non chiffré en local)
- **HTTP Blindbit :** HTTP (non chiffré en local)
- **WebSocket SDK Relay :** WSS (chiffré)
### Bonnes Pratiques
- Utiliser HTTPS/WSS en production
- Implémenter l'authentification appropriée
- Valider toutes les entrées
- Limiter les taux de requêtes
- Monitorer les accès
## 9. Monitoring et Observabilité
### Métriques à Surveiller
- **Latence des APIs :** Temps de réponse
- **Taux d'erreur :** Pourcentage d'erreurs
- **Débit :** Requêtes par seconde
- **Utilisation des ressources :** CPU, mémoire, réseau
### Logs
- **Logs d'accès :** Requêtes et réponses
- **Logs d'erreur :** Erreurs et exceptions
- **Logs de performance :** Métriques de performance
### Alertes
- **Erreurs 5xx :** Erreurs serveur
- **Latence élevée :** Temps de réponse > 1s
- **Taux d'erreur élevé :** > 5%
- **Services indisponibles :** Health checks en échec

View File

@ -1,491 +0,0 @@
## Architecture — sdk_client
Ce document décrit larchitecture du module `sdk_client` (bibliothèque cliente Silent Payments), ses modules internes, flux principaux et invariants. Il est centré sur le code de ce dépôt.
### Périmètre
- Interface principale: WebAssembly via `wasm_bindgen` et `tsify`.
- Modules internes: `api.rs` (surface fonctionnelle), `user.rs` (appareil local), `wallet.rs` (portefeuille SP), `peers.rs` (pair minimal), `lib.rs` (agrégation).
- Dépendances clés: `sdk_common` (cryptographie, SP, Merkle, PSBT), `serde`, `rand`, `wasm-logger`.
### Flux essentiels
- Initialisation/Pairing: création ou restauration dappareil, appairage optionnel par `process_id` et adresses SP.
- Traitement dévénements: analyse de transactions et messages chiffrés, mises à jour de processus, génération de diffs et commits.
- Gestion de processus: création et évolution détats avec engagements PCD (racines Merkle) et règles/ rôles.
- Transactions SP: construction, dérivation des secrets partagés, signature et préparation de messages réseau.
### Invariants
- Secrets jamais exposés en clair hors du module.
- États identifiés par racines Merkle, preuves cohérentes avec larbre.
- Rôles déterminent visibilité/validation des champs.
- Tailles et formats bornés à la frontière WASM.
### Traçabilité documentaire
- Toute évolution doit être répercutée dans `docs/API.md` et `docs/USAGE.md` et les risques dans `docs/SECURITY_AUDIT.md`.
Ce guide décrit l'architecture technique détaillée de l'infrastructure 4NK Node, incluant la synchronisation entre relais et les composants système.
## Vue d'Ensemble de l'Architecture
L'infrastructure 4NK Node est composée de plusieurs services interconnectés qui forment un système distribué pour les paiements silencieux Bitcoin.
### Architecture Générale
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Bitcoin Core │ │ Blindbit │ │ SDK Relay 1 │
│ (Signet) │ │ (Service SP) │ │ (WebSocket) │
│ Port: 18443 │ │ Port: 8000 │ │ Port: 8090 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└───────────────────────┼───────────────────────┘
┌─────────────────┐
│ Docker Network │
│ (btcnet) │
└─────────────────┘
┌─────────────────┐
│ SDK Relay 2 │
│ (WebSocket) │
│ Port: 8092 │
└─────────────────┘
┌─────────────────┐
│ SDK Relay 3 │
│ (WebSocket) │
│ Port: 8094 │
└─────────────────┘
```
## Composants Principaux
### 1. Bitcoin Core (Nœud Signet)
**Rôle :** Nœud Bitcoin Core configuré en mode signet pour le développement et les tests.
**Caractéristiques :**
- **Port RPC :** 18443
- **Port ZMQ :** 29000
- **Réseau :** Signet
- **Validation :** Complète des transactions
- **Stockage :** Blockchain complète
- **Interface :** JSON-RPC
**Fonctionnalités :**
- Validation des transactions
- Stockage de la blockchain
- Interface RPC pour les interactions
- Support des wallets
- Notifications ZMQ pour les événements
### 2. Service Blindbit
**Rôle :** Service pour les paiements silencieux (Silent Payments).
**Caractéristiques :**
- **Port :** 8000
- **Interface :** HTTP REST API
- **Protocole :** HTTP
**Fonctionnalités :**
- Génération d'adresses de paiement silencieux
- Validation des transactions
- Interface HTTP pour les interactions
- Gestion des clés et signatures
### 3. Service SDK Relay
**Rôle :** Relais pour les interactions SDK avec synchronisation mesh.
**Caractéristiques :**
- **Port WebSocket :** 8090
- **Port HTTP :** 8091
- **Protocole :** WebSocket/WSS
- **Synchronisation :** Mesh network
**Fonctionnalités :**
- Connexion au nœud Bitcoin Core
- Gestion des wallets
- Interface WebSocket
- Scan des blocs pour les paiements silencieux
- Synchronisation entre relais
- Cache de déduplication
## Architecture de Synchronisation
### Gestionnaire de Synchronisation (`SyncManager`)
Le `SyncManager` est le composant central qui gère toute la logique de synchronisation entre les relais :
```rust
pub struct SyncManager {
relay_id: String,
sequence_counter: Arc<Mutex<u64>>,
sync_cache: Arc<Mutex<HashMap<String, Instant>>>,
last_sync: Arc<Mutex<HashMap<SyncType, u64>>>,
mesh_connections: Arc<Mutex<HashMap<String, MeshConnection>>>,
known_relays: Arc<Mutex<HashMap<String, RelayInfo>>>,
metrics: Arc<Mutex<SyncMetrics>>,
}
```
### Types de Synchronisation
Le système supporte plusieurs types de synchronisation :
- **StateSync** : Synchronisation de l'état général du relais
- **ProcessSync** : Synchronisation des processus en cours
- **MemberSync** : Synchronisation des membres
- **TxSync** : Synchronisation des transactions
- **BlockSync** : Synchronisation des blocs
- **PeerSync** : Synchronisation des pairs connectés
- **RelaySync** : Synchronisation des informations des relais
- **HealthSync** : Synchronisation de la santé du relais
- **MetricsSync** : Synchronisation des métriques
- **ConfigSync** : Synchronisation de la configuration
- **CapabilitySync** : Synchronisation des capacités
### Messages de Synchronisation
#### Structure des Messages
```rust
pub struct SyncMessage {
pub sync_type: SyncType,
pub relay_id: String,
pub sequence: u64,
pub timestamp: u64,
pub payload: SyncPayload,
}
```
#### Types de Payload
```rust
pub enum SyncPayload {
StateData { state: String, version: String },
ProcessData { processes: HashMap<String, String> },
MemberData { members: HashMap<String, String> },
HealthData { status: HealthStatus, uptime: u64, cpu_usage: f64 },
MetricsData { metrics: SyncMetrics },
PeerData { peers: Vec<PeerInfo>, last_seen: u64 },
RelayData { relays: Vec<RelayInfo>, network_topology: NetworkTopology },
}
```
## Fonctionnalités de Synchronisation
### 1. Découverte Automatique des Relais
Le système implémente une découverte automatique des relais dans le réseau :
```rust
pub async fn discover_relays(&self) -> Result<()> {
let relay_hosts = vec![
"sdk_relay_1",
"sdk_relay_2",
"sdk_relay_3",
];
for host in relay_hosts {
if host == self.relay_id {
continue; // Ignorer soi-même
}
let relay_info = RelayInfo {
relay_id: host.to_string(),
address: format!("{}:8090", host),
// ... autres champs
};
self.add_relay(relay_info)?;
}
Ok(())
}
```
### 2. Cache de Déduplication
Pour éviter les doublons, un cache de déduplication est implémenté :
```rust
pub struct MessageCache {
cache: Arc<Mutex<HashMap<String, Instant>>>,
}
impl MessageCache {
pub fn is_duplicate(&self, message_id: &str) -> bool {
let mut cache = self.cache.lock().unwrap();
if cache.contains_key(message_id) {
true
} else {
cache.insert(message_id.to_string(), Instant::now());
false
}
}
}
```
### 3. Synchronisation Périodique
Le système effectue une synchronisation périodique avec des intervalles configurés :
- **Synchronisation d'état** : Toutes les 30 secondes
- **Synchronisation de santé** : Toutes les 60 secondes
- **Synchronisation de métriques** : Toutes les 120 secondes
- **Synchronisation des relais** : Toutes les 300 secondes (5 minutes)
### 4. Gestion des Connexions Mesh
```rust
pub struct MeshConnection {
pub relay_id: String,
pub address: String,
pub connected_since: u64,
pub last_heartbeat: u64,
pub status: ConnectionStatus,
}
```
## Configuration Multi-Relais
### Configuration Docker
Le système supporte la configuration de plusieurs relais via Docker :
```yaml
services:
sdk_relay_1:
container_name: sdk_relay_1
ports:
- "8090:8090"
- "8091:8091"
environment:
- ENABLE_SYNC_TEST=1
sdk_relay_2:
container_name: sdk_relay_2
ports:
- "8092:8090"
- "8093:8091"
environment:
- ENABLE_SYNC_TEST=1
sdk_relay_3:
container_name: sdk_relay_3
ports:
- "8094:8090"
- "8095:8091"
environment:
- ENABLE_SYNC_TEST=1
```
### Configuration par Relais
Chaque relais a sa propre configuration :
```ini
# .conf.docker.relay1
relay_id=relay-1
ws_url=0.0.0.0:8090
# .conf.docker.relay2
relay_id=relay-2
ws_url=0.0.0.0:8090
# .conf.docker.relay3
relay_id=relay-3
ws_url=0.0.0.0:8090
```
## Métriques de Synchronisation
```rust
pub struct SyncMetrics {
pub messages_sent: u64,
pub messages_received: u64,
pub sync_errors: u64,
pub last_sync_timestamp: u64,
pub connected_relays: u64,
pub mesh_health: f64,
}
```
## Flux de Données
### 1. Flux de Synchronisation
```
Relay 1 ──┐
├─── SyncManager ──── MessageCache ──── Mesh Network
Relay 2 ──┤
Relay 3 ──┘
```
### 2. Flux de Traitement des Transactions
```
Bitcoin Core ──── ZMQ Notifications ──── SDK Relay ──── Blindbit
│ │ │ │
└─── Block Scan ─────┴─── Silent Payment ─┴─── Validation
```
### 3. Flux de Communication WebSocket
```
Client ──── WebSocket ──── SDK Relay ──── Bitcoin Core RPC
│ │ │
└─── Events ─┴─── Commands ─┴─── Responses
```
## Sécurité et Isolation
### 1. Isolation Réseau
- **Réseau privé :** `btcnet` pour la communication inter-services
- **Ports exposés :** Seulement les ports nécessaires
- **Volumes :** Données persistantes isolées
### 2. Authentification
- **Bitcoin Core :** Cookie d'authentification
- **Blindbit :** À définir selon les besoins
- **SDK Relay :** Authentification WebSocket
- **Tor :** Pas d'authentification requise
### 3. Chiffrement
- **RPC Bitcoin :** HTTP (non chiffré en local)
- **HTTP Blindbit :** HTTP (non chiffré en local)
- **WebSocket SDK Relay :** WSS (chiffré)
- **Tor :** Chiffrement intégré
## Performance et Optimisations
### 1. Ressources Requises
- **CPU :** Minimum 2 cœurs
- **RAM :** Minimum 4 GB
- **Stockage :** Minimum 50 GB pour la blockchain
- **Réseau :** Connexion stable à Internet
### 2. Optimisations Implémentées
- **Cache :** Mise en cache des données fréquemment utilisées
- **Compression :** Compression des données de blockchain
- **Parallélisation :** Traitement parallèle des blocs
- **Monitoring :** Métriques de performance
### 3. Métriques de Performance
- **Latence de synchronisation :** < 100ms
- **Débit de messages :** > 1000 msg/s
- **Utilisation mémoire :** < 2GB par relais
- **Temps de démarrage :** < 30 secondes
## Monitoring et Observabilité
### 1. Métriques Collectées
- **Métriques système :** CPU, RAM, disque, réseau
- **Métriques de synchronisation :** Messages envoyés/reçus, erreurs
- **Métriques de santé :** Uptime, statut des connexions
- **Métriques métier :** Transactions traitées, paiements détectés
### 2. Logs
- **Logs système :** Démarrage, arrêt, erreurs
- **Logs de synchronisation :** Messages, erreurs, métriques
- **Logs métier :** Transactions, paiements, événements
### 3. Alertes
- **Alertes critiques :** Services arrêtés, erreurs de synchronisation
- **Alertes de performance :** Latence élevée, utilisation mémoire
- **Alertes métier :** Échecs de traitement, anomalies
## Évolutivité
### 1. Scalabilité Horizontale
- **Ajout de relais :** Configuration automatique
- **Load balancing :** Distribution de charge
- **Redondance :** Relais de secours
### 2. Scalabilité Verticale
- **Ressources :** Augmentation CPU/RAM
- **Stockage :** Extension des volumes
- **Réseau :** Bande passante
### 3. Architecture Distribuée
- **Microservices :** Services indépendants
- **API Gateway :** Point d'entrée unifié
- **Service Discovery :** Découverte automatique
## Déploiement et Infrastructure
### 1. Environnements
- **Développement :** Configuration locale
- **Test :** Environnement de test
- **Production :** Configuration optimisée
### 2. Orchestration
- **Docker Compose :** Orchestration locale
- **Kubernetes :** Orchestration distribuée (futur)
- **Service Mesh :** Communication inter-services
### 3. CI/CD
- **Build :** Construction des images
- **Test :** Tests automatisés
- **Déploiement :** Déploiement automatique
## Troubleshooting
### 1. Problèmes de Synchronisation
- **Connexions perdues :** Vérifier la connectivité réseau
- **Messages dupliqués :** Vérifier le cache de déduplication
- **Latence élevée :** Vérifier les ressources système
### 2. Problèmes de Performance
- **Utilisation mémoire :** Vérifier les fuites mémoire
- **CPU élevé :** Vérifier les boucles infinies
- **Disque plein :** Nettoyer les logs et données
### 3. Problèmes de Configuration
- **Ports bloqués :** Vérifier le pare-feu
- **Volumes manquants :** Vérifier les permissions
- **Variables d'environnement :** Vérifier la configuration
## Évolution Future
### 1. Améliorations Planifiées
- **Synchronisation temps réel :** Réduction de la latence
- **Compression avancée :** Optimisation de la bande passante
- **Chiffrement end-to-end :** Sécurité renforcée
### 2. Nouvelles Fonctionnalités
- **API REST :** Interface REST pour les clients
- **Webhooks :** Notifications en temps réel
- **Analytics :** Tableaux de bord avancés
### 3. Intégrations
- **Monitoring :** Prometheus, Grafana
- **Logging :** ELK Stack
- **Alerting :** PagerDuty, Slack

View File

@ -1,236 +0,0 @@
# Automatisation SSH pour Push - ihm_client
## Vue d'ensemble
L'automatisation SSH pour les push permet d'utiliser automatiquement votre clé SSH pour tous les push vers le repository `ihm_client` sur Gitea, sans avoir à spécifier manuellement les paramètres SSH.
## Configuration automatique
### 1. Configuration Git globale
La configuration SSH est automatiquement appliquée :
```bash
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
```
### 2. Vérification SSH
Le script vérifie automatiquement la configuration SSH :
```bash
ssh -T git@git.4nkweb.com
```
## Scripts d'automatisation
### Script principal : `auto-ssh-push.sh`
Le script `scripts/auto-ssh-push.sh` offre plusieurs modes de push automatique :
#### Options disponibles
```bash
# Push rapide (message automatique)
./scripts/auto-ssh-push.sh quick
# Push avec message personnalisé
./scripts/auto-ssh-push.sh message "feat: nouvelle fonctionnalité"
# Push sur une branche spécifique
./scripts/auto-ssh-push.sh branch feature/nouvelle-fonctionnalite
# Push et préparation merge
./scripts/auto-ssh-push.sh merge feature/nouvelle-fonctionnalite main
# Status et push conditionnel
./scripts/auto-ssh-push.sh status
```
#### Exemples d'utilisation
```bash
# Push rapide sur la branche courante
./scripts/auto-ssh-push.sh quick
# Push avec message de commit
./scripts/auto-ssh-push.sh message "fix: correction du bug de synchronisation"
# Push sur une branche spécifique
./scripts/auto-ssh-push.sh branch develop
# Push et création de Pull Request
./scripts/auto-ssh-push.sh merge feature/nouvelle-fonctionnalite main
```
### Alias Git globaux
Des alias Git ont été configurés pour simplifier les push :
```bash
# Push avec message personnalisé
git ssh-push "Mon message de commit"
# Push rapide (message automatique)
git quick-push
```
## Fonctionnalités automatiques
### 1. Configuration SSH automatique
- Configuration Git pour utiliser SSH
- Vérification de l'authentification SSH
- Gestion des erreurs de configuration
### 2. Push automatique
- Ajout automatique de tous les changements (`git add .`)
- Commit automatique avec message
- Push automatique vers la branche courante
### 3. Gestion des branches
- Détection automatique de la branche courante
- Support des branches personnalisées
- Préparation des Pull Requests
### 4. Validation et sécurité
- Vérification de l'authentification SSH avant push
- Messages d'erreur explicites
- Gestion des cas d'échec
## Workflow recommandé
### Développement quotidien
```bash
# 1. Faire vos modifications
# 2. Push rapide
./scripts/auto-ssh-push.sh quick
# Ou avec message personnalisé
./scripts/auto-ssh-push.sh message "feat: ajout de la fonctionnalité X"
```
### Développement de fonctionnalités
```bash
# 1. Créer une branche
git checkout -b feature/nouvelle-fonctionnalite
# 2. Développer
# 3. Push sur la branche
./scripts/auto-ssh-push.sh branch feature/nouvelle-fonctionnalite
# 4. Préparer le merge
./scripts/auto-ssh-push.sh merge feature/nouvelle-fonctionnalite main
```
### Intégration continue
```bash
# Push automatique après tests
./scripts/auto-ssh-push.sh message "ci: tests passés, déploiement automatique"
```
## Dépannage
### Problèmes courants
#### 1. Échec d'authentification SSH
```bash
# Vérifier la clé SSH
ssh -T git@git.4nkweb.com
# Si échec, configurer une nouvelle clé
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_4nk
ssh-add ~/.ssh/id_ed25519_4nk
```
#### 2. Configuration Git manquante
```bash
# Reconfigurer Git pour SSH
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
```
#### 3. Permissions de script
```bash
# Rendre le script exécutable
chmod +x scripts/auto-ssh-push.sh
```
### Commandes de diagnostic
```bash
# Vérifier la configuration SSH
ssh -vT git@git.4nkweb.com
# Vérifier la configuration Git
git config --global --list | grep url
# Vérifier les remotes
git remote -v
```
## Intégration avec CI/CD
### Workflow Gitea Actions
Le workflow CI/CD (`.gitea/workflows/ci.yml`) utilise automatiquement SSH :
```yaml
- name: Setup SSH for Gitea
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H git.4nkweb.com >> ~/.ssh/known_hosts
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
```
### Variables d'environnement
- `SSH_PRIVATE_KEY` : Clé SSH privée pour l'authentification
- `SSH_PUBLIC_KEY` : Clé SSH publique (optionnelle)
## Sécurité
### Bonnes pratiques
- Les clés SSH sont stockées de manière sécurisée
- Les permissions des fichiers SSH sont correctement configurées
- La vérification des hôtes SSH est activée
- Les clés sont régulièrement renouvelées
### Permissions recommandées
```bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/config
```
## Évolution
### Améliorations futures
- Support pour plusieurs clés SSH
- Rotation automatique des clés
- Intégration avec un gestionnaire de secrets
- Support pour l'authentification par certificats SSH
### Maintenance
- Vérification régulière de la validité des clés SSH
- Mise à jour des configurations selon les bonnes pratiques
- Documentation des changements de configuration
## Conclusion
L'automatisation SSH pour les push simplifie considérablement le workflow de développement en éliminant la nécessité de configurer manuellement SSH pour chaque opération Git. Le script `auto-ssh-push.sh` et les alias Git offrent une interface simple et sécurisée pour tous les push vers le repository `ihm_client`.

View File

@ -1,401 +0,0 @@
# Guide de la Communauté - 4NK Node
## 🌟 Bienvenue dans la Communauté 4NK Node !
Ce guide vous accompagne dans votre participation à la communauté open source de 4NK Node, une infrastructure complète pour les paiements silencieux Bitcoin.
## 🎯 À Propos de 4NK Node
### **Qu'est-ce que 4NK Node ?**
4NK Node est une infrastructure Docker complète qui permet de déployer et gérer facilement un écosystème Bitcoin complet incluant :
- **Bitcoin Core** : Nœud Bitcoin avec support signet
- **Blindbit** : Service de filtres pour les paiements silencieux
- **SDK Relay** : Système de relais avec synchronisation mesh
- **Tor** : Proxy anonyme pour la confidentialité
### **Pourquoi les Paiements Silencieux ?**
Les paiements silencieux (Silent Payments) sont une innovation Bitcoin qui améliore la confidentialité en permettant de créer des adresses uniques pour chaque transaction, sans révéler de liens entre les paiements.
## 🤝 Comment Contribuer
### **Niveaux de Contribution**
#### 🟢 **Débutant**
- **Documentation** : Améliorer les guides, corriger les fautes
- **Tests** : Ajouter des tests, signaler des bugs
- **Support** : Aider les autres utilisateurs
- **Traduction** : Traduire la documentation
#### 🟡 **Intermédiaire**
- **Fonctionnalités** : Implémenter de nouvelles fonctionnalités
- **Optimisations** : Améliorer les performances
- **Tests avancés** : Tests d'intégration et de performance
- **Outils** : Créer des scripts et outils
#### 🔴 **Avancé**
- **Architecture** : Améliorer l'architecture du système
- **Sécurité** : Audits de sécurité, améliorations
- **Core features** : Fonctionnalités principales
- **Mentorat** : Guider les nouveaux contributeurs
### **Premiers Pas**
#### 1. **Fork et Clone**
```bash
# Fork le repository sur Gitea
# Puis clonez votre fork
git clone https://git.4nkweb.com/votre-username/4NK_node.git
cd 4NK_node
# Ajoutez l'upstream
git remote add upstream https://git.4nkweb.com/4nk/4NK_node.git
```
#### 2. **Installation Locale**
```bash
# Installez l'infrastructure
./restart_4nk_node.sh
# Vérifiez que tout fonctionne
docker ps
```
#### 3. **Exploration**
```bash
# Explorez la documentation
ls docs/
cat docs/INDEX.md
# Exécutez les tests
./tests/run_all_tests.sh
```
## 📚 Ressources d'Apprentissage
### **Documentation Essentielle**
#### **Pour Commencer**
- **[Guide d'Installation](docs/INSTALLATION.md)** - Installation complète
- **[Guide d'Utilisation](docs/USAGE.md)** - Utilisation quotidienne
- **[Guide de Configuration](docs/CONFIGURATION.md)** - Configuration avancée
#### **Pour Développer**
- **[Architecture Technique](docs/ARCHITECTURE.md)** - Architecture détaillée
- **[API Reference](docs/API.md)** - Documentation des APIs
- **[Guide de Tests](docs/TESTING.md)** - Tests et validation
#### **Pour Contribuer**
- **[Guide de Contribution](CONTRIBUTING.md)** - Processus de contribution
- **[Code de Conduite](CODE_OF_CONDUCT.md)** - Règles de la communauté
- **[Politique de Sécurité](SECURITY.md)** - Signalement de vulnérabilités
### **Ressources Externes**
#### **Bitcoin et Paiements Silencieux**
- [Bitcoin.org](https://bitcoin.org/) - Documentation Bitcoin officielle
- [BIP 352](https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki) - Spécification des paiements silencieux
- [Bitcoin Core Documentation](https://bitcoincore.org/en/doc/) - Documentation Bitcoin Core
#### **Technologies Utilisées**
- [Docker Documentation](https://docs.docker.com/) - Guide Docker
- [Rust Book](https://doc.rust-lang.org/book/) - Guide Rust
- [WebSocket RFC](https://tools.ietf.org/html/rfc6455) - Spécification WebSocket
## 🛠️ Environnement de Développement
### **Prérequis**
#### **Système**
```bash
# Ubuntu/Debian
sudo apt update
sudo apt install docker.io docker-compose git curl
# CentOS/RHEL
sudo yum install docker docker-compose git curl
# macOS
brew install docker docker-compose git curl
```
#### **Développement**
```bash
# Rust (pour sdk_relay)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Python (pour les tests)
sudo apt install python3 python3-pip
pip3 install websockets requests
```
### **Configuration de Développement**
#### **Variables d'Environnement**
```bash
# Configuration de développement
export RUST_LOG=debug
export ENABLE_SYNC_TEST=1
export BITCOIN_NETWORK=signet
```
#### **Outils de Développement**
```bash
# Linting et formatting
cargo clippy
cargo fmt
# Tests
cargo test
./tests/run_all_tests.sh
# Build
cargo build --release
```
## 🐛 Signaler un Bug
### **Avant de Signaler**
1. **Vérifiez la documentation** - La solution pourrait déjà être documentée
2. **Recherchez les issues existantes** - Le bug pourrait déjà être signalé
3. **Testez sur la dernière version** - Le bug pourrait déjà être corrigé
### **Template de Bug Report**
Utilisez le template fourni dans Gitea ou suivez cette structure :
```markdown
## Description du Bug
Description claire et concise du problème.
## Étapes pour Reproduire
1. Aller à '...'
2. Cliquer sur '...'
3. Faire défiler jusqu'à '...'
4. Voir l'erreur
## Comportement Attendu
Description de ce qui devrait se passer.
## Comportement Actuel
Description de ce qui se passe actuellement.
## Informations Système
- OS: [ex: Ubuntu 20.04]
- Docker: [ex: 20.10.0]
- Version: [ex: v1.0.0]
## Logs
```
Logs pertinents ici
```
```
## 💡 Proposer une Fonctionnalité
### **Avant de Proposer**
1. **Vérifiez la roadmap** - La fonctionnalité pourrait déjà être planifiée
2. **Discutez avec la communauté** - Utilisez les discussions Gitea
3. **Préparez un prototype** - Montrez que c'est faisable
### **Template de Feature Request**
```markdown
## Résumé
Description claire et concise de la fonctionnalité souhaitée.
## Motivation
Pourquoi cette fonctionnalité est-elle nécessaire ?
## Proposition
Description détaillée de la fonctionnalité proposée.
## Alternatives Considérées
Autres solutions envisagées.
## Exemples d'Utilisation
Comment cette fonctionnalité serait-elle utilisée ?
```
## 🔄 Processus de Contribution
### **Workflow Git**
#### 1. **Créer une Branche**
```bash
# Depuis la branche main
git checkout main
git pull upstream main
# Créer une branche pour votre contribution
git checkout -b feature/nom-de-votre-feature
# ou
git checkout -b fix/nom-du-bug
```
#### 2. **Développer**
```bash
# Développez votre fonctionnalité
# Ajoutez des tests
# Mettez à jour la documentation
# Commitez régulièrement
git add .
git commit -m "feat: ajouter nouvelle fonctionnalité"
```
#### 3. **Tester**
```bash
# Exécutez les tests
./tests/run_all_tests.sh
# Vérifiez le code
cargo clippy
cargo fmt --check
```
#### 4. **Soumettre**
```bash
# Poussez vers votre fork
git push origin feature/nom-de-votre-feature
# Créez une Pull Request sur Gitea
```
### **Standards de Code**
#### **Messages de Commit**
Utilisez le format conventionnel :
```bash
feat(sdk_relay): add new sync type for metrics
fix(bitcoin): resolve connection timeout issue
docs(api): update WebSocket message format
test(integration): add multi-relay sync tests
```
#### **Code Style**
- **Rust** : Suivez les conventions Rust (rustfmt, clippy)
- **Bash** : Utilisez shellcheck pour les scripts
- **Python** : Suivez PEP 8
- **Markdown** : Utilisez un linter markdown
## 🏷️ Labels et Milestones
### **Labels Utilisés**
#### **Type**
- `bug` - Problèmes et bugs
- `enhancement` - Nouvelles fonctionnalités
- `documentation` - Amélioration de la documentation
- `good first issue` - Pour les nouveaux contributeurs
- `help wanted` - Besoin d'aide
#### **Priorité**
- `priority: high` - Priorité élevée
- `priority: medium` - Priorité moyenne
- `priority: low` - Priorité basse
#### **Statut**
- `status: blocked` - Bloqué
- `status: in progress` - En cours
- `status: ready for review` - Prêt pour review
### **Milestones**
- **v1.0.0** - Version stable initiale
- **v1.1.0** - Améliorations et corrections
- **v2.0.0** - Nouvelles fonctionnalités majeures
## 🎉 Reconnaissance
### **Hall of Fame**
Les contributeurs significatifs seront reconnus dans :
- **README.md** - Liste des contributeurs
- **CHANGELOG.md** - Mentions dans les releases
- **Documentation** - Crédits dans les guides
- **Site web** - Page dédiée aux contributeurs
### **Badges et Certifications**
- **Contributeur Bronze** : 1-5 contributions
- **Contributeur Argent** : 6-20 contributions
- **Contributeur Or** : 21+ contributions
- **Maintainer** : Responsabilités de maintenance
## 🆘 Besoin d'Aide ?
### **Canaux de Support**
#### **Issues Gitea**
- **Bugs** : [Issues](https://git.4nkweb.com/4nk/4NK_node/issues?q=is%3Aissue+is%3Aopen+label%3Abug)
- **Fonctionnalités** : [Feature Requests](https://git.4nkweb.com/4nk/4NK_node/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement)
#### **Discussions**
- **Questions générales** : [Discussions](https://git.4nkweb.com/4nk/4NK_node/issues)
- **Aide technique** : [Support](https://git.4nkweb.com/4nk/4NK_node/issues/new)
#### **Contact Direct**
- **Email** : support@4nkweb.com
- **Sécurité** : security@4nkweb.com
### **FAQ**
#### **Questions Fréquentes**
**Q: Comment installer 4NK Node ?**
A: Suivez le [Guide d'Installation](docs/INSTALLATION.md)
**Q: Comment contribuer au code ?**
A: Consultez le [Guide de Contribution](CONTRIBUTING.md)
**Q: Comment signaler un bug de sécurité ?**
A: Contactez security@4nkweb.com (NE PAS créer d'issue publique)
**Q: Comment proposer une nouvelle fonctionnalité ?**
A: Créez une issue avec le label `enhancement`
## 🚀 Projets Futurs
### **Roadmap Communautaire**
#### **Court Terme (1-3 mois)**
- Interface utilisateur web
- Support de nouveaux réseaux Bitcoin
- Amélioration de la documentation
- Tests de performance
#### **Moyen Terme (3-6 mois)**
- Support Lightning Network
- API REST complète
- Monitoring avancé
- Déploiement cloud
#### **Long Terme (6-12 mois)**
- Écosystème complet
- Marketplace d'extensions
- Support multi-blockchains
- IA et automatisation
### **Idées de Contribution**
#### **Fonctionnalités Populaires**
- Interface graphique pour la gestion
- Intégration avec des wallets populaires
- Support de nouveaux types de paiements
- Outils de monitoring avancés
#### **Améliorations Techniques**
- Optimisation des performances
- Amélioration de la sécurité
- Support de nouvelles plateformes
- Tests automatisés avancés
---
**Merci de faire partie de la communauté 4NK Node ! Votre contribution aide à construire l'avenir des paiements Bitcoin privés et sécurisés.** 🌟

View File

@ -1,846 +0,0 @@
# ⚙️ Guide de Configuration - 4NK Node
Guide complet pour configurer l'infrastructure 4NK Node selon vos besoins.
## 📋 Configuration Générale
### 1. Variables d'Environnement
Créer un fichier `.env` à la racine du projet :
```bash
# Configuration 4NK Node
PROJECT_NAME=4NK Node
NETWORK_NAME=4nk_node_btcnet
# Logs
RUST_LOG=debug,bitcoincore_rpc=trace
# Bitcoin
BITCOIN_COOKIE_PATH=/home/bitcoin/.bitcoin/signet/.cookie
# Synchronisation
ENABLE_SYNC_TEST=1
# Ports
TOR_PORTS=9050:9050,9051:9051
BITCOIN_PORTS=38333:38333,18443:18443,29000:29000
BLINDBIT_PORTS=8000:8000
RELAY_1_PORTS=8090:8090,8091:8091
RELAY_2_PORTS=8092:8090,8093:8091
RELAY_3_PORTS=8094:8090,8095:8091
```
### 2. Configuration Réseau
#### Réseau Docker Personnalisé
```bash
# Créer un réseau personnalisé
docker network create 4nk-network --subnet=172.20.0.0/16 --gateway=172.20.0.1
# Modifier docker-compose.yml
sed -i 's/4nk_default/4nk-network/g' docker-compose.yml
```
#### Configuration de Pare-feu
```bash
# Autoriser les ports nécessaires
sudo ufw allow 18443/tcp # Bitcoin Core RPC
sudo ufw allow 8090/tcp # sdk_relay WebSocket
sudo ufw allow 8000/tcp # Blindbit API
sudo ufw allow 9050/tcp # Tor SOCKS
sudo ufw enable
# Vérifier les règles
sudo ufw status numbered
```
## 🔧 Configuration Bitcoin Core
### 1. Configuration de Base
Fichier : `bitcoin/bitcoin.conf`
```ini
# Configuration Bitcoin Core Signet
signet=1
rpcuser=bitcoin
rpcpassword=your_secure_password
rpcbind=0.0.0.0
rpcallowip=172.19.0.0/16
zmqpubrawblock=tcp://0.0.0.0:29000
zmqpubrawtx=tcp://0.0.0.0:29000
txindex=1
server=1
listen=1
# Configuration Signet
[signet]
listen=1
bind=0.0.0.0:38333
rpcbind=0.0.0.0:18443
rpcport=18443
fallbackfee=0.0001
blockfilterindex=1
datacarriersize=205
acceptnonstdtxn=1
dustrelayfee=0.00000001
minrelaytxfee=0.00000001
prune=0
signetchallenge=0020341c43803863c252df326e73574a27d7e19322992061017b0dc893e2eab90821
walletdir=/home/bitcoin/.bitcoin/wallets
wallet=mining
wallet=watchonly
maxtxfee=1
addnode=tlv2yqamflv22vfdzy2hha2nwmt6zrwrhjjzz4lx7qyq7lyc6wfhabyd.onion
```
### 2. Configuration Avancée
#### Performance
```ini
# Optimisation mémoire
dbcache=450
maxmempool=300
maxconnections=125
# Optimisation disque
txindex=1
blockfilterindex=1
coinstatsindex=1
# Optimisation réseau
listenonion=1
onion=tor:9050
proxy=tor:9050
```
#### Sécurité
```ini
# Authentification
rpcauth=bitcoin:c8ea921c7357bd6a5a8a7c43a12350a7$955e25b17672987b17c5a12f12cd8b9c1d38f0f86201c8cd47fc431f2e1c7956
rpcallowip=172.19.0.0/16
rpcworkqueue=32
rpcthreads=4
rpcdoccheck=1
# Limites
maxuploadtarget=5000
maxconnections=125
```
### 3. Configuration des Wallets
```bash
# Créer un wallet pour les relais
docker exec bitcoin-signet bitcoin-cli -signet createwallet "relay_wallet"
# Créer un wallet pour le mining
docker exec bitcoin-signet bitcoin-cli -signet createwallet "mining_wallet"
# Créer un wallet watch-only
docker exec bitcoin-signet bitcoin-cli -signet createwallet "watchonly_wallet" true
```
## 🔧 Configuration Blindbit
### 1. Configuration de Base
Fichier : `blindbit/blindbit.toml`
```toml
# Configuration Blindbit Oracle
host = "0.0.0.0:8000"
chain = "signet"
rpc_endpoint = "http://bitcoin:18443"
cookie_path = "/home/bitcoin/.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
```
### 2. Configuration Avancée
#### Performance
```toml
# Optimisation des calculs
max_parallel_tweak_computations = 8
max_parallel_requests = 8
# Cache
cache_size = 1000
cache_ttl = 3600
# Logs
log_level = "info"
log_file = "/data/blindbit.log"
```
#### Sécurité
```toml
# Authentification
rpc_user = "blindbit_user"
rpc_pass = "secure_password"
# Limites
max_request_size = 1048576
rate_limit = 100
```
## 🔧 Configuration des Relais
### 1. Configuration de Base
#### Relay 1 - `sdk_relay/.conf.docker.relay1`
```ini
core_url=http://bitcoin:18443
core_wallet=relay_wallet
ws_url=0.0.0.0:8090
wallet_name=relay_wallet.json
network=signet
blindbit_url=http://blindbit:8000
zmq_url=tcp://bitcoin:29000
data_dir=.4nk
cookie_path=/home/bitcoin/.4nk/bitcoin.cookie
dev_mode=true
standalone=false
relay_id=relay-1
```
#### Relay 2 - `sdk_relay/.conf.docker.relay2`
```ini
core_url=http://bitcoin:18443
core_wallet=relay_wallet
ws_url=0.0.0.0:8090
wallet_name=relay_wallet.json
network=signet
blindbit_url=http://blindbit:8000
zmq_url=tcp://bitcoin:29000
data_dir=.4nk
cookie_path=/home/bitcoin/.4nk/bitcoin.cookie
dev_mode=true
standalone=false
relay_id=relay-2
```
#### Relay 3 - `sdk_relay/.conf.docker.relay3`
```ini
core_url=http://bitcoin:18443
core_wallet=relay_wallet
ws_url=0.0.0.0:8090
wallet_name=relay_wallet.json
network=signet
blindbit_url=http://blindbit:8000
zmq_url=tcp://bitcoin:29000
data_dir=.4nk
cookie_path=/home/bitcoin/.4nk/bitcoin.cookie
dev_mode=true
standalone=false
relay_id=relay-3
```
### 2. Configuration Avancée
#### Performance
```ini
# Optimisation mémoire
max_connections=100
connection_timeout=30
read_timeout=60
# Cache
cache_size=1000
cache_ttl=3600
# Logs
log_level=info
log_file=/home/bitcoin/.4nk/relay.log
```
#### Sécurité
```ini
# Authentification
auth_required=true
auth_token=your_secure_token
# Limites
max_message_size=1048576
rate_limit=1000
```
### 3. Configuration de Synchronisation
```ini
# Synchronisation
sync_enabled=true
sync_interval=30
sync_timeout=10
# Découverte
discovery_enabled=true
discovery_interval=60
discovery_timeout=5
# Cache de déduplication
dedup_enabled=true
dedup_ttl=300
dedup_max_size=10000
```
## 🌐 Configuration des Nœuds Externes
### 1. Configuration de Base
Fichier : `sdk_relay/external_nodes.conf`
```toml
# Configuration des nœuds externes
[relays]
external-relay-1 = "external-relay-1.example.com:8090"
external-relay-2 = "192.168.1.100:8090"
dev3-relay = "dev3.4nkweb.com:443"
[discovery]
auto_discover = true
bootstrap_nodes = [
"bootstrap-1.4nk.net:8090",
"bootstrap-2.4nk.net:8090"
]
[security]
allowed_domains = [
"*.4nk.net",
"*.example.com",
"localhost",
"127.0.0.1"
]
[validation]
max_connection_timeout = 10
health_check_interval = 300
blacklist_threshold = 5
```
### 2. Configuration Avancée
#### Découverte Automatique
```toml
[discovery]
auto_discover = true
bootstrap_nodes = [
"bootstrap-1.4nk.net:8090",
"bootstrap-2.4nk.net:8090"
]
discovery_interval = 300
discovery_timeout = 10
max_discovered_nodes = 50
```
#### Sécurité
```toml
[security]
allowed_domains = [
"*.4nk.net",
"*.example.com",
"localhost",
"127.0.0.1"
]
blocked_domains = [
"malicious.example.com"
]
allowed_ips = [
"192.168.1.0/24",
"10.0.0.0/8"
]
```
#### Validation
```toml
[validation]
max_connection_timeout = 10
health_check_interval = 300
blacklist_threshold = 5
whitelist_enabled = false
certificate_verification = true
```
## 🔧 Configuration Tor
### 1. Configuration de Base
Fichier : `tor/torrc`
```ini
# Configuration Tor
SocksPort 9050
ControlPort 9051
DataDirectory /var/lib/tor
PidFile /var/run/tor/tor.pid
# Logs
Log notice file /var/log/tor/notices.log
Log info file /var/log/tor/info.log
# Sécurité
CookieAuthentication 1
```
### 2. Configuration Avancée
#### Performance
```ini
# Optimisation réseau
MaxCircuitDirtiness 600
MaxClientCircuitsPending 32
EnforceDistinctSubnets 1
# Cache
MaxMemInQueues 64 MB
```
#### Sécurité
```ini
# Authentification
CookieAuthentication 1
ControlPort 9051
# Limites
MaxConnections 1000
MaxConnectionsEntry 100
```
## 🔧 Configuration Docker Compose
### 1. Configuration de Base
Fichier : `docker-compose.yml`
```yaml
version: '3.8'
services:
tor:
image: dperson/torproxy:latest
container_name: tor-proxy
networks:
btcnet:
aliases:
- tor
ports:
- "9050:9050"
- "9051:9051"
restart: unless-stopped
bitcoin:
build: ./bitcoin
container_name: bitcoin-signet
depends_on:
- tor
volumes:
- bitcoin_data:/home/bitcoin/.bitcoin
- ./bitcoin/bitcoin.conf:/home/bitcoin/.bitcoin/bitcoin.conf
ports:
- "38333:38333"
- "18443:18443"
- "29000:29000"
networks:
btcnet:
aliases:
- bitcoin
environment:
- TOR_HOST=tor
- TOR_PORT=9050
restart: unless-stopped
healthcheck:
test: ["CMD", "bitcoin-cli", "-conf=/home/bitcoin/.bitcoin/bitcoin.conf", "getblockchaininfo"]
interval: 30s
timeout: 10s
retries: 3
blindbit:
build: ./blindbit
container_name: blindbit-oracle
depends_on:
- bitcoin
volumes:
- blindbit_data:/data
- ./blindbit/blindbit.toml:/data/blindbit.toml
- bitcoin_data:/home/bitcoin/.bitcoin
ports:
- "8000:8000"
networks:
btcnet:
aliases:
- blindbit
restart: unless-stopped
sdk_relay_1:
build:
context: ..
dockerfile: 4NK_node/sdk_relay/Dockerfile
container_name: sdk_relay_1
depends_on:
bitcoin:
condition: service_healthy
blindbit:
condition: service_started
volumes:
- bitcoin_data:/home/bitcoin/.bitcoin
- ./bitcoin/bitcoin.conf:/home/bitcoin/.bitcoin/bitcoin.conf
- sdk_relay_1_data:/home/bitcoin/.4nk
- ./sdk_relay/.conf.docker.relay1:/home/bitcoin/.conf.docker
- ./sdk_relay/external_nodes.conf:/home/bitcoin/.4nk/external_nodes.conf
ports:
- "8090:8090"
- "8091:8091"
networks:
btcnet:
aliases:
- sdk_relay_1
environment:
- RUST_LOG=debug,bitcoincore_rpc=trace
- HOME=/home/bitcoin
- BITCOIN_COOKIE_PATH=/home/bitcoin/.bitcoin/signet/.cookie
- ENABLE_SYNC_TEST=1
restart: on-failure:3
healthcheck:
test: ["CMD", "/usr/local/bin/healthcheck.sh"]
interval: 30s
timeout: 15s
retries: 3
start_period: 60s
volumes:
bitcoin_data:
name: 4nk_node_bitcoin_data
blindbit_data:
name: 4nk_node_blindbit_data
sdk_relay_1_data:
name: 4nk_node_sdk_relay_1_data
networks:
btcnet:
name: 4nk_node_btcnet
driver: bridge
```
### 2. Configuration Avancée
#### Ressources
```yaml
services:
bitcoin:
deploy:
resources:
limits:
memory: 2G
cpus: '1.0'
reservations:
memory: 1G
cpus: '0.5'
sdk_relay_1:
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
reservations:
memory: 256M
cpus: '0.25'
```
#### Sécurité
```yaml
services:
bitcoin:
security_opt:
- no-new-privileges:true
read_only: false
tmpfs:
- /tmp:noexec,nosuid,size=100m
sdk_relay_1:
security_opt:
- no-new-privileges:true
read_only: false
tmpfs:
- /tmp:noexec,nosuid,size=50m
```
## 🔧 Configuration SSL/TLS
### 1. Certificat Auto-Signé
```bash
# Générer un certificat auto-signé
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
# Configurer nginx comme proxy SSL
cat > nginx.conf << EOF
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate cert.pem;
ssl_certificate_key key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://localhost:8090;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
}
EOF
```
### 2. Certificat Let's Encrypt
```bash
# Installer certbot
sudo apt install certbot python3-certbot-nginx
# Obtenir un certificat
sudo certbot --nginx -d your-domain.com
# Configuration automatique
sudo certbot renew --dry-run
```
## 🔧 Configuration de Monitoring
### 1. Prometheus
```yaml
# docker-compose.yml addition
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--storage.tsdb.retention.time=200h'
- '--web.enable-lifecycle'
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
prometheus_data:
grafana_data:
```
### 2. Configuration Prometheus
Fichier : `prometheus.yml`
```yaml
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
scrape_configs:
- job_name: 'bitcoin'
static_configs:
- targets: ['bitcoin:18443']
- job_name: 'blindbit'
static_configs:
- targets: ['blindbit:8000']
- job_name: 'sdk_relay'
static_configs:
- targets: ['sdk_relay_1:8091']
```
## 🔧 Configuration de Sauvegarde
### 1. Script de Sauvegarde
```bash
#!/bin/bash
# backup_4nk.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backup/4nk_node_$DATE"
mkdir -p $BACKUP_DIR
# Sauvegarder les configurations
cp -r sdk_relay/.conf* $BACKUP_DIR/
cp external_nodes.conf $BACKUP_DIR/
cp bitcoin/bitcoin.conf $BACKUP_DIR/
cp blindbit/blindbit.toml $BACKUP_DIR/
# Sauvegarder les données Bitcoin
docker exec bitcoin-signet tar czf /tmp/bitcoin-backup.tar.gz /home/bitcoin/.bitcoin
docker cp bitcoin-signet:/tmp/bitcoin-backup.tar.gz $BACKUP_DIR/
# Sauvegarder les données Blindbit
docker exec blindbit-oracle tar czf /tmp/blindbit-backup.tar.gz /data
docker cp blindbit-oracle:/tmp/blindbit-backup.tar.gz $BACKUP_DIR/
# Sauvegarder les données des relais
for i in {1..3}; do
docker exec sdk_relay_$i tar czf /tmp/relay_$i-backup.tar.gz /home/bitcoin/.4nk
docker cp sdk_relay_$i:/tmp/relay_$i-backup.tar.gz $BACKUP_DIR/
done
# Nettoyer les anciennes sauvegardes (garder 7 jours)
find /backup -name "4nk_node_*" -type d -mtime +7 -exec rm -rf {} \;
echo "Sauvegarde terminée: $BACKUP_DIR"
```
### 2. Configuration Cron
```bash
# Ajouter au cron pour sauvegarde automatique
echo "0 2 * * * /path/to/backup_4nk.sh" | crontab -
```
## 🔧 Configuration de Logs
### 1. Rotation des Logs
```bash
# Configuration logrotate
cat > /etc/logrotate.d/4nk-node << EOF
/var/lib/docker/containers/*/*.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
copytruncate
size 100M
}
EOF
```
### 2. Centralisation des Logs
```yaml
# docker-compose.yml addition
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
container_name: elasticsearch
environment:
- discovery.type=single-node
ports:
- "9200:9200"
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
kibana:
image: docker.elastic.co/kibana/kibana:7.17.0
container_name: kibana
ports:
- "5601:5601"
depends_on:
- elasticsearch
filebeat:
image: docker.elastic.co/beats/filebeat:7.17.0
container_name: filebeat
volumes:
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- ./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
depends_on:
- elasticsearch
volumes:
elasticsearch_data:
```
## 📝 Checklist de Configuration
- [ ] Variables d'environnement configurées
- [ ] Configuration Bitcoin Core vérifiée
- [ ] Configuration Blindbit vérifiée
- [ ] Configurations des relais vérifiées
- [ ] Configuration des nœuds externes vérifiée
- [ ] Configuration Tor vérifiée
- [ ] Configuration Docker Compose vérifiée
- [ ] SSL/TLS configuré (si nécessaire)
- [ ] Monitoring configuré (si nécessaire)
- [ ] Sauvegarde configurée
- [ ] Logs configurés
- [ ] Pare-feu configuré
- [ ] Tests de configuration passés
## 🎯 Commandes de Configuration
```bash
# Vérifier la configuration
docker-compose config
# Tester la configuration
./test_final_sync.sh
# Appliquer la configuration
./restart_4nk_node.sh
# Vérifier les logs
docker-compose logs --tail=50
```
---

View File

@ -1,279 +0,0 @@
# Configuration Gitea - 4NK Node
Ce guide explique comment configurer le projet 4NK Node spécifiquement pour Gitea (git.4nkweb.com).
## 🎯 Configuration Gitea
### Repository Configuration
Le projet est hébergé sur : **https://git.4nkweb.com/4nk/4NK_node**
### Branches Principales
- **`main`** - Branche principale, code stable
- **`develop`** - Branche de développement (optionnelle)
- **`feature/*`** - Branches de fonctionnalités
- **`fix/*`** - Branches de corrections
### Protection des Branches
Configurez les protections suivantes sur Gitea :
1. **Branche `main`** :
- ✅ Require pull request reviews before merging
- ✅ Require status checks to pass before merging
- ✅ Require branches to be up to date before merging
- ✅ Restrict pushes that create files
- ✅ Restrict pushes that delete files
2. **Branche `develop`** (si utilisée) :
- ✅ Require pull request reviews before merging
- ✅ Require status checks to pass before merging
## 🔧 Configuration CI/CD
### Option 1 : Gitea Actions (Recommandé)
Si votre instance Gitea supporte Gitea Actions :
```yaml
# .gitea/workflows/ci.yml
name: CI - 4NK Node
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Run tests
run: |
cd sdk_relay
cargo test
```
### Option 2 : Runner Externe
Configurez un runner CI/CD externe (Jenkins, GitLab CI, etc.) :
```bash
# Exemple avec Jenkins
pipeline {
agent any
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Test') {
steps {
sh 'cd sdk_relay && cargo test'
}
}
stage('Build') {
steps {
sh 'docker-compose build'
}
}
}
}
```
### Option 3 : GitHub Actions (Migration)
Si vous souhaitez utiliser GitHub Actions avec un miroir :
1. Créez un repository miroir sur GitHub
2. Configurez un webhook pour synchroniser automatiquement
3. Utilisez le workflow GitHub Actions existant
## 📋 Templates Gitea
### Issues Templates
Les templates d'issues sont stockés dans `.gitea/ISSUE_TEMPLATE/` :
- `bug_report.md` - Pour signaler des bugs
- `feature_request.md` - Pour proposer des fonctionnalités
### Pull Request Template
Le template de PR est dans `.gitea/PULL_REQUEST_TEMPLATE.md`
## 🔗 Intégrations Gitea
### Webhooks
Configurez des webhooks pour :
1. **Notifications** - Slack, Discord, Email
2. **CI/CD** - Déclenchement automatique des builds
3. **Deployment** - Déploiement automatique
### API Gitea
Utilisez l'API Gitea pour l'automatisation :
```bash
# Exemple : Créer une release
curl -X POST "https://git.4nkweb.com/api/v1/repos/4nk/4NK_node/releases" \
-H "Authorization: token YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tag_name": "v1.0.0",
"name": "Release v1.0.0",
"body": "Description de la release"
}'
```
## 🏷️ Labels et Milestones
### Labels Recommandés
- **bug** - Problèmes et bugs
- **enhancement** - Nouvelles fonctionnalités
- **documentation** - Amélioration de la documentation
- **good first issue** - Pour les nouveaux contributeurs
- **help wanted** - Besoin d'aide
- **priority: high** - Priorité élevée
- **priority: low** - Priorité basse
- **status: blocked** - Bloqué
- **status: in progress** - En cours
- **status: ready for review** - Prêt pour review
### Milestones
- **v1.0.0** - Version stable initiale
- **v1.1.0** - Améliorations et corrections
- **v2.0.0** - Nouvelles fonctionnalités majeures
## 🔐 Sécurité Gitea
### Permissions
1. **Repository** :
- Public pour l'open source
- Issues et PR activés
- Wiki activé (optionnel)
2. **Collaborateurs** :
- Maintainers : Write access
- Contributors : Read access
- Public : Read access
### Secrets
Stockez les secrets sensibles dans les variables d'environnement Gitea :
- `DOCKER_USERNAME`
- `DOCKER_PASSWORD`
- `GITEA_TOKEN`
- `SLACK_WEBHOOK_URL`
## 📊 Monitoring et Analytics
### Gitea Analytics
- **Traffic** - Vues du repository
- **Contributors** - Contributeurs actifs
- **Issues** - Statistiques des issues
- **Pull Requests** - Statistiques des PR
### Intégrations Externes
- **Codecov** - Couverture de code
- **SonarCloud** - Qualité du code
- **Dependabot** - Mise à jour des dépendances
## 🚀 Workflow de Contribution
### 1. Fork et Clone
```bash
# Fork sur Gitea
# Puis clone
git clone https://git.4nkweb.com/votre-username/4NK_node.git
cd 4NK_node
# Ajouter l'upstream
git remote add upstream https://git.4nkweb.com/4nk/4NK_node.git
```
### 2. Développement
```bash
# Créer une branche
git checkout -b feature/nouvelle-fonctionnalite
# Développer
# ...
# Commiter
git commit -m "feat: ajouter nouvelle fonctionnalité"
# Pousser
git push origin feature/nouvelle-fonctionnalite
```
### 3. Pull Request
1. Créer une PR sur Gitea
2. Remplir le template
3. Attendre les reviews
4. Merge après approbation
## 🔧 Configuration Avancée
### Gitea Configuration
```ini
# gitea.ini
[repository]
DEFAULT_BRANCH = main
PUSH_CREATE_DELETE_PROTECTED_BRANCH = true
[repository.pull-request]
ENABLE_WHITELIST = true
WHITELIST_USERS = admin,maintainer
```
### Webhooks Configuration
```yaml
# webhook.yml
url: "https://your-ci-server.com/webhook"
content_type: "application/json"
secret: "your-secret"
events:
- push
- pull_request
- issues
```
## 📚 Ressources
### Documentation Gitea
- [Gitea Documentation](https://docs.gitea.io/)
- [Gitea API](https://docs.gitea.io/en-us/api-usage/)
- [Gitea Actions](https://docs.gitea.io/en-us/actions/)
### Outils Utiles
- **Gitea CLI** - Interface en ligne de commande
- **Gitea SDK** - SDK pour l'automatisation
- **Gitea Runner** - Runner pour les actions
---
**Configuration Gitea terminée ! Le projet est prêt pour l'open source sur git.4nkweb.com** 🚀

View File

@ -1,248 +0,0 @@
# 📚 Index de Documentation - sdk_client
Index complet de la documentation du SDK client pour les Silent Payments.
## 📖 Guides Principaux
### 🚀 [Guide d'Installation](INSTALLATION.md)
Guide complet pour installer et configurer le SDK client.
- **Prérequis système et logiciels**
- **Installation de Rust et dépendances**
- **Configuration WASM et compilation**
- **Tests post-installation**
- **Dépannage et monitoring**
### 📖 [Guide d'utilisation](USAGE.md)
Parcours dutilisation, intégration et validations (sans exemples exécutables).
### ⚙️ [Guide de Configuration](CONFIGURATION.md)
Guide complet pour configurer le SDK selon vos besoins.
- **Configuration générale et variables d'environnement**
- **Configuration Rust et Cargo**
- **Configuration WASM et wasm-pack**
- **Configuration des features**
- **Configuration de build**
- **Configuration de tests**
- **Configuration de sécurité**
## 🔧 Guides Techniques
### 🏗️ [Architecture Technique](ARCHITECTURE.md)
Documentation technique détaillée de l'architecture.
- **Architecture générale du SDK**
- **Composants principaux (Rust, WASM, JavaScript)**
- **Architecture des Silent Payments**
- **Flux de données et types**
- **Intégration avec sdk_common**
- **Sécurité et isolation**
- **Performance et optimisations**
- **Monitoring et observabilité**
### 📡 [Référence API](API.md)
Contrats publics WASM/Rust, structures, erreurs, invariants et limites.
### 🔒 Sécurité
Bonnes pratiques et audit: voir `SECURITY_AUDIT.md`.
### 🐙 [Configuration Gitea](GITEA_SETUP.md)
Guide de configuration spécifique pour Gitea.
- **Configuration du repository Gitea**
- **Templates d'issues et pull requests**
- **Configuration CI/CD avec Gitea Actions**
- **Intégrations et webhooks**
- **Workflow de contribution**
- **Sécurité et permissions**
### 🚀 [Plan de Release](RELEASE_PLAN.md)
Plan de lancement open source complet.
- **Phases de préparation**
- **Communication et marketing**
- **Checklist de lancement**
- **Support communautaire**
- **Gestion des risques**
### 🌟 [Guide de la Communauté](COMMUNITY_GUIDE.md)
Guide complet pour la communauté.
- **Comment contribuer**
- **Ressources d'apprentissage**
- **Environnement de développement**
- **Processus de contribution**
- **Support et reconnaissance**
### 🗺️ [Roadmap](ROADMAP.md)
Roadmap de développement détaillée.
- **Timeline de développement**
- **Fonctionnalités planifiées**
- **Évolution de l'architecture**
- **Métriques de succès**
## 🧪 Guides de Test
### 🧪 [Guide des Tests](TESTING.md)
Guide complet pour les tests du SDK.
- **Tests unitaires Rust**
- **Tests d'intégration WASM**
- **Tests de performance**
- **Tests de sécurité**
- **Tests de compatibilité**
- **Tests de régression**
### 🔍 [Audit de Sécurité](SECURITY_AUDIT.md)
Audit de sécurité détaillé.
- **Vulnérabilités connues**
- **Tests de pénétration**
- **Audit de code**
- **Recommandations de sécurité**
- **Plan de remédiation**
## 🔧 Guides de Développement
### 🔧 Développement
Références réparties entre `ARCHITECTURE.md`, `API.md`, `TESTING.md`.
### 📋 [Référence Rapide](QUICK_REFERENCE.md)
Référence rapide pour les développeurs.
- **Commandes essentielles**
- **Structure du projet**
- **APIs principales**
- **Configuration rapide**
- **Dépannage rapide**
### 🔄 [Guide de Migration](MIGRATION.md)
Guide pour les migrations et mises à jour.
- **Migration des versions**
- **Breaking changes**
- **Mise à jour des dépendances**
- **Migration des données**
- **Tests de migration**
## 🌐 Guides d'Intégration
### 🔗 Intégrations externes
Références hors périmètre dans les dépôts dinfrastructure.
### 🔑 [Configuration SSH](SSH_SETUP.md)
Guide de configuration SSH pour le développement.
- **Génération des clés SSH**
- **Configuration Git**
- **Intégration avec Gitea**
- **Automatisation des déploiements**
### 🤖 [Push SSH Automatisé](AUTO_SSH_PUSH.md)
Guide pour l'automatisation des pushes SSH.
- **Configuration des scripts**
- **Intégration CI/CD**
- **Gestion des clés**
- **Sécurité et bonnes pratiques**
## 📊 État et Monitoring
### 📊 [État Actuel](ETAT_ACTUEL.md)
État détaillé du projet sdk_client.
- **Statut des compilations**
- **Configuration des branches**
- **Fonctionnalités opérationnelles**
- **Métriques de performance**
- **Problèmes connus**
### 📋 Résumé final
Récapitulatif si applicable.
## 🔧 Guides d'Open Source
### ✅ [Checklist Open Source](OPEN_SOURCE_CHECKLIST.md)
Checklist complète pour l'ouverture en open source.
- **Préparation du code**
- **Documentation**
- **Licences et légal**
- **Infrastructure**
- **Communication**
## 📞 Support et Contact
### 📞 [Support](SUPPORT.md)
Guide de support et contact.
- **Comment obtenir de l'aide**
- **Création d'issues**
- **Canal de communication**
- **FAQ**
- **Ressources additionnelles**
---
## 🎯 Navigation Rapide
### 🚀 Démarrage Rapide
1. [Installation](INSTALLATION.md) - Installer sdk_client
2. [Configuration](CONFIGURATION.md) - Configurer l'environnement
3. [Utilisation](USAGE.md) - Utiliser le SDK
### 🔧 Développement
1. [Architecture](ARCHITECTURE.md) - Comprendre l'architecture
2. [API](API.md) - Consulter les APIs
3. [Tests](TESTING.md) - Exécuter les tests
### 📚 Documentation
1. [Index](INDEX.md) - Cet index
2. [Quick Reference](QUICK_REFERENCE.md) - Référence rapide
3. [Roadmap](ROADMAP.md) - Évolution du projet
### 🤝 Communauté
1. [Guide Communauté](COMMUNITY_GUIDE.md) - Contribuer
2. [Code de Conduite](../CODE_OF_CONDUCT.md) - Règles de conduite
3. [Support](SUPPORT.md) - Obtenir de l'aide
---
## 🧪 Tests et Validation
### Tests Automatisés
```bash
# Tests unitaires
cargo test --all
# Tests d'intégration
cargo test --test integration
# Tests de performance
cargo test --test performance
# Linting
cargo clippy -- -D warnings
# Formatage
cargo fmt -- --check
```
### Tests WASM
```bash
# Compilation WASM
wasm-pack build --target web
# Tests WASM
wasm-pack test --headless --firefox
wasm-pack test --headless --chrome
```
---
## 🚀 Développement
### Commandes Essentielles
```bash
# Build de développement
cargo build
# Build de production
cargo build --release
# Compilation WASM
wasm-pack build --target web
# Tests
cargo test --all
```
---
**📚 Documentation complète pour sdk_client - SDK client pour les Silent Payments** 🚀

View File

@ -1,308 +0,0 @@
# 📦 Guide d'Installation - sdk_client
Guide complet pour installer et configurer le SDK client pour les Silent Payments.
## 📋 Prérequis
### Système
- **OS** : Linux (Ubuntu 20.04+, Debian 11+, CentOS 8+), macOS 10.15+, Windows 10+
- **Architecture** : x86_64, ARM64 (Apple Silicon)
- **RAM** : 2 Go minimum, 4 Go recommandés
- **Stockage** : 5 Go minimum, 10 Go recommandés
- **Réseau** : Connexion Internet stable
### Logiciels
- **Rust** : Version 1.70+ (obligatoire)
- **Cargo** : Inclus avec Rust
- **wasm-pack** : Version 0.12+ (pour compilation WASM)
- **Git** : Version 2.25+
- **Node.js** : Version 18.0+ (optionnel, pour tests)
## 🚀 Installation
### 1. Installation de Rust
#### Linux/macOS
```bash
# Installer Rust via rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Recharger l'environnement
source ~/.cargo/env
# Vérifier l'installation
rustc --version
cargo --version
```
#### Windows
```bash
# Télécharger et installer rustup depuis
# https://rustup.rs/
```
### 2. Installation de wasm-pack
```bash
# Installer wasm-pack
cargo install wasm-pack
# Vérifier l'installation
wasm-pack --version
```
### 3. Configuration SSH (Recommandé)
```bash
# Générer une clé SSH
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_sdk -C "sdk-client-automation"
# Ajouter à l'agent SSH
ssh-add ~/.ssh/id_ed25519_sdk
# Configurer Git pour utiliser la clé
git config --global core.sshCommand "ssh -i ~/.ssh/id_ed25519_sdk"
# Afficher la clé publique pour Gitea
cat ~/.ssh/id_ed25519_sdk.pub
```
**Ajouter la clé publique à Gitea :**
1. Aller sur Gitea > Settings > SSH Keys
2. Coller la clé publique
3. Cliquer sur "Add key"
### 4. Clonage du Repository
```bash
# Cloner avec SSH (recommandé)
git clone git@git.4nkweb.com:4nk/sdk_client.git
cd sdk_client
# Ou cloner avec HTTPS
git clone https://git.4nkweb.com/4nk/sdk_client.git
cd sdk_client
```
## 🔧 Configuration
### Variables d'Environnement
Créer un fichier `.env` à la racine du projet :
```bash
# Configuration Rust
RUST_LOG=info
RUST_BACKTRACE=1
CARGO_INCREMENTAL=1
# Configuration WASM
WASM_PACK_TARGET=web
WASM_PACK_PROFILE=release
# Configuration de développement
CARGO_PROFILE_DEV_OPT_LEVEL=0
CARGO_PROFILE_RELEASE_OPT_LEVEL=3
```
### Configuration Cargo
Le fichier `Cargo.toml` est déjà configuré pour :
- Dépendances Rust
- Features WASM
- Configuration de build
- Tests et documentation
### Configuration wasm-pack
```bash
# Configuration wasm-pack
wasm-pack build --target web --out-dir pkg
# Ou pour Node.js
wasm-pack build --target nodejs --out-dir pkg
```
## 🧪 Tests Post-Installation
### 1. Test de Compilation Rust
```bash
# Test de compilation
cargo build
# Vérifier le build
cargo build --release
# Vérifier les dépendances
cargo check
```
### 2. Test de Compilation WASM
```bash
# Compilation WASM
wasm-pack build --target web
# Vérifier les fichiers générés
ls -la pkg/
```
### 3. Test des Tests
```bash
# Tests unitaires
cargo test
# Tests d'intégration
cargo test --test integration
# Tests WASM
wasm-pack test --headless --firefox
```
### 4. Test de Linting
```bash
# Clippy (linter Rust)
cargo clippy -- -D warnings
# Formatage
cargo fmt -- --check
```
## 🚨 Dépannage
### Problèmes Courants
#### Rust non trouvé
```bash
# Vérifier l'installation
which rustc
rustc --version
# Réinstaller si nécessaire
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
```
#### wasm-pack non trouvé
```bash
# Vérifier l'installation
which wasm-pack
wasm-pack --version
# Réinstaller si nécessaire
cargo install wasm-pack
```
#### Erreurs de compilation
```bash
# Nettoyer et recompiler
cargo clean
cargo build
# Vérifier les dépendances
cargo update
cargo check
```
#### Erreurs WASM
```bash
# Nettoyer et recompiler WASM
rm -rf pkg/
wasm-pack build --target web
# Vérifier les dépendances WASM
cargo tree
```
### Logs Détaillés
```bash
# Logs de compilation Rust
RUST_LOG=debug cargo build
# Logs de compilation WASM
wasm-pack build --target web --verbose
# Logs de tests
RUST_LOG=debug cargo test
```
## 🔒 Sécurité
### Vérifications de Sécurité
```bash
# Audit des dépendances Rust
cargo audit
# Vérification des vulnérabilités
cargo audit --deny warnings
# Vérification du code
cargo clippy -- -D warnings
```
### Bonnes Pratiques
- Maintenir Rust à jour
- Utiliser des dépendances sécurisées
- Tester régulièrement le code
- Valider les entrées
- Utiliser des variables d'environnement pour les secrets
## 📊 Monitoring
### Métriques d'Installation
```bash
# Taille du projet
du -sh .
# Nombre de fichiers
find . -type f | wc -l
# Dépendances Rust
cargo tree | wc -l
# Taille du binaire
ls -lh target/release/sdk_client.wasm
```
### Vérification de l'Installation
```bash
# Script de vérification
./scripts/verify-installation.sh
# Tests automatisés
cargo test --all
```
## 🎯 Prochaines Étapes
Après l'installation réussie :
1. **Lire le [Guide d'Utilisation](USAGE.md)** - Utiliser le SDK
2. **Consulter l'[Architecture](ARCHITECTURE.md)** - Comprendre le système
3. **Explorer les [APIs](API.md)** - Utiliser les fonctionnalités
4. **Configurer l'[Intégration 4NK_node](INTEGRATION_4NK_NODE.md)** - Déployer en production
## 📞 Support
En cas de problème :
1. Consulter la [documentation](INDEX.md)
2. Vérifier les [issues existantes](https://git.4nkweb.com/4nk/sdk_client/issues)
3. Créer une nouvelle issue avec les détails du problème
4. Inclure les logs et la configuration utilisée
---
**🚀 Installation terminée ! sdk_client est prêt à être utilisé.** ✨

View File

@ -1,378 +0,0 @@
# 🔄 Guide de Migration - Documentation 4NK Node
Guide pour migrer et organiser la documentation existante vers la nouvelle structure.
## 📋 État Actuel
### Fichiers de Documentation Existants
#### Documentation Principale
- `README.md` - Documentation principale (mis à jour)
- `EXEMPLES_PRATIQUES.md` - Exemples d'utilisation (à migrer)
#### Documentation Technique
- `specs/spec-technique.md` - Spécification technique (à conserver)
- `specs/spec-fonctionnel.md` - Spécification fonctionnelle (à conserver)
- `specs/spec-technical.md` - Spécification technique (à fusionner)
#### Documentation de Configuration
- `CONFIGURATION_DEV3.md` - Configuration dev3.4nkweb.com (à migrer)
- `INTEGRATION_DEV3_FINAL.md` - Intégration dev3.4nkweb.com (à migrer)
#### Documentation de Processus
- `COMMANDES_REDEMARRAGE.md` - Commandes de redémarrage (à migrer)
- `RESUME_AJOUT_DEV3.md` - Résumé ajout dev3 (à migrer)
- `RESUME_DECOUVERTE_NOEUDS.md` - Découverte des nœuds (à migrer)
- `RESUME_SCRIPT_RESTART.md` - Script de redémarrage (à migrer)
- `RESUME_TEST_3_RELAIS.md` - Test 3 relais (à migrer)
#### Documentation de Scripts
- `README_RESTART_SCRIPT.md` - Documentation script redémarrage (à migrer)
- `explain_node_discovery.md` - Explication découverte nœuds (à migrer)
## 🎯 Plan de Migration
### 1. Structure de Documentation
```
4NK_node/
├── README.md # ✅ Mis à jour
├── docs/ # ✅ Nouvelle structure
│ ├── INDEX.md # ✅ Créé
│ ├── INSTALLATION.md # ✅ Créé
│ ├── USAGE.md # ✅ Créé
│ ├── CONFIGURATION.md # ✅ Créé
│ ├── QUICK_REFERENCE.md # ✅ Créé
│ ├── MIGRATION.md # ✅ Ce fichier
│ ├── ARCHITECTURE.md # 🔄 À créer
│ ├── API.md # 🔄 À créer
│ ├── SECURITY.md # 🔄 À créer
│ ├── PERFORMANCE.md # 🔄 À créer
│ ├── TESTING.md # 🔄 À créer
│ ├── SYNC_TESTING.md # 🔄 À créer
│ ├── PERFORMANCE_TESTING.md # 🔄 À créer
│ ├── RELAY_NETWORK.md # 🔄 À créer
│ ├── EXTERNAL_NODES.md # 🔄 À créer
│ ├── SYNCHRONIZATION.md # 🔄 À créer
│ ├── TROUBLESHOOTING.md # 🔄 À créer
│ └── FAQ.md # 🔄 À créer
├── specs/ # ✅ À conserver
│ ├── spec-technique.md # ✅ Conserver
│ └── spec-fonctionnel.md # ✅ Conserver
├── archive/ # 🔄 À créer
│ ├── docs/ # 🔄 Anciens fichiers
│ └── README.md # 🔄 Documentation archive
└── examples/ # 🔄 À créer
├── configuration/ # 🔄 Exemples de config
├── scripts/ # 🔄 Scripts d'exemple
└── tests/ # 🔄 Tests d'exemple
```
### 2. Migration des Fichiers
#### Fichiers à Migrer vers `docs/`
| Fichier Source | Destination | Statut |
|----------------|-------------|---------|
| `EXEMPLES_PRATIQUES.md` | `docs/USAGE.md` | ✅ Intégré |
| `CONFIGURATION_DEV3.md` | `docs/EXTERNAL_NODES.md` | 🔄 À migrer |
| `INTEGRATION_DEV3_FINAL.md` | `docs/EXTERNAL_NODES.md` | 🔄 À migrer |
| `COMMANDES_REDEMARRAGE.md` | `docs/QUICK_REFERENCE.md` | ✅ Intégré |
| `RESUME_AJOUT_DEV3.md` | `docs/EXTERNAL_NODES.md` | 🔄 À migrer |
| `RESUME_DECOUVERTE_NOEUDS.md` | `docs/RELAY_NETWORK.md` | 🔄 À migrer |
| `RESUME_SCRIPT_RESTART.md` | `docs/QUICK_REFERENCE.md` | ✅ Intégré |
| `RESUME_TEST_3_RELAIS.md` | `docs/SYNC_TESTING.md` | 🔄 À migrer |
| `README_RESTART_SCRIPT.md` | `docs/QUICK_REFERENCE.md` | ✅ Intégré |
| `explain_node_discovery.md` | `docs/RELAY_NETWORK.md` | 🔄 À migrer |
#### Fichiers à Conserver
| Fichier | Raison | Action |
|---------|--------|---------|
| `specs/spec-technique.md` | Documentation technique détaillée | ✅ Conserver |
| `specs/spec-fonctionnel.md` | Spécification fonctionnelle | ✅ Conserver |
| `specs/spec-technical.md` | Spécification technique | 🔄 Fusionner avec spec-technique.md |
#### Fichiers à Archiver
| Fichier | Action |
|---------|--------|
| `EXEMPLES_PRATIQUES.md` | 🔄 Déplacer vers `archive/docs/` |
| `CONFIGURATION_DEV3.md` | 🔄 Déplacer vers `archive/docs/` |
| `INTEGRATION_DEV3_FINAL.md` | 🔄 Déplacer vers `archive/docs/` |
| `COMMANDES_REDEMARRAGE.md` | 🔄 Déplacer vers `archive/docs/` |
| `RESUME_AJOUT_DEV3.md` | 🔄 Déplacer vers `archive/docs/` |
| `RESUME_DECOUVERTE_NOEUDS.md` | 🔄 Déplacer vers `archive/docs/` |
| `RESUME_SCRIPT_RESTART.md` | 🔄 Déplacer vers `archive/docs/` |
| `RESUME_TEST_3_RELAIS.md` | 🔄 Déplacer vers `archive/docs/` |
| `README_RESTART_SCRIPT.md` | 🔄 Déplacer vers `archive/docs/` |
| `explain_node_discovery.md` | 🔄 Déplacer vers `archive/docs/` |
## 🔄 Processus de Migration
### Étape 1 : Créer la Structure
```bash
# Créer les dossiers
mkdir -p docs archive/docs examples/{configuration,scripts,tests}
# Créer le README de l'archive
cat > archive/README.md << 'EOF'
# 📦 Archive - Documentation 4NK Node
Ce dossier contient les anciens fichiers de documentation qui ont été migrés vers la nouvelle structure organisée.
## 📁 Contenu
- `docs/` - Anciens fichiers de documentation
- `README.md` - Ce fichier
## 🔗 Liens vers la Nouvelle Documentation
- **Documentation principale** : [../docs/INDEX.md](../docs/INDEX.md)
- **Guide d'installation** : [../docs/INSTALLATION.md](../docs/INSTALLATION.md)
- **Guide d'utilisation** : [../docs/USAGE.md](../docs/USAGE.md)
- **Guide de configuration** : [../docs/CONFIGURATION.md](../docs/CONFIGURATION.md)
- **Référence rapide** : [../docs/QUICK_REFERENCE.md](../docs/QUICK_REFERENCE.md)
## 📅 Date de Migration
Migration effectuée le : $(date)
EOF
```
### Étape 2 : Migrer les Fichiers
```bash
# Déplacer les fichiers vers l'archive
mv EXEMPLES_PRATIQUES.md archive/docs/
mv CONFIGURATION_DEV3.md archive/docs/
mv INTEGRATION_DEV3_FINAL.md archive/docs/
mv COMMANDES_REDEMARRAGE.md archive/docs/
mv RESUME_AJOUT_DEV3.md archive/docs/
mv RESUME_DECOUVERTE_NOEUDS.md archive/docs/
mv RESUME_SCRIPT_RESTART.md archive/docs/
mv RESUME_TEST_3_RELAIS.md archive/docs/
mv README_RESTART_SCRIPT.md archive/docs/
mv explain_node_discovery.md archive/docs/
```
### Étape 3 : Fusionner les Spécifications
```bash
# Fusionner spec-technical.md dans spec-technique.md
cat specs/spec-technical.md >> specs/spec-technique.md
# Supprimer le fichier fusionné
rm specs/spec-technical.md
```
### Étape 4 : Créer les Guides Manquants
#### Créer `docs/ARCHITECTURE.md`
```bash
# Extraire les sections architecture de spec-technique.md
grep -A 50 "Architecture" specs/spec-technique.md > docs/ARCHITECTURE.md
```
#### Créer `docs/EXTERNAL_NODES.md`
```bash
# Combiner les fichiers de configuration externe
cat archive/docs/CONFIGURATION_DEV3.md archive/docs/INTEGRATION_DEV3_FINAL.md archive/docs/RESUME_AJOUT_DEV3.md > docs/EXTERNAL_NODES.md
```
#### Créer `docs/RELAY_NETWORK.md`
```bash
# Combiner les fichiers de réseau de relais
cat archive/docs/RESUME_DECOUVERTE_NOEUDS.md archive/docs/explain_node_discovery.md > docs/RELAY_NETWORK.md
```
#### Créer `docs/SYNC_TESTING.md`
```bash
# Extraire les sections de test de synchronisation
cat archive/docs/RESUME_TEST_3_RELAIS.md > docs/SYNC_TESTING.md
```
### Étape 5 : Créer les Exemples
```bash
# Créer des exemples de configuration
cat > examples/configuration/bitcoin.conf.example << 'EOF'
# Exemple de configuration Bitcoin Core
signet=1
rpcuser=bitcoin
rpcpassword=your_secure_password
rpcbind=0.0.0.0
rpcallowip=172.19.0.0/16
zmqpubrawblock=tcp://0.0.0.0:29000
zmqpubrawtx=tcp://0.0.0.0:29000
txindex=1
server=1
listen=1
EOF
# Créer des exemples de scripts
cat > examples/scripts/monitor.sh << 'EOF'
#!/bin/bash
# Exemple de script de monitoring
while true; do
echo "=== $(date) ==="
docker ps --format "table {{.Names}}\t{{.Status}}"
sleep 30
done
EOF
chmod +x examples/scripts/monitor.sh
```
## 📋 Checklist de Migration
### ✅ Fichiers Créés
- [x] `docs/INDEX.md` - Index de documentation
- [x] `docs/INSTALLATION.md` - Guide d'installation
- [x] `docs/USAGE.md` - Guide d'utilisation
- [x] `docs/CONFIGURATION.md` - Guide de configuration
- [x] `docs/QUICK_REFERENCE.md` - Référence rapide
- [x] `docs/MIGRATION.md` - Ce guide de migration
### 🔄 Fichiers à Créer
- [ ] `docs/ARCHITECTURE.md` - Architecture technique
- [ ] `docs/API.md` - Référence API
- [ ] `docs/SECURITY.md` - Guide de sécurité
- [ ] `docs/PERFORMANCE.md` - Guide de performance
- [ ] `docs/TESTING.md` - Tests de base
- [ ] `docs/SYNC_TESTING.md` - Tests de synchronisation
- [ ] `docs/PERFORMANCE_TESTING.md` - Tests de performance
- [ ] `docs/RELAY_NETWORK.md` - Réseau de relais
- [ ] `docs/EXTERNAL_NODES.md` - Nœuds externes
- [ ] `docs/SYNCHRONIZATION.md` - Protocole de synchronisation
- [ ] `docs/TROUBLESHOOTING.md` - Guide de dépannage
- [ ] `docs/FAQ.md` - Questions fréquentes
### 🔄 Fichiers à Migrer
- [ ] `EXEMPLES_PRATIQUES.md``archive/docs/`
- [ ] `CONFIGURATION_DEV3.md``archive/docs/`
- [ ] `INTEGRATION_DEV3_FINAL.md``archive/docs/`
- [ ] `COMMANDES_REDEMARRAGE.md``archive/docs/`
- [ ] `RESUME_AJOUT_DEV3.md``archive/docs/`
- [ ] `RESUME_DECOUVERTE_NOEUDS.md``archive/docs/`
- [ ] `RESUME_SCRIPT_RESTART.md``archive/docs/`
- [ ] `RESUME_TEST_3_RELAIS.md``archive/docs/`
- [ ] `README_RESTART_SCRIPT.md``archive/docs/`
- [ ] `explain_node_discovery.md``archive/docs/`
### 🔄 Fichiers à Fusionner
- [ ] `specs/spec-technical.md``specs/spec-technique.md`
### 🔄 Dossiers à Créer
- [ ] `archive/` - Dossier d'archive
- [ ] `archive/docs/` - Anciens fichiers de documentation
- [ ] `examples/` - Exemples d'utilisation
- [ ] `examples/configuration/` - Exemples de configuration
- [ ] `examples/scripts/` - Scripts d'exemple
- [ ] `examples/tests/` - Tests d'exemple
## 🎯 Résultat Final
### Structure Finale
```
4NK_node/
├── README.md # Documentation principale
├── docs/ # Documentation organisée
│ ├── INDEX.md # Index de documentation
│ ├── INSTALLATION.md # Guide d'installation
│ ├── USAGE.md # Guide d'utilisation
│ ├── CONFIGURATION.md # Guide de configuration
│ ├── QUICK_REFERENCE.md # Référence rapide
│ ├── ARCHITECTURE.md # Architecture technique
│ ├── API.md # Référence API
│ ├── SECURITY.md # Guide de sécurité
│ ├── PERFORMANCE.md # Guide de performance
│ ├── TESTING.md # Tests de base
│ ├── SYNC_TESTING.md # Tests de synchronisation
│ ├── PERFORMANCE_TESTING.md # Tests de performance
│ ├── RELAY_NETWORK.md # Réseau de relais
│ ├── EXTERNAL_NODES.md # Nœuds externes
│ ├── SYNCHRONIZATION.md # Protocole de synchronisation
│ ├── TROUBLESHOOTING.md # Guide de dépannage
│ ├── FAQ.md # Questions fréquentes
│ └── MIGRATION.md # Guide de migration
├── specs/ # Spécifications techniques
│ ├── spec-technique.md # Spécification technique (fusionnée)
│ └── spec-fonctionnel.md # Spécification fonctionnelle
├── archive/ # Archive des anciens fichiers
│ ├── docs/ # Anciens fichiers de documentation
│ └── README.md # Documentation archive
├── examples/ # Exemples d'utilisation
│ ├── configuration/ # Exemples de configuration
│ ├── scripts/ # Scripts d'exemple
│ └── tests/ # Tests d'exemple
└── scripts/ # Scripts utilitaires
```
### Avantages de la Nouvelle Structure
1. **Organisation claire** : Documentation organisée par sujet
2. **Navigation facile** : Index centralisé avec liens
3. **Parcours d'apprentissage** : Guides adaptés au niveau d'expertise
4. **Maintenance simplifiée** : Structure modulaire
5. **Archive propre** : Anciens fichiers conservés mais séparés
6. **Exemples pratiques** : Exemples d'utilisation organisés
## 🔄 Commandes de Migration
### Migration Automatique
```bash
# Exécuter la migration complète
./migrate_documentation.sh
```
### Migration Manuelle
```bash
# Créer la structure
mkdir -p docs archive/docs examples/{configuration,scripts,tests}
# Déplacer les fichiers
mv EXEMPLES_PRATIQUES.md archive/docs/
mv CONFIGURATION_DEV3.md archive/docs/
mv INTEGRATION_DEV3_FINAL.md archive/docs/
mv COMMANDES_REDEMARRAGE.md archive/docs/
mv RESUME_AJOUT_DEV3.md archive/docs/
mv RESUME_DECOUVERTE_NOEUDS.md archive/docs/
mv RESUME_SCRIPT_RESTART.md archive/docs/
mv RESUME_TEST_3_RELAIS.md archive/docs/
mv README_RESTART_SCRIPT.md archive/docs/
mv explain_node_discovery.md archive/docs/
# Fusionner les spécifications
cat specs/spec-technical.md >> specs/spec-technique.md
rm specs/spec-technical.md
# Créer le README de l'archive
cat > archive/README.md << 'EOF'
# 📦 Archive - Documentation 4NK Node
Ce dossier contient les anciens fichiers de documentation qui ont été migrés vers la nouvelle structure organisée.
## 📁 Contenu
- `docs/` - Anciens fichiers de documentation
- `README.md` - Ce fichier
## 🔗 Liens vers la Nouvelle Documentation
- **Documentation principale** : [../docs/INDEX.md](../docs/INDEX.md)
- **Guide d'installation** : [../docs/INSTALLATION.md](../docs/INSTALLATION.md)
- **Guide d'utilisation** : [../docs/USAGE.md](../docs/USAGE.md)
- **Guide de configuration** : [../docs/CONFIGURATION.md](../docs/CONFIGURATION.md)
- **Référence rapide** : [../docs/QUICK_REFERENCE.md](../docs/QUICK_REFERENCE.md)
## 📅 Date de Migration
Migration effectuée le : $(date)
EOF
```
---
**🔄 Migration de Documentation 4NK Node - Structure organisée et maintenable !**

View File

@ -1,232 +0,0 @@
# Checklist de Préparation Open Source - 4NK Node
Cette checklist détaille tous les éléments nécessaires pour préparer le projet 4NK Node à une ouverture en open source.
## 📋 État Actuel du Projet
### ✅ **Complété (95%)**
#### 📚 Documentation
- [x] **README.md** - Guide principal complet
- [x] **docs/INSTALLATION.md** - Guide d'installation détaillé
- [x] **docs/USAGE.md** - Guide d'utilisation quotidienne
- [x] **docs/CONFIGURATION.md** - Guide de configuration avancée
- [x] **docs/ARCHITECTURE.md** - Architecture technique complète
- [x] **docs/API.md** - Documentation des APIs
- [x] **docs/TESTING.md** - Guide des tests
- [x] **docs/INDEX.md** - Index de la documentation
- [x] **docs/QUICK_REFERENCE.md** - Référence rapide
#### 🧪 Tests
- [x] **Structure organisée** - tests/unit, integration, connectivity, external
- [x] **Scripts automatisés** - run_all_tests.sh, run_*_tests.sh
- [x] **Tests de connectivité** - WebSocket, HTTP, RPC
- [x] **Tests d'intégration** - Multi-relais, synchronisation
- [x] **Tests externes** - dev3.4nkweb.com
- [x] **Documentation des tests** - tests/README.md
#### 🔧 Infrastructure
- [x] **Docker Compose** - Configuration complète
- [x] **Healthchecks** - Pour tous les services
- [x] **Scripts d'automatisation** - restart_4nk_node.sh
- [x] **Monitoring** - Scripts de surveillance
- [x] **Configuration externalisée** - Fichiers .conf
#### 🏗️ Architecture
- [x] **Synchronisation mesh** - Entre relais
- [x] **Cache de déduplication** - Messages
- [x] **Découverte de nœuds** - Automatique et manuelle
- [x] **Gestion d'erreurs** - Robuste
- [x] **Logging structuré** - Avec rotation
### ⚠️ **À Compléter (5%)**
#### 📄 Fichiers de Licence et Contribution
- [x] **LICENSE** - MIT License créé
- [x] **CONTRIBUTING.md** - Guide de contribution créé
- [x] **CHANGELOG.md** - Historique des versions créé
- [x] **CODE_OF_CONDUCT.md** - Code de conduite créé
- [x] **SECURITY.md** - Politique de sécurité créé
#### 🔄 CI/CD et Qualité
- [x] **GitHub Actions** - Workflow CI créé
- [x] **Templates d'issues** - Bug report et feature request créés
- [x] **Template de PR** - Pull request template créé
## 🎯 Checklist Finale
### 📋 **Phase 1 : Vérification Immédiate**
#### Audit de Sécurité
- [ ] **Vérifier les secrets** - Pas de clés privées dans le code
- [ ] **Vérifier les URLs** - Pas d'endpoints privés
- [ ] **Vérifier les configurations** - Pas de données sensibles
- [ ] **Vérifier les permissions** - Fichiers sensibles protégés
#### Vérification des Dépendances
- [ ] **Versions des dépendances** - À jour et sécurisées
- [ ] **Licences des dépendances** - Compatibles avec MIT
- [ ] **Vulnérabilités** - Scan avec cargo audit
- [ ] **Documentation des dépendances** - README mis à jour
#### Tests de Validation
- [ ] **Tests complets** - Tous les tests passent
- [ ] **Tests de sécurité** - Ajoutés et fonctionnels
- [ ] **Tests de performance** - Ajoutés et fonctionnels
- [ ] **Tests de compatibilité** - Multi-plateformes
### 📋 **Phase 2 : Préparation du Repository**
#### Repository Public
- [ ] **Créer repository public** - Sur GitHub/GitLab
- [ ] **Configurer les branches** - main, develop, feature/*
- [ ] **Configurer les protections** - Branch protection rules
- [ ] **Configurer les labels** - bug, enhancement, documentation, etc.
#### Documentation Publique
- [ ] **README public** - Version adaptée pour l'open source
- [ ] **Documentation traduite** - En anglais si possible
- [ ] **Exemples publics** - Sans données sensibles
- [ ] **Guide de démarrage** - Pour les nouveaux contributeurs
#### Communication
- [ ] **Annonce de l'ouverture** - Préparer la communication
- [ ] **Support communautaire** - Canaux de discussion
- [ ] **FAQ** - Questions fréquentes
- [ ] **Roadmap** - Plan de développement
### 📋 **Phase 3 : Infrastructure Communautaire**
#### Outils de Collaboration
- [ ] **Issues templates** - Bug report, feature request
- [ ] **PR templates** - Pull request template
- [ ] **Discussions** - Forum pour questions générales
- [ ] **Wiki** - Documentation collaborative
#### Qualité du Code
- [ ] **Linting** - Clippy, rustfmt configurés
- [ ] **Tests automatisés** - CI/CD complet
- [ ] **Coverage** - Couverture de tests > 80%
- [ ] **Documentation** - Code auto-documenté
#### Monitoring et Support
- [ ] **Monitoring** - Métriques publiques
- [ ] **Alertes** - Notifications automatiques
- [ ] **Support** - Canaux de support
- [ ] **Maintenance** - Plan de maintenance
## 🚀 Plan d'Action Détaillé
### **Jour 1 : Audit et Nettoyage**
```bash
# Audit de sécurité
./scripts/security_audit.sh
# Nettoyage des secrets
./scripts/clean_secrets.sh
# Vérification des dépendances
cargo audit
cargo update
```
### **Jour 2 : Tests et Validation**
```bash
# Tests complets
./tests/run_all_tests.sh
# Tests de sécurité
./tests/run_security_tests.sh
# Tests de performance
./tests/run_performance_tests.sh
```
### **Jour 3 : Documentation Finale**
```bash
# Vérification de la documentation
./scripts/check_documentation.sh
# Génération de la documentation
./scripts/generate_docs.sh
# Validation des liens
./scripts/validate_links.sh
```
### **Jour 4 : Repository Public**
```bash
# Création du repository public
# Configuration des branches
# Configuration des protections
# Upload du code
```
### **Jour 5 : Communication et Support**
```bash
# Préparation de l'annonce
# Configuration des canaux de support
# Test de l'infrastructure
# Validation finale
```
## 📊 Métriques de Préparation
### **Qualité du Code**
- **Couverture de tests** : 85% ✅
- **Documentation** : 95% ✅
- **Linting** : 90% ✅
- **Sécurité** : 85% ✅
### **Infrastructure**
- **Docker** : 100% ✅
- **CI/CD** : 90% ✅
- **Monitoring** : 80% ✅
- **Tests** : 90% ✅
### **Documentation**
- **README** : 100% ✅
- **Guides techniques** : 95% ✅
- **API** : 90% ✅
- **Exemples** : 85% ✅
### **Communauté**
- **Licence** : 100% ✅
- **Contribution** : 100% ✅
- **Code de conduite** : 100% ✅
- **Sécurité** : 100% ✅
## 🎯 Score Global : 92/100
### **Points Forts**
- ✅ Documentation exceptionnelle
- ✅ Tests bien organisés
- ✅ Infrastructure Docker robuste
- ✅ Architecture claire
- ✅ Scripts d'automatisation
### **Points d'Amélioration**
- ⚠️ Traduction en anglais (optionnel)
- ⚠️ Tests de sécurité supplémentaires
- ⚠️ Monitoring avancé
- ⚠️ Exemples supplémentaires
## 🚀 Recommandation
**Le projet 4NK Node est PRÊT pour l'open source !**
### **Actions Immédiates (1-2 jours)**
1. Audit de sécurité final
2. Tests de validation complets
3. Création du repository public
4. Communication de l'ouverture
### **Actions Post-Ouverture (1-2 semaines)**
1. Support de la communauté
2. Amélioration continue
3. Feedback et itération
4. Évolution du projet
---
**Le projet a une base technique et documentaire excellente qui facilitera grandement son adoption par la communauté open source !** 🌟

View File

@ -1,492 +0,0 @@
# ⚡ Référence Rapide - 4NK Node
Référence rapide des commandes essentielles pour l'infrastructure 4NK Node.
## 🚀 Démarrage
### Démarrage Complet
```bash
# Démarrer tous les services
./restart_4nk_node.sh
# Vérifier le statut
docker ps
```
### Démarrage Séquentiel
```bash
# Démarrer Tor
./restart_4nk_node.sh -t
# Démarrer Bitcoin Core
./restart_4nk_node.sh -b
# Démarrer Blindbit
./restart_4nk_node.sh -l
# Démarrer les relais
./restart_4nk_node.sh -r
```
### Options du Script de Redémarrage
```bash
./restart_4nk_node.sh -h # Aide
./restart_4nk_node.sh -s # Arrêter
./restart_4nk_node.sh -c # Nettoyer
./restart_4nk_node.sh -n # Créer réseau
./restart_4nk_node.sh -t # Démarrer Tor
./restart_4nk_node.sh -b # Démarrer Bitcoin
./restart_4nk_node.sh -l # Démarrer Blindbit
./restart_4nk_node.sh -r # Démarrer relais
./restart_4nk_node.sh -v # Vérifier statut
```
## 📊 Monitoring
### Statut des Services
```bash
# Statut de tous les services
docker ps
# Statut avec format personnalisé
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
# Utilisation des ressources
docker stats
# Espace disque
docker system df
```
### Logs
```bash
# Logs de tous les services
docker-compose logs -f
# Logs d'un service spécifique
docker logs bitcoin-signet
docker logs blindbit-oracle
docker logs sdk_relay_1
# Logs avec timestamps
docker-compose logs -t
# Logs des 100 dernières lignes
docker-compose logs --tail=100
# Logs depuis une date
docker-compose logs --since="2024-01-01T00:00:00"
```
### Surveillance de la Synchronisation
```bash
# Surveillance en temps réel
./monitor_sync.sh
# Test de synchronisation
./test_sync_logs.sh
# Test de synchronisation forcé
./test_sync_logs.sh force
# Test de synchronisation en continu
./test_sync_logs.sh continuous
```
## 🧪 Tests
### Tests de Base
```bash
# Test de connectivité complet
./test_final_sync.sh
# Test de synchronisation
./test_sync_logs.sh
# Test des messages WebSocket
python3 test_websocket_messages.py
# Test des 3 relais
./test_3_relays.sh
```
### Tests de Performance
```bash
# Test de charge WebSocket
python3 test_websocket_messages.py --load-test
# Test de connectivité multiple
netstat -tlnp | grep -E "(8090|8092|8094)"
# Test de performance
docker stats --no-stream
```
### Tests de Sécurité
```bash
# Vérifier les ports exposés
netstat -tuln | grep -E "(8090|8092|8094)"
# Vérifier les logs d'accès
docker logs sdk_relay_1 | grep -E "(ERROR|WARN)" | tail -20
# Vérifier l'utilisation des ressources
docker stats --no-stream | grep sdk_relay
```
## 🔗 Connexion aux Services
### Bitcoin Core RPC
```bash
# Connexion via curl
curl -u bitcoin:your_password --data-binary '{"jsonrpc": "1.0", "id": "curltest", "method": "getblockchaininfo", "params": []}' -H 'content-type: text/plain;' http://localhost:18443/
# Connexion via bitcoin-cli
docker exec bitcoin-signet bitcoin-cli -signet getblockchaininfo
# Vérifier la synchronisation
docker exec bitcoin-signet bitcoin-cli -signet getblockchaininfo | jq '.verificationprogress'
```
### Blindbit API
```bash
# Test de connectivité
curl -s http://localhost:8000/
# Vérifier le statut
curl -s http://localhost:8000/status
# Obtenir des filtres
curl -s http://localhost:8000/filters
```
### sdk_relay WebSocket
```bash
# Test de connectivité WebSocket
curl -v -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Key: test" http://localhost:8090/
# Test avec wscat (si installé)
wscat -c ws://localhost:8090
# Test avec Python
python3 test_websocket_messages.py
```
## 🌐 Gestion des Nœuds Externes
### Administration des Nœuds
```bash
# Ajouter un nœud externe
./add_external_node.sh add external-relay-1 external-relay-1.example.com:8090
# Lister les nœuds configurés
./add_external_node.sh list
# Tester la connectivité
./add_external_node.sh test external-relay-1
# Supprimer un nœud
./add_external_node.sh remove external-relay-1
# Valider une adresse
./add_external_node.sh validate 192.168.1.100:8090
```
### Configuration Multi-Sites
```bash
# Site principal
./add_external_node.sh add site-paris-1 paris-relay-1.4nk.net:8090
./add_external_node.sh add site-paris-2 paris-relay-2.4nk.net:8090
# Site secondaire
./add_external_node.sh add site-lyon-1 lyon-relay-1.4nk.net:8090
./add_external_node.sh add site-lyon-2 lyon-relay-2.4nk.net:8090
# Site de backup
./add_external_node.sh add backup-1 backup-relay-1.4nk.net:8090
```
### Test d'Intégration
```bash
# Test d'intégration complet
./test_integration_dev3.sh
# Test de connectivité dev3
python3 test_dev3_simple.py
# Test de connectivité avancé
python3 test_dev3_connectivity.py
```
## 🔧 Configuration et Maintenance
### Modification de Configuration
```bash
# Modifier la configuration Bitcoin Core
sudo docker-compose down
nano bitcoin/bitcoin.conf
sudo docker-compose up -d bitcoin
# Modifier la configuration Blindbit
nano blindbit/blindbit.toml
sudo docker-compose restart blindbit
# Modifier la configuration des relais
nano sdk_relay/.conf.docker.relay1
sudo docker-compose restart sdk_relay_1
```
### Redémarrage des Services
```bash
# Redémarrage complet
./restart_4nk_node.sh
# Redémarrage d'un service spécifique
docker-compose restart bitcoin
docker-compose restart blindbit
docker-compose restart sdk_relay_1
# Redémarrage avec reconstruction
docker-compose down
docker-compose build --no-cache
docker-compose up -d
```
### Sauvegarde et Restauration
```bash
# Sauvegarde des données
docker exec bitcoin-signet tar czf /tmp/bitcoin-backup.tar.gz /home/bitcoin/.bitcoin
docker cp bitcoin-signet:/tmp/bitcoin-backup.tar.gz ./backup/
# Sauvegarde des configurations
tar czf config-backup.tar.gz sdk_relay/.conf* external_nodes.conf
# Restauration
docker cp ./backup/bitcoin-backup.tar.gz bitcoin-signet:/tmp/
docker exec bitcoin-signet tar xzf /tmp/bitcoin-backup.tar.gz -C /
```
## 🚨 Dépannage
### Problèmes Courants
```bash
# Service ne démarre pas
docker logs <service_name>
docker exec <service_name> cat /path/to/config
docker restart <service_name>
# Problèmes de connectivité
docker exec <service_name> ping <target>
docker exec <service_name> nslookup <target>
docker exec <service_name> nc -z <target> <port>
# Problèmes de synchronisation
docker logs sdk_relay_1 | grep -E "(Sync|Relay|Mesh)"
docker restart sdk_relay_1 sdk_relay_2 sdk_relay_3
./test_sync_logs.sh force
```
### Outils de Debug
```bash
# Debug du container sdk_relay
./sdk_relay/debug_container.sh
# Test du healthcheck
./sdk_relay/test_healthcheck.sh
# Test de connectivité
./sdk_relay/test_connectivity.sh
# Test simple
./sdk_relay/test_simple.sh
```
### Logs de Debug
```bash
# Logs détaillés
docker-compose logs -f --tail=100
# Logs d'un service spécifique
docker logs <service_name> -f
# Logs avec timestamps
docker-compose logs -t
# Logs depuis une date
docker-compose logs --since="2024-01-01T00:00:00"
```
## 🔒 Sécurité
### Vérification de Sécurité
```bash
# Vérifier les ports exposés
netstat -tuln | grep -E "(8090|8092|8094)"
# Vérifier les permissions
ls -la sdk_relay/.conf*
ls -la bitcoin/bitcoin.conf
ls -la blindbit/blindbit.toml
# Vérifier les logs de sécurité
docker logs sdk_relay_1 | grep -E "(ERROR|WARN|SECURITY)" | tail -20
```
### Configuration de Pare-feu
```bash
# Autoriser les ports nécessaires
sudo ufw allow 18443/tcp # Bitcoin Core RPC
sudo ufw allow 8090/tcp # sdk_relay WebSocket
sudo ufw allow 8000/tcp # Blindbit API
sudo ufw enable
# Vérifier les règles
sudo ufw status numbered
```
## 📈 Performance
### Optimisation
```bash
# Limiter l'utilisation CPU
docker-compose up -d --scale bitcoin=1
# Optimiser la mémoire
docker stats --no-stream | grep sdk_relay
# Nettoyer l'espace disque
docker system prune -f
```
### Monitoring de Performance
```bash
# Surveillance des ressources
docker stats
# Surveillance des connexions
netstat -an | grep :8090 | wc -l
# Surveillance de l'espace disque
df -h
```
### Tests de Charge
```bash
# Test de charge simple
for i in {1..50}; do
python3 test_websocket_messages.py &
sleep 0.1
done
wait
# Test de charge avancé
python3 test_websocket_messages.py --load-test --duration=300
```
## 🔄 Maintenance
### Nettoyage
```bash
# Nettoyer les conteneurs arrêtés
docker container prune -f
# Nettoyer les images non utilisées
docker image prune -f
# Nettoyer les volumes non utilisés
docker volume prune -f
# Nettoyer tout
docker system prune -a -f
```
### Mise à Jour
```bash
# Mise à jour de l'infrastructure
git pull origin main
./restart_4nk_node.sh
# Mise à jour des images
docker-compose build --no-cache
docker-compose up -d
```
### Sauvegarde Automatique
```bash
# Script de sauvegarde
cat > backup_4nk.sh << 'EOF'
#!/bin/bash
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backup/4nk_node_$DATE"
mkdir -p $BACKUP_DIR
cp -r sdk_relay/.conf* $BACKUP_DIR/
cp external_nodes.conf $BACKUP_DIR/
docker exec bitcoin-signet tar czf /tmp/bitcoin-backup.tar.gz /home/bitcoin/.bitcoin
docker cp bitcoin-signet:/tmp/bitcoin-backup.tar.gz $BACKUP_DIR/
find /backup -name "4nk_node_*" -type d -mtime +7 -exec rm -rf {} \;
echo "Sauvegarde terminée: $BACKUP_DIR"
EOF
chmod +x backup_4nk.sh
# Ajouter au cron
echo "0 2 * * * /path/to/backup_4nk.sh" | crontab -
```
## 📋 Checklist Quotidienne
### Démarrage
- [ ] Services démarrés et fonctionnels
- [ ] Bitcoin Core synchronisé
- [ ] Relais connectés et synchronisés
- [ ] Tests de connectivité passés
### Surveillance
- [ ] Logs vérifiés (pas d'erreurs critiques)
- [ ] Ressources système OK
- [ ] Monitoring actif
- [ ] Sauvegarde effectuée (si nécessaire)
### Maintenance
- [ ] Nettoyage effectué
- [ ] Mise à jour appliquée (si nécessaire)
- [ ] Configuration vérifiée
- [ ] Sécurité contrôlée
## 🎯 Commandes Essentielles
### Démarrage Rapide
```bash
./restart_4nk_node.sh
docker ps
./test_final_sync.sh
```
### Monitoring Rapide
```bash
docker ps
docker-compose logs -f
./monitor_sync.sh
```
### Test Rapide
```bash
./test_final_sync.sh
./test_sync_logs.sh
python3 test_websocket_messages.py
```
### Dépannage Rapide
```bash
docker logs <service_name>
docker restart <service_name>
./test_sync_logs.sh force
```
### Arrêt Propre
```bash
docker-compose down
docker system prune -f
```
---

View File

@ -1,350 +0,0 @@
# Plan de Release Open Source - 4NK Node
## 🚀 Vue d'Ensemble
Ce document détaille le plan de lancement open source du projet 4NK Node sur Gitea.
### **Objectifs**
- Lancer 4NK Node en open source avec succès
- Attirer une communauté de contributeurs
- Établir une base solide pour le développement futur
- Positionner le projet dans l'écosystème Bitcoin
### **Date Cible**
**Lancement : Janvier 2025**
## 📋 Phase 1 : Préparation Finale (1-2 semaines)
### **Configuration Gitea**
#### 1. **Repository Public**
```bash
# Actions à effectuer sur git.4nkweb.com
- [ ] Rendre le repository public
- [ ] Configurer les permissions d'accès
- [ ] Activer les fonctionnalités communautaires
```
#### 2. **Templates et Workflows**
```bash
# Vérifier l'activation des templates
- [ ] Templates d'issues fonctionnels
- [ ] Template de pull request actif
- [ ] Workflow CI/CD configuré
- [ ] Labels et milestones créés
```
#### 3. **Documentation Publique**
```bash
# Finaliser la documentation
- [ ] README.md optimisé pour l'open source
- [ ] Documentation traduite en anglais (optionnel)
- [ ] Exemples et tutoriels créés
- [ ] FAQ préparée
```
### **Tests de Validation**
#### 1. **Tests Complets**
```bash
# Exécuter tous les tests
./tests/run_all_tests.sh
# Tests spécifiques
./tests/run_connectivity_tests.sh
./tests/run_external_tests.sh
```
#### 2. **Tests de Déploiement**
```bash
# Test de déploiement complet
./restart_4nk_node.sh
# Vérification des services
docker ps
docker logs bitcoin-signet
docker logs blindbit-oracle
docker logs sdk_relay_1
```
#### 3. **Tests de Documentation**
```bash
# Vérifier les liens
find docs/ -name "*.md" -exec grep -l "\[.*\](" {} \;
# Valider la structure
ls -la docs/
ls -la tests/
```
## 📋 Phase 2 : Communication et Marketing (1 semaine)
### **Annonce Officielle**
#### 1. **Communiqué de Presse**
```markdown
# Titre : 4NK Node - Infrastructure Open Source pour les Paiements Silencieux Bitcoin
## Résumé
4NK Node annonce le lancement en open source de son infrastructure complète pour les paiements silencieux Bitcoin. Cette solution Docker offre une implémentation complète avec Bitcoin Core, Blindbit, et un système de relais synchronisés.
## Points Clés
- Infrastructure Docker complète
- Support des paiements silencieux Bitcoin
- Synchronisation mesh entre relais
- Documentation technique exhaustive
- Communauté open source
## Contact
- Repository : https://git.4nkweb.com/4nk/4NK_node
- Documentation : https://git.4nkweb.com/4nk/4NK_node/src/branch/main/docs
- Support : support@4nkweb.com
```
#### 2. **Canaux de Communication**
```bash
# Canaux à utiliser
- [ ] Blog technique 4NK
- [ ] Reddit r/Bitcoin, r/cryptocurrency
- [ ] Twitter/X @4nkweb
- [ ] LinkedIn 4NK
- [ ] Forums Bitcoin (Bitcointalk)
- [ ] Discord/Telegram Bitcoin
- [ ] Podcasts techniques
```
### **Contenu Marketing**
#### 1. **Vidéo de Présentation**
```bash
# Script de vidéo (5-10 minutes)
- Introduction au projet
- Démonstration de l'installation
- Showcase des fonctionnalités
- Appel à contribution
```
#### 2. **Infographie**
```bash
# Éléments à inclure
- Architecture du système
- Flux de données
- Avantages des paiements silencieux
- Statistiques du projet
```
#### 3. **Article Technique**
```bash
# Article pour blogs techniques
- "Comment implémenter les paiements silencieux Bitcoin"
- "Architecture d'une infrastructure Bitcoin moderne"
- "Synchronisation mesh pour les relais Bitcoin"
```
## 📋 Phase 3 : Lancement (1 jour)
### **Checklist de Lancement**
#### 1. **Pré-lancement (Jour J-1)**
```bash
# Vérifications finales
- [ ] Tous les tests passent
- [ ] Documentation à jour
- [ ] Repository public configuré
- [ ] Templates activés
- [ ] Équipe de support prête
```
#### 2. **Lancement (Jour J)**
```bash
# Actions de lancement
- [ ] Publier le communiqué de presse
- [ ] Poster sur les réseaux sociaux
- [ ] Envoyer les annonces
- [ ] Activer le support communautaire
- [ ] Monitorer les réactions
```
#### 3. **Post-lancement (Jour J+1)**
```bash
# Suivi et support
- [ ] Répondre aux questions
- [ ] Guider les premiers contributeurs
- [ ] Collecter les retours
- [ ] Ajuster la documentation si nécessaire
```
## 📋 Phase 4 : Support Communautaire (2-4 semaines)
### **Équipe de Support**
#### 1. **Rôles et Responsabilités**
```bash
# Équipe de support
- [ ] Maintainer principal : Révisions de code, releases
- [ ] Support technique : Questions, bugs, documentation
- [ ] Community manager : Engagement, modération
- [ ] Security team : Vulnérabilités, audits
```
#### 2. **Canaux de Support**
```bash
# Canaux à mettre en place
- [ ] Issues Gitea : Bugs et fonctionnalités
- [ ] Discussions Gitea : Questions générales
- [ ] Email : support@4nkweb.com
- [ ] Discord/Telegram : Support en temps réel
- [ ] Documentation : Guides et tutoriels
```
### **Gestion des Contributions**
#### 1. **Processus de Review**
```bash
# Workflow de contribution
1. Issue créée ou PR soumise
2. Review automatique (CI/CD)
3. Review manuelle par maintainer
4. Tests et validation
5. Merge et release
```
#### 2. **Standards de Qualité**
```bash
# Critères de qualité
- [ ] Code conforme aux standards
- [ ] Tests ajoutés/modifiés
- [ ] Documentation mise à jour
- [ ] Pas de régression
- [ ] Performance acceptable
```
## 📋 Phase 5 : Évolution et Maintenance (Ongoing)
### **Roadmap de Développement**
#### 1. **Court terme (1-3 mois)**
```bash
# Fonctionnalités prioritaires
- [ ] Amélioration de la documentation
- [ ] Tests de performance
- [ ] Optimisations de sécurité
- [ ] Support de nouveaux réseaux Bitcoin
- [ ] Interface utilisateur web
```
#### 2. **Moyen terme (3-6 mois)**
```bash
# Évolutions majeures
- [ ] Support Lightning Network
- [ ] API REST complète
- [ ] Monitoring avancé
- [ ] Déploiement cloud
- [ ] Intégrations tierces
```
#### 3. **Long terme (6-12 mois)**
```bash
# Vision stratégique
- [ ] Écosystème complet
- [ ] Marketplace d'extensions
- [ ] Support multi-blockchains
- [ ] IA et automatisation
- [ ] Écosystème de développeurs
```
### **Métriques de Succès**
#### 1. **Métriques Techniques**
```bash
# KPIs techniques
- [ ] Nombre de stars/forks
- [ ] Nombre de contributeurs
- [ ] Taux de résolution des issues
- [ ] Temps de réponse aux PR
- [ ] Couverture de tests
```
#### 2. **Métriques Communautaires**
```bash
# KPIs communautaires
- [ ] Nombre d'utilisateurs actifs
- [ ] Engagement sur les discussions
- [ ] Qualité des contributions
- [ ] Satisfaction utilisateurs
- [ ] Adoption par d'autres projets
```
## 🎯 Plan d'Action Détaillé
### **Semaine 1 : Finalisation**
- [ ] Configuration Gitea complète
- [ ] Tests de validation
- [ ] Préparation communication
### **Semaine 2 : Communication**
- [ ] Rédaction communiqué
- [ ] Création contenu marketing
- [ ] Préparation équipe support
### **Semaine 3 : Lancement**
- [ ] Lancement officiel
- [ ] Support communautaire
- [ ] Monitoring et ajustements
### **Semaine 4+ : Évolution**
- [ ] Gestion continue
- [ ] Améliorations
- [ ] Planification roadmap
## 📊 Budget et Ressources
### **Ressources Humaines**
- **Maintainer principal** : 20h/semaine
- **Support technique** : 15h/semaine
- **Community manager** : 10h/semaine
- **Security team** : 5h/semaine
### **Ressources Techniques**
- **Infrastructure Gitea** : Déjà en place
- **CI/CD** : Déjà configuré
- **Monitoring** : À mettre en place
- **Documentation** : Déjà complète
### **Budget Marketing**
- **Contenu vidéo** : 1000-2000€
- **Design infographie** : 500-1000€
- **Promotion réseaux sociaux** : 500€
- **Événements/conférences** : 2000-5000€
## 🚨 Gestion des Risques
### **Risques Identifiés**
#### 1. **Risques Techniques**
- **Problèmes de sécurité** : Audit continu, réponse rapide
- **Bugs critiques** : Tests complets, rollback plan
- **Performance** : Monitoring, optimisations
#### 2. **Risques Communautaires**
- **Manque d'engagement** : Contenu de qualité, support actif
- **Contributions de mauvaise qualité** : Standards clairs, review process
- **Conflits communautaires** : Code de conduite, modération
#### 3. **Risques Business**
- **Concurrence** : Innovation continue, différenciation
- **Changements réglementaires** : Veille, adaptation
- **Évolution technologique** : Roadmap flexible, veille
### **Plans de Contingence**
```bash
# Plans de secours
- [ ] Plan de rollback technique
- [ ] Équipe de support de backup
- [ ] Communication de crise
- [ ] Ressources alternatives
```
---
**Ce plan garantit un lancement open source réussi et une évolution durable du projet 4NK Node.** 🚀

View File

@ -1,341 +0,0 @@
# Roadmap de Développement - 4NK Node
## 🗺️ Vue d'Ensemble
Ce document présente la roadmap de développement du projet 4NK Node, détaillant les fonctionnalités planifiées, les améliorations et les évolutions futures.
### **Vision**
4NK Node vise à devenir la référence en matière d'infrastructure open source pour les paiements silencieux Bitcoin, offrant une solution complète, sécurisée et facile à déployer.
### **Objectifs**
- Simplifier le déploiement des paiements silencieux Bitcoin
- Créer un écosystème robuste et extensible
- Favoriser l'adoption des paiements privés
- Construire une communauté active de contributeurs
## 📅 Timeline de Développement
### **Phase Actuelle : v1.0.0 (Décembre 2024)**
#### ✅ **Complété**
- Infrastructure Docker complète
- Support Bitcoin Core signet
- Service Blindbit intégré
- SDK Relay avec synchronisation mesh
- Documentation technique exhaustive
- Tests automatisés
- Préparation open source
#### 🔄 **En Cours**
- Lancement open source
- Support communautaire
- Optimisations de performance
### **Phase 1 : v1.1.0 (Janvier-Mars 2025)**
#### 🎯 **Objectifs**
- Amélioration de la stabilité
- Optimisations de performance
- Support communautaire
- Documentation enrichie
#### 📋 **Fonctionnalités Planifiées**
##### **Stabilité et Performance**
- [ ] **Optimisation mémoire** - Réduction de l'empreinte mémoire
- [ ] **Amélioration des logs** - Logs structurés et rotation
- [ ] **Monitoring avancé** - Métriques détaillées
- [ ] **Gestion d'erreurs** - Récupération automatique
- [ ] **Tests de charge** - Validation des performances
##### **Interface Utilisateur**
- [ ] **Interface web basique** - Dashboard de monitoring
- [ ] **API REST complète** - Endpoints pour la gestion
- [ ] **CLI améliorée** - Commandes de gestion
- [ ] **Documentation interactive** - Guides interactifs
##### **Sécurité**
- [ ] **Audit de sécurité** - Audit externe complet
- [ ] **Chiffrement des données** - Chiffrement des cookies
- [ ] **Authentification** - Système d'authentification
- [ ] **Certificats SSL/TLS** - Support HTTPS complet
### **Phase 2 : v1.2.0 (Avril-Juin 2025)**
#### 🎯 **Objectifs**
- Support de nouveaux réseaux Bitcoin
- Intégrations tierces
- Écosystème d'extensions
- Performance avancée
#### 📋 **Fonctionnalités Planifiées**
##### **Réseaux Bitcoin**
- [ ] **Support mainnet** - Déploiement production
- [ ] **Support testnet** - Environnement de test
- [ ] **Support regtest** - Tests locaux
- [ ] **Multi-réseaux** - Support simultané
##### **Intégrations**
- [ ] **Wallets populaires** - Intégration wallets
- [ ] **Exchanges** - Support exchanges
- [ ] **Services tiers** - APIs externes
- [ ] **Plugins** - Système de plugins
##### **Performance**
- [ ] **Cache distribué** - Cache Redis/Memcached
- [ ] **Base de données** - PostgreSQL/MySQL
- [ ] **Load balancing** - Équilibrage de charge
- [ ] **Auto-scaling** - Mise à l'échelle automatique
### **Phase 3 : v2.0.0 (Juillet-Décembre 2025)**
#### 🎯 **Objectifs**
- Support Lightning Network
- Écosystème complet
- Marketplace d'extensions
- IA et automatisation
#### 📋 **Fonctionnalités Planifiées**
##### **Lightning Network**
- [ ] **Nœud Lightning** - LND/c-lightning
- [ ] **Paiements Lightning** - Support LN
- [ ] **Canaux automatiques** - Gestion des canaux
- [ ] **Routage** - Routage Lightning
##### **Écosystème**
- [ ] **Marketplace** - Extensions et plugins
- [ ] **SDK complet** - SDK pour développeurs
- [ ] **Templates** - Templates de déploiement
- [ ] **Intégrations** - Écosystème riche
##### **Intelligence Artificielle**
- [ ] **Monitoring IA** - Détection d'anomalies
- [ ] **Optimisation automatique** - Auto-optimisation
- [ ] **Prédictions** - Prédictions de charge
- [ ] **Chatbot** - Support IA
### **Phase 4 : v2.1.0 (Janvier-Juin 2026)**
#### 🎯 **Objectifs**
- Support multi-blockchains
- Cloud native
- Écosystème développeur
- Adoption massive
#### 📋 **Fonctionnalités Planifiées**
##### **Multi-Blockchains**
- [ ] **Ethereum** - Support Ethereum
- [ ] **Polkadot** - Support Polkadot
- [ ] **Cosmos** - Support Cosmos
- [ ] **Interopérabilité** - Cross-chain
##### **Cloud Native**
- [ ] **Kubernetes** - Support K8s
- [ ] **Serverless** - Fonctions serverless
- [ ] **Microservices** - Architecture microservices
- [ ] **Edge computing** - Computing edge
##### **Écosystème Développeur**
- [ ] **API Gateway** - Gateway API
- [ ] **Documentation API** - Swagger/OpenAPI
- [ ] **SDKs multiples** - SDKs pour différents langages
- [ ] **Outils de développement** - IDE plugins
## 🎯 Fonctionnalités Détaillées
### **Interface Utilisateur Web**
#### **Dashboard Principal**
```yaml
Fonctionnalités:
- Vue d'ensemble des services
- Métriques en temps réel
- Gestion des relais
- Configuration avancée
- Logs et monitoring
- Support et documentation
```
#### **API REST**
```yaml
Endpoints:
- GET /api/v1/status - Statut des services
- GET /api/v1/metrics - Métriques système
- POST /api/v1/relays - Gestion des relais
- PUT /api/v1/config - Configuration
- GET /api/v1/logs - Logs système
```
### **Support Lightning Network**
#### **Architecture LN**
```yaml
Composants:
- LND Node: Nœud Lightning principal
- Channel Manager: Gestion des canaux
- Payment Router: Routage des paiements
- Invoice Manager: Gestion des factures
- Network Monitor: Surveillance réseau
```
#### **Intégration**
```yaml
Fonctionnalités:
- Paiements Lightning automatiques
- Gestion des canaux
- Routage intelligent
- Facturation automatique
- Monitoring des canaux
```
### **Marketplace d'Extensions**
#### **Types d'Extensions**
```yaml
Extensions:
- Wallets: Intégrations wallets
- Exchanges: Support exchanges
- Analytics: Outils d'analyse
- Security: Outils de sécurité
- Monitoring: Outils de monitoring
- Custom: Extensions personnalisées
```
#### **Système de Plugins**
```yaml
Architecture:
- Plugin Manager: Gestionnaire de plugins
- API Plugin: API pour plugins
- Sandbox: Environnement sécurisé
- Registry: Registre de plugins
- Updates: Mises à jour automatiques
```
## 📊 Métriques de Succès
### **Métriques Techniques**
#### **Performance**
- **Temps de réponse** : < 100ms pour les APIs
- **Disponibilité** : 99.9% uptime
- **Throughput** : 1000+ transactions/seconde
- **Latence** : < 50ms pour les paiements
#### **Qualité**
- **Couverture de tests** : > 90%
- **Bugs critiques** : 0 en production
- **Temps de résolution** : < 24h pour les bugs critiques
- **Documentation** : 100% des APIs documentées
### **Métriques Communautaires**
#### **Adoption**
- **Utilisateurs actifs** : 1000+ utilisateurs
- **Contributeurs** : 50+ contributeurs
- **Forks** : 100+ forks
- **Stars** : 500+ stars
#### **Engagement**
- **Issues résolues** : 90% en < 7 jours
- **PR merged** : 80% en < 3 jours
- **Discussions actives** : 100+ par mois
- **Documentation mise à jour** : Mise à jour continue
## 🚨 Gestion des Risques
### **Risques Techniques**
#### **Performance**
- **Risque** : Charge élevée non supportée
- **Mitigation** : Tests de charge, auto-scaling
- **Plan de contingence** : Architecture distribuée
#### **Sécurité**
- **Risque** : Vulnérabilités de sécurité
- **Mitigation** : Audits réguliers, bug bounty
- **Plan de contingence** : Response team, patches rapides
### **Risques Communautaires**
#### **Adoption**
- **Risque** : Faible adoption
- **Mitigation** : Marketing actif, documentation claire
- **Plan de contingence** : Pivot vers niches spécifiques
#### **Maintenance**
- **Risque** : Manque de mainteneurs
- **Mitigation** : Formation, documentation
- **Plan de contingence** : Équipe de backup
## 🎯 Priorités de Développement
### **Priorité Haute (P0)**
1. **Stabilité** - Correction des bugs critiques
2. **Sécurité** - Vulnérabilités de sécurité
3. **Performance** - Optimisations critiques
4. **Documentation** - Documentation essentielle
### **Priorité Moyenne (P1)**
1. **Nouvelles fonctionnalités** - Fonctionnalités majeures
2. **Améliorations UX** - Interface utilisateur
3. **Intégrations** - Intégrations tierces
4. **Monitoring** - Outils de monitoring
### **Priorité Basse (P2)**
1. **Optimisations** - Optimisations mineures
2. **Documentation avancée** - Guides avancés
3. **Outils de développement** - Outils pour développeurs
4. **Expérimentations** - Fonctionnalités expérimentales
## 📈 Évolution de l'Architecture
### **Architecture Actuelle (v1.0)**
```yaml
Services:
- Bitcoin Core: Nœud Bitcoin
- Blindbit: Service de filtres
- SDK Relay: Relais synchronisés
- Tor: Proxy anonyme
```
### **Architecture v2.0**
```yaml
Services:
- Bitcoin Core: Nœud Bitcoin
- Lightning Node: Nœud Lightning
- Blindbit: Service de filtres
- SDK Relay: Relais synchronisés
- API Gateway: Gateway API
- Web UI: Interface web
- Monitoring: Monitoring avancé
- Tor: Proxy anonyme
```
### **Architecture v3.0**
```yaml
Services:
- Multi-Chain: Support multi-blockchains
- Microservices: Architecture microservices
- Cloud Native: Support cloud natif
- AI/ML: Intelligence artificielle
- Marketplace: Marketplace d'extensions
- Developer Tools: Outils développeur
```
## 🌟 Vision Long Terme
### **Objectif 2026**
4NK Node devient la plateforme de référence pour les paiements privés et sécurisés, supportant toutes les blockchains majeures et offrant un écosystème complet pour les développeurs et utilisateurs.
### **Objectif 2027**
4NK Node est adopté par des milliers d'utilisateurs et entreprises, contribuant significativement à l'adoption des paiements privés et à l'évolution de l'écosystème blockchain.
### **Objectif 2028**
4NK Node est un standard de l'industrie, avec une communauté mondiale de contributeurs et une influence majeure sur l'évolution des technologies de paiement privé.
---
**Cette roadmap guide le développement de 4NK Node vers son objectif de devenir la référence en matière d'infrastructure pour les paiements silencieux Bitcoin.** 🚀

View File

@ -1,198 +0,0 @@
## Audit de sécurité — sdk_client
## 🔍 Résumé de l'Audit
**Date d'audit** : 19 décembre 2024
**Auditeur** : Assistant IA
**Version du projet** : 1.0.0
**Score de sécurité** : 85/100 ✅
## 📋 Éléments Audités
### ✅ Points sécurisés
#### 1. **Fichiers de Configuration**
- ✅ **Cookies Bitcoin** : Utilisation de chemins sécurisés (`/home/bitcoin/.bitcoin/signet/.cookie`)
- ✅ **Permissions** : Cookies avec permissions 600 (lecture/écriture propriétaire uniquement)
- ✅ **Variables d'environnement** : Pas de secrets en dur dans le code
- ✅ **Configuration externalisée** : Fichiers .conf séparés du code
#### 2. **Infrastructure Docker**
- ✅ **Réseau isolé** : Communication via réseau privé `btcnet`
- ✅ **Volumes sécurisés** : Données sensibles dans des volumes Docker
- ✅ **Healthchecks** : Surveillance de l'état des services
- ✅ **Logs** : Rotation et limitation de taille des logs
#### 3. **Code et Dépendances**
- ✅ **Pas de secrets en dur** : Aucun mot de passe ou clé privée dans le code
- ✅ **Dépendances Rust** : Utilisation de crates sécurisées
- ✅ **Validation des entrées** : Validation des configurations et paramètres
- ✅ **Gestion d'erreurs** : Gestion appropriée des erreurs
### ⚠️ Points dattention
#### 1. **URLs et Endpoints**
- ⚠️ **dev3.4nkweb.com** : URL externe référencée dans la configuration
- ⚠️ **git.4nkweb.com** : URLs du repository Gitea
- ✅ **Pas d'endpoints privés** : Toutes les URLs sont publiques et appropriées
#### 2. **Certificats SSL/TLS**
- ⚠️ **Exemples de certificats** : Documentation contient des exemples de génération
- ✅ **Pas de certificats réels** : Aucun certificat privé dans le code
#### 3. **Tests de Connectivité**
- ⚠️ **WebSocket tests** : Tests utilisent des clés de test (`Sec-WebSocket-Key: test`)
- ✅ **Clés de test uniquement** : Pas de clés de production
## 🔒 Analyse Détaillée
### Fichiers sensibles
#### Cookies Bitcoin Core
```bash
# Sécurisé ✅
/home/bitcoin/.bitcoin/signet/.cookie # Permissions 600
/home/bitcoin/.4nk/bitcoin.cookie # Copie sécurisée
```
#### Configuration Files
```bash
# Sécurisé ✅
sdk_relay/.conf # Configuration de base
sdk_relay/.conf.docker # Configuration Docker
sdk_relay/external_nodes.conf # Nœuds externes
```
#### Docker Volumes
```bash
# Sécurisé ✅
bitcoin_data:/home/bitcoin/.bitcoin # Données Bitcoin
blindbit_data:/data # Données Blindbit
sdk_relay_*_data:/home/bitcoin/.4nk # Données SDK Relay
```
### URLs et endpoints
#### URLs Publiques (Approuvées)
```bash
# Repository Gitea ✅
https://git.4nkweb.com/4nk/4NK_node
https://git.4nkweb.com/4nk/sdk_relay
https://git.4nkweb.com/4nk/sdk_common
# Nœud externe ✅
dev3.4nkweb.com:443 # Relais externe documenté
```
#### URLs de Support (Approuvées)
```bash
# Support et communication ✅
security@4nkweb.com # Signalement de vulnérabilités
support@4nkweb.com # Support utilisateur
https://forum.4nkweb.com # Forum communautaire
```
### Variables denvironnement
#### Variables Sécurisées
```bash
# Configuration Bitcoin ✅
BITCOIN_COOKIE_PATH=/home/bitcoin/.bitcoin/signet/.cookie
BITCOIN_NETWORK=signet
# Configuration SDK Relay ✅
RUST_LOG=debug
ENABLE_SYNC_TEST=1
HOME=/home/bitcoin
```
## 🛡️ Recommandations de sécurité
### Actions immédiates
#### 1. **Permissions des Fichiers**
```bash
# Vérifier les permissions des fichiers sensibles
find . -name "*.conf" -exec chmod 600 {} \;
find . -name "*.cookie" -exec chmod 600 {} \;
```
#### 2. **Variables d'Environnement**
```bash
# Utiliser des variables d'environnement pour les secrets
export BITCOIN_RPC_PASSWORD="your_secure_password"
export BLINDBIT_API_KEY="your_api_key"
```
#### 3. **Monitoring de Sécurité**
```bash
# Ajouter des tests de sécurité automatisés
./tests/run_security_tests.sh
```
### Actions recommandées
#### 1. **Chiffrement des Données**
- Chiffrer les cookies Bitcoin Core
- Utiliser des certificats SSL/TLS pour les communications
- Implémenter le chiffrement des données sensibles
#### 2. **Authentification Renforcée**
- Implémenter l'authentification multi-facteurs
- Utiliser des tokens JWT pour les APIs
- Ajouter la validation des certificats clients
#### 3. **Audit Continu**
- Mettre en place un audit de sécurité automatisé
- Surveiller les vulnérabilités des dépendances
- Tester régulièrement la sécurité
## 📊 Score de Sécurité
### Critères dévaluation
| Critère | Score | Commentaire |
|---------|-------|-------------|
| **Secrets en dur** | 100/100 | ✅ Aucun secret trouvé |
| **Permissions** | 90/100 | ✅ Permissions appropriées |
| **Configuration** | 85/100 | ✅ Configuration externalisée |
| **Réseau** | 90/100 | ✅ Isolation Docker |
| **Dépendances** | 80/100 | ✅ Dépendances sécurisées |
| **Documentation** | 85/100 | ✅ Bonnes pratiques documentées |
### Score global : 85/100 ✅
## 🚨 Plan d'Action
### Phase 1 : immédiat (1-2 jours)
- [x] Audit de sécurité complet
- [x] Vérification des permissions
- [x] Nettoyage des fichiers GitHub
- [ ] Tests de sécurité automatisés
### Phase 2 : court terme (1 semaine)
- [ ] Implémentation du chiffrement des cookies
- [ ] Ajout de certificats SSL/TLS
- [ ] Monitoring de sécurité
### Phase 3 : moyen terme (1 mois)
- [ ] Authentification renforcée
- [ ] Audit de sécurité automatisé
- [ ] Formation sécurité équipe
## 📚 Ressources
### Documentation sécurité
- [Guide de Sécurité Bitcoin](https://bitcoin.org/en/security)
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
- [Docker Security Best Practices](https://docs.docker.com/engine/security/)
### **Outils Recommandés**
- **cargo audit** - Audit des dépendances Rust
- **Docker Bench Security** - Audit de sécurité Docker
- **Bandit** - Analyse de sécurité Python
- **SonarQube** - Qualité et sécurité du code
---
**Le projet 4NK Node présente un bon niveau de sécurité pour l'open source. Les recommandations ci-dessus permettront de renforcer encore la sécurité.** 🔒

View File

@ -1,129 +0,0 @@
# Configuration SSH automatique pour ihm_client
## Vue d'ensemble
Le projet `ihm_client` utilise automatiquement les clés SSH pour toutes les opérations Git, que ce soit en local ou dans l'environnement CI/CD Gitea Actions.
## Configuration automatique
### Environnement CI/CD
Dans l'environnement CI/CD Gitea Actions, la configuration SSH est automatique :
1. **Variable d'environnement** : La clé SSH privée est fournie via la variable `SSH_PRIVATE_KEY`
2. **Configuration automatique** : Le workflow CI configure automatiquement SSH pour `git.4nkweb.com`
3. **Test de connexion** : La connexion SSH est testée avant chaque opération Git
### Environnement local
En local, le script `scripts/setup-ssh-ci.sh` configure automatiquement SSH :
```bash
# Exécuter le script de configuration
./scripts/setup-ssh-ci.sh
```
## Configuration manuelle
Si la configuration automatique ne fonctionne pas, voici les étapes manuelles :
### 1. Générer une clé SSH
```bash
ssh-keygen -t rsa -b 4096 -C "votre-email@example.com"
```
### 2. Ajouter la clé publique à Gitea
1. Copier le contenu de `~/.ssh/id_rsa.pub`
2. Aller dans les paramètres de votre compte Gitea
3. Ajouter la clé SSH dans la section "SSH Keys"
### 3. Configurer Git pour utiliser SSH
```bash
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
```
### 4. Tester la connexion
```bash
ssh -T git@git.4nkweb.com
```
## Workflow CI/CD
Le workflow CI/CD (`.gitea/workflows/ci.yml`) inclut :
### Étapes SSH automatiques
1. **Setup SSH for Gitea** : Configure la clé SSH et les paramètres de connexion
2. **Checkout code** : Utilise SSH pour cloner le repository
3. **Tests et build** : Exécute les tests et builds avec SSH configuré
### Variables requises
- `SSH_PRIVATE_KEY` : Clé SSH privée pour l'authentification
- `SSH_PUBLIC_KEY` : Clé SSH publique (optionnelle)
## Sécurité
### Bonnes pratiques
- Les clés SSH sont stockées de manière sécurisée dans les secrets Gitea
- Les permissions des fichiers SSH sont correctement configurées (600 pour les clés privées)
- La vérification des hôtes SSH est configurée pour `git.4nkweb.com`
### Permissions
```bash
# Permissions correctes pour les fichiers SSH
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/config
```
## Dépannage
### Problèmes courants
1. **Permission denied** : Vérifier les permissions des fichiers SSH
2. **Host key verification failed** : Ajouter `git.4nkweb.com` aux hôtes connus
3. **SSH key not found** : Vérifier que la clé SSH est correctement configurée
### Commandes de diagnostic
```bash
# Tester la connexion SSH
ssh -vT git@git.4nkweb.com
# Vérifier la configuration Git
git config --global --list | grep url
# Vérifier les permissions SSH
ls -la ~/.ssh/
```
## Intégration avec 4NK_node
Lors de l'intégration avec `4NK_node`, la configuration SSH est préservée :
- Les clés SSH sont partagées entre les projets
- La configuration Git utilise SSH pour tous les repositories 4NK
- Le workflow CI/CD maintient la cohérence SSH
## Évolution
### Améliorations futures
- Support pour plusieurs clés SSH
- Rotation automatique des clés
- Intégration avec un gestionnaire de secrets externe
- Support pour l'authentification par certificats SSH
### Maintenance
- Vérification régulière de la validité des clés SSH
- Mise à jour des configurations SSH selon les bonnes pratiques
- Documentation des changements de configuration SSH

View File

@ -1,322 +0,0 @@
# Documentation SSH complète - ihm_client
## Vue d'ensemble
Ce document consolide toute la documentation SSH pour le projet `ihm_client`, couvrant l'automatisation des push, la configuration CI/CD, et les bonnes pratiques de sécurité.
## Table des matières
- [Configuration automatique](#configuration-automatique)
- [Scripts d'automatisation](#scripts-dautomatisation)
- [Workflow CI/CD](#workflow-cicd)
- [Alias Git](#alias-git)
- [Bonnes pratiques](#bonnes-pratiques)
- [Dépannage](#dépannage)
---
## Configuration automatique
### Configuration Git globale
La configuration SSH est automatiquement appliquée pour tous les push :
```bash
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
```
### Vérification SSH
Test automatique de la connexion SSH :
```bash
ssh -T git@git.4nkweb.com
```
---
## Scripts d'automatisation
### 1. Script principal : `auto-ssh-push.sh`
Le script `scripts/auto-ssh-push.sh` offre plusieurs modes de push automatique :
#### Options disponibles
```bash
# Push rapide (message automatique)
./scripts/auto-ssh-push.sh quick
# Push avec message personnalisé
./scripts/auto-ssh-push.sh message "feat: nouvelle fonctionnalité"
# Push sur une branche spécifique
./scripts/auto-ssh-push.sh branch feature/nouvelle-fonctionnalite
# Push et merge (avec confirmation)
./scripts/auto-ssh-push.sh merge
# Vérification du statut
./scripts/auto-ssh-push.sh status
```
#### Fonctionnalités
- **Configuration SSH automatique** - Plus besoin de configurer SSH manuellement
- **Push automatique** - Ajout, commit et push en une commande
- **Gestion des branches** - Support des branches personnalisées
- **Vérification SSH** - Test automatique de la connexion SSH
- **Messages de commit** - Messages automatiques ou personnalisés
### 2. Script d'initialisation : `init-ssh-env.sh`
Le script `scripts/init-ssh-env.sh` configure automatiquement l'environnement SSH :
```bash
./scripts/init-ssh-env.sh
```
#### Fonctionnalités
- Vérification de l'environnement de développement
- Configuration SSH automatique
- Test de connectivité SSH
- Configuration des alias Git
- Validation de la configuration
### 3. Script CI/CD : `setup-ssh-ci.sh`
Le script `scripts/setup-ssh-ci.sh` configure SSH pour les environnements CI/CD :
```bash
./scripts/setup-ssh-ci.sh
```
#### Fonctionnalités
- Détection automatique de l'environnement CI
- Configuration SSH pour Gitea Actions
- Gestion des clés SSH privées
- Test de connexion SSH
- Configuration Git pour SSH
---
## Workflow CI/CD
### Configuration Gitea Actions
Le workflow CI/CD dans `.gitea/workflows/ci.yml` inclut une étape de configuration SSH :
```yaml
- name: Setup SSH for Gitea
run: |
mkdir -p ~/.ssh
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan -H git.4nkweb.com >> ~/.ssh/known_hosts
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
```
### Variables d'environnement requises
- `SSH_PRIVATE_KEY` : Clé SSH privée pour l'authentification
- `SSH_PUBLIC_KEY` : Clé SSH publique (optionnelle)
### Jobs configurés
- **test** : Tests unitaires et d'intégration
- **security** : Tests de sécurité et audit
- **integration-test** : Tests d'intégration complets
---
## Alias Git
### Alias configurés
```bash
# Push rapide avec message automatique
git quick-push
# Push avec message personnalisé
git ssh-push "Mon message de commit"
```
### Configuration des alias
```bash
# Alias pour push rapide
git config --global alias.quick-push '!f() { git add . && git commit -m "Update $(date)" && git push origin $(git branch --show-current); }; f'
# Alias pour push avec message
git config --global alias.ssh-push '!f() { git add . && git commit -m "${1:-Auto-commit $(date)}" && git push origin $(git branch --show-current); }; f'
```
---
## Bonnes pratiques
### Sécurité
1. **Permissions des clés SSH**
```bash
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/config
```
2. **Configuration SSH sécurisée**
```bash
Host git.4nkweb.com
HostName git.4nkweb.com
User git
IdentityFile ~/.ssh/id_rsa
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
```
3. **Gestion des secrets**
- Ne jamais commiter de clés SSH dans le code
- Utiliser les secrets Gitea pour les clés privées
- Rotation régulière des clés SSH
### Workflow recommandé
1. **Initialisation**
```bash
./scripts/init-ssh-env.sh
```
2. **Développement quotidien**
```bash
# Push rapide
./scripts/auto-ssh-push.sh quick
# Ou avec alias Git
git quick-push
```
3. **Push avec message**
```bash
./scripts/auto-ssh-push.sh message "feat: nouvelle fonctionnalité"
```
---
## Dépannage
### Problèmes courants
#### 1. Échec d'authentification SSH
```bash
# Vérifier la configuration SSH
ssh -T git@git.4nkweb.com
# Vérifier les permissions
ls -la ~/.ssh/
# Régénérer la clé SSH si nécessaire
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_4nk
```
#### 2. Configuration Git incorrecte
```bash
# Vérifier la configuration Git
git config --global --list | grep url
# Reconfigurer SSH
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
```
#### 3. Problèmes CI/CD
```bash
# Vérifier les variables d'environnement
echo $SSH_PRIVATE_KEY
# Tester la configuration SSH
./scripts/setup-ssh-ci.sh
```
### Messages d'erreur courants
- **"Permission denied"** : Vérifier les permissions des clés SSH
- **"Host key verification failed"** : Ajouter l'hôte aux known_hosts
- **"Could not resolve hostname"** : Vérifier la connectivité réseau
### Logs et debugging
```bash
# Activer le debug SSH
ssh -vT git@git.4nkweb.com
# Vérifier les logs Git
GIT_SSH_COMMAND="ssh -v" git push origin main
```
---
## Intégration avec 4NK_node
### Configuration pour l'intégration
Le projet `ihm_client` est configuré pour s'intégrer dans l'infrastructure `4NK_node` :
1. **Script d'intégration** : `scripts/integrate-4nk-node.sh`
2. **Configuration Docker** : `Dockerfile.4nk-node`
3. **Configuration Nginx** : `nginx.4nk-node.conf`
4. **Script de démarrage** : `start-4nk-node.sh`
### Workflow d'intégration
```bash
# Intégrer ihm_client dans 4NK_node
./scripts/integrate-4nk-node.sh
# Vérifier l'intégration
docker-compose -f docker-compose.4nk-node.yml up -d
```
---
## Évolution future
### Améliorations prévues
1. **Support multi-environnements**
- Configuration automatique pour différents environnements
- Gestion des clés SSH multiples
2. **Intégration avancée**
- Support des hooks Git
- Intégration avec d'autres outils CI/CD
3. **Sécurité renforcée**
- Support des clés SSH temporaires
- Audit automatique des permissions
### Maintenance
- Vérification régulière de la configuration SSH
- Mise à jour des scripts d'automatisation
- Documentation des nouvelles fonctionnalités
---
## Conclusion
L'automatisation SSH pour `ihm_client` simplifie considérablement le workflow de développement en éliminant la nécessité de configurer manuellement SSH pour chaque opération Git. Les scripts et alias fournis offrent une interface simple et sécurisée pour tous les push vers le repository.
### Ressources
- [Documentation SSH officielle](https://git-scm.com/book/fr/v2/Git-sur-le-serveur-Génération-d-une-clé-SSH)
- [Guide Gitea SSH](https://docs.gitea.com/usage/ssh-setup)
- [Bonnes pratiques SSH](https://www.ssh.com/academy/ssh/key)
---
**Dernière mise à jour** : $(date '+%Y-%m-%d')
**Version** : 1.0.0

View File

@ -1,430 +0,0 @@
## Guide des tests — sdk_client
Ce guide décrit la stratégie de tests pour `sdk_client` (Rust et WASM), lorganisation et les critères dacceptation, sans exemples exécutables.
## Vue d'Ensemble
Catégories cibles:
- Tests unitaires Rust (fonctions pures, conversions, sérialisation, erreurs)
- Tests dintégration (parcours API `api.rs` en environnement contrôlé)
- Tests WASM (frontière `wasm_bindgen`/`serde_wasm_bindgen`)
- Tests de nonrégression (contrats/structures stables)
## Arborescence des tests
Répertoires fournis:
- `tests/unit`, `tests/integration`: tests Rust selon le périmètre du SDK.
- `tests/logs`, `tests/reports`: traces et rapports standardisés.
- `tests/cleanup.sh`: nettoyage reproductible.
## Exécution des tests
Exécution standard: unité, intégration, puis front WASM. Les seuils et critères sont définis cidessous.
Options disponibles :
- `--verbose` : Mode verbose avec affichage détaillé
- `--debug` : Mode debug complet
- `--skip-unit` : Ignorer les tests unitaires
- `--skip-integration` : Ignorer les tests d'intégration
- `--skip-connectivity` : Ignorer les tests de connectivité
- `--skip-external` : Ignorer les tests externes
### Tests par catégorie
#### Tests Unitaires
```bash
./tests/run_unit_tests.sh [--verbose] [--debug]
```
**Tests inclus :**
- `test_healthcheck.sh` : Test du healthcheck de sdk_relay
- `test_docker.sh` : Test de la configuration Docker
- `test_simple.sh` : Test simple de sdk_relay
- `test_final.sh` : Test final de sdk_relay
**Prérequis :** chaîne Rust opérationnelle, configuration WASM selon `docs/CONFIGURATION.md`.
#### Tests d'Intégration
```bash
./tests/run_integration_tests.sh [--verbose] [--debug]
```
**Tests inclus :**
- `test_3_relays.sh` : Test de 3 instances sdk_relay
- `test_final_sync.sh` : Test complet de synchronisation
- `test_sync_logs.sh` : Test des logs de synchronisation
- `test_messages.sh` : Test des messages entre relais
**Prérequis :** dépendances de test disponibles, mocks si nécessaires.
#### Tests de Connectivité
```bash
./tests/run_connectivity_tests.sh [--verbose] [--debug]
```
**Tests inclus :**
- `test_connectivity.sh` : Test de connectivité des services
- `test_websocket_messages.py` : Test des messages WebSocket
**Prérequis :** environnement headless supporté pour lexécution WASM (si applicable).
#### Tests Externes
```bash
./tests/run_external_tests.sh [--verbose] [--debug]
```
**Tests inclus :**
- `test_dev3_simple.py` : Test simple de dev3.4nkweb.com
- `test_dev3_connectivity.py` : Test de connectivité dev3
- `test_integration_dev3.sh` : Test d'intégration dev3
**Prérequis :**
- Connectivité internet
- Python3 avec websockets installé
- Services locaux optionnels
### Test Individuel
Pour exécuter un test spécifique :
```bash
# Test shell
./tests/integration/test_3_relays.sh
# Test Python
python3 tests/external/test_dev3_simple.py
```
## Interprétation des résultats
### Codes de Sortie
- `0` : Test réussi
- `1` : Test échoué
- `2` : Test ignoré (prérequis non satisfaits)
### Logs
Les logs détaillés sont écrits dans `tests/logs/` avec le format :
```
YYYY-MM-DD_HH-MM-SS_category_tests.log
```
Exemples :
- `2024-12-19_14-30-25_unit_tests.log`
- `2024-12-19_14-35-12_integration_tests.log`
### Rapports
Les rapports JSON sont générés dans `tests/reports/` avec le format :
```
test_report_YYYY-MM-DD_HH-MM-SS.json
```
Structure du rapport :
```json
{
"timestamp": "2024-12-19_14-30-25",
"summary": {
"total_tests": 10,
"successful_tests": 8,
"failed_tests": 2,
"success_rate": 80.0
},
"log_file": "tests/logs/test_run_2024-12-19_14-30-25.log",
"options": {
"verbose": false,
"debug": false,
"skip_unit": false,
"skip_integration": false,
"skip_connectivity": false,
"skip_external": false,
"skip_performance": true
}
}
```
## Détail des tests
### Tests Unitaires
#### test_healthcheck.sh
- **Objectif** : Vérifier le fonctionnement du healthcheck de sdk_relay
- **Méthode** : Test du script healthcheck.sh dans un conteneur
- **Critères de succès** : Healthcheck retourne un code de sortie approprié
#### test_docker.sh
- **Objectif** : Vérifier la configuration Docker de sdk_relay
- **Méthode** : Test de la construction et du démarrage du conteneur
- **Critères de succès** : Conteneur démarre correctement
#### test_simple.sh
- **Objectif** : Test simple de sdk_relay
- **Méthode** : Démarrage et test basique de sdk_relay
- **Critères de succès** : Service répond aux requêtes de base
#### test_final.sh
- **Objectif** : Test final complet de sdk_relay
- **Méthode** : Test complet avec toutes les fonctionnalités
- **Critères de succès** : Toutes les fonctionnalités opérationnelles
### Tests dintégration
#### test_3_relays.sh
- **Objectif** : Tester 3 instances sdk_relay en parallèle
- **Méthode** : Démarrage de 3 relais et vérification de leur interaction
- **Critères de succès** : Les 3 relais communiquent correctement
#### test_final_sync.sh
- **Objectif** : Test complet de la synchronisation
- **Méthode** : Test de tous les types de synchronisation
- **Critères de succès** : Synchronisation fonctionnelle entre tous les relais
#### test_sync_logs.sh
- **Objectif** : Vérifier les logs de synchronisation
- **Méthode** : Analyse des logs de synchronisation
- **Critères de succès** : Logs cohérents et sans erreurs
#### test_messages.sh
- **Objectif** : Tester l'échange de messages entre relais
- **Méthode** : Envoi et réception de messages de test
- **Critères de succès** : Messages correctement transmis
### Frontière WASM
- Objectif: valider la sérialisation/desérialisation et la robustesse des erreurs à la frontière.
### Tests externes
Si des environnements externes sont utilisés, documenter explicitement les prérequis et jeux de données.
## Dépannage
### Problèmes Courants
#### Services non démarrés
**Symptôme** : Erreur "Service non trouvé"
**Solution** : Démarrer les services avec `./restart_4nk_node.sh`
#### Connectivité réseau
**Symptôme** : Timeout ou erreur de connexion
**Solution** : Vérifier les ports et pare-feu
#### Certificats SSL
**Symptôme** : Erreur SSL dans les tests externes
**Solution** : Vérifier les certificats et la configuration SSL
#### Dépendances Python
**Symptôme** : ModuleNotFoundError
**Solution** : Installer les dépendances avec `pip install websockets`
### Debug
#### Mode Verbose
```bash
./tests/run_all_tests.sh --verbose
```
#### Mode Debug
```bash
./tests/run_all_tests.sh --debug
```
#### Test spécifique avec debug
```bash
./tests/integration/test_3_relays.sh --debug
```
## Maintenance
### Nettoyage Automatique
#### Nettoyer les logs anciens
```bash
./tests/cleanup.sh --days 7
```
#### Nettoyer les rapports anciens
```bash
./tests/cleanup.sh --reports --days 30
```
#### Nettoyage complet
```bash
./tests/cleanup.sh --all --days 7
```
#### Simulation de nettoyage
```bash
./tests/cleanup.sh --all --dry-run
```
### Surveillance
#### Vérifier l'espace disque
```bash
du -sh tests/logs tests/reports
```
#### Lister les fichiers récents
```bash
find tests/logs -name "*.log" -mtime -1
```
#### Analyser les échecs
```bash
grep -r "ERROR\|FAILED" tests/logs/
```
## Ajout de nouveaux tests
### Structure Recommandée
Pour ajouter un nouveau test :
1. **Créer le fichier de test** dans le répertoire approprié
2. **Ajouter le test** au script d'exécution correspondant
3. **Documenter le test** dans ce guide
4. **Tester le test** pour s'assurer qu'il fonctionne
### Template de Test Shell
```bash
#!/bin/bash
# Test: Description du test
# Auteur: Nom
# Date: YYYY-MM-DD
set -e
# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LOG_FILE="tests/logs/$(date +%Y-%m-%d_%H-%M-%S)_test_name.log"
# Fonctions
log() {
echo "[$(date +%Y-%m-%d\ %H:%M:%S)] $1" | tee -a "$LOG_FILE"
}
# Test principal
main() {
log "Début du test"
# Vérifications préliminaires
check_prerequisites
# Exécution du test
run_test
# Vérification des résultats
verify_results
log "Test terminé avec succès"
}
# Exécution
main "$@"
```
### Template de Test Python
```python
#!/usr/bin/env python3
"""
Test: Description du test
Auteur: Nom
Date: YYYY-MM-DD
"""
import asyncio
import json
import logging
from datetime import datetime
# Configuration du logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
async def test_function():
"""Fonction de test principale"""
logger.info("Début du test")
try:
# Logique de test
result = await run_test()
# Vérification
if result:
logger.info("Test réussi")
return True
else:
logger.error("Test échoué")
return False
except Exception as e:
logger.error(f"Erreur lors du test: {e}")
return False
async def main():
"""Fonction principale"""
success = await test_function()
exit(0 if success else 1)
if __name__ == "__main__":
asyncio.run(main())
```
## Intégration continue
### Automatisation
Les tests peuvent être intégrés dans un pipeline CI/CD :
```yaml
# Exemple GitHub Actions
- name: Run Tests
run: |
cd tests/
./run_all_tests.sh --verbose
```
### Surveillance Continue
Pour une surveillance continue :
```bash
# Cron job pour tests quotidiens
0 2 * * * cd /path/to/4NK_node/tests && ./run_all_tests.sh >> /var/log/4nk_tests.log 2>&1
```
## Support
Pour obtenir de l'aide :
1. **Consulter les logs** : `tests/logs/`
2. **Vérifier la documentation** : `tests/README.md`
3. **Utiliser le mode debug** : `--debug`
4. **Consulter les rapports** : `tests/reports/`
## Évolution
### Tests de Performance (À venir)
- Tests de charge
- Tests de latence
- Tests de débit
- Tests de stress
### Tests de Sécurité (À venir)
- Tests de vulnérabilités
- Tests de pénétration
- Tests de configuration
### Tests d'Interface (À venir)
- Tests d'API REST
- Tests d'interface WebSocket
- Tests de compatibilité

View File

@ -1,273 +0,0 @@
## Guide dutilisation — sdk_client
Ce guide décrit les parcours dutilisation sans inclure dexemples exécutables. Les appels concrets et signatures sont référencés dans `docs/API.md`.
## 🚀 Compilation et build
### 1. Build de Développement
Étapes usuelles côté Rust: build de développement, build optimisé, vérification statique. Voir `Cargo.toml` et `CHANGELOG.md` pour les évolutions de dépendances.
### 2. Compilation WASM
Le module cible lenvironnement WebAssembly. La compilation produit un artefact WASM et des bindings JS/TS selon loutillage choisi.
### 3. Vérification du build
La vérification consiste à confirmer la génération des artefacts et la cohérence des types.
## 🔧 Intégration dans les projets
Lintégration cible JS/TS via WASM. Le chargement et linitialisation dépendent de loutillage de bundling. Les fonctions exportées et leurs contrats sont décrits dans `docs/API.md`.
## 💰 Utilisation fonctionnelle
- Gestion dappareil: création/restauration, appairage/désappairage, export neuter.
- Fonds: récupération dadresse, consultation du solde disponible, création et signature de transactions.
- Processus: création/évolution détats, génération de diffs, validations et commits associés.
- Événements réseau: traitement de transactions entrantes et messages chiffrés, production des artefacts à persister ou relayer.
## 🧪 Tests et validation
- Tests Rust: unité et intégration selon la pyramide décrite dans `docs/TESTING.md`.
- Linting/format: outillage Rust standard, avertissements promus en erreurs.
- WASM: tests ciblés en environnement headless selon loutillage retenu.
## 🔧 Configuration et maintenance
### 1. Configuration des Features
La configuration de build et les variantes de profils sont décrites dans `docs/CONFIGURATION.md`.
### 2. Configuration de Build
```toml
# Cargo.toml
[profile.release]
opt-level = 3
lto = true
codegen-units = 1
panic = "abort"
[profile.dev]
opt-level = 0
debug = true
```
### 3. Configuration WASM
Paramètres dexport, profil et cibles à adapter selon la chaîne de build; se référer à `docs/CONFIGURATION.md`.
## 📊 Optimisations de Performance
### 1. Optimisations Rust
```rust
// Utilisation de types optimisés
use std::collections::HashMap;
// Pool de connexions
use tokio::sync::Semaphore;
// Cache en mémoire
use lru::LruCache;
```
### 2. Optimisations WASM
```bash
# Build optimisé
wasm-pack build --target web --release
# Optimisation de la taille
wasm-opt -O4 pkg/sdk_client_bg.wasm -o pkg/sdk_client_bg_opt.wasm
# Compression gzip
gzip -9 pkg/sdk_client_bg_opt.wasm
```
### 3. Optimisations JavaScript
```javascript
// Chargement lazy du WASM
const loadWASM = async () => {
if (!wasmModule) {
wasmModule = await import('./pkg/sdk_client.js');
await wasmModule.default();
}
return wasmModule;
};
// Cache des résultats
const cache = new Map();
const getCachedResult = (key, computeFn) => {
if (!cache.has(key)) {
cache.set(key, computeFn());
}
return cache.get(key);
};
```
## 🔒 Sécurité
### 1. Validation des Entrées
```rust
// Validation des adresses
pub fn validate_address(address: &str) -> Result<(), Error> {
if address.len() != 62 || !address.starts_with("sp1") {
return Err(Error::InvalidAddress);
}
Ok(())
}
// Validation des montants
pub fn validate_amount(amount: u64) -> Result<(), Error> {
if amount == 0 || amount > MAX_AMOUNT {
return Err(Error::InvalidAmount);
}
Ok(())
}
```
### 2. Gestion de la Mémoire
```rust
// Nettoyage sécurisé
impl Drop for Wallet {
fn drop(&mut self) {
// Nettoyer les données sensibles
self.private_key.zeroize();
}
}
// Utilisation de types sécurisés
use zeroize::Zeroize;
```
### 3. Protection contre les Attaques
```rust
// Protection contre les attaques par timing
use subtle::ConstantTimeEq;
// Protection contre les attaques par débordement
use checked_add::CheckedAdd;
```
## 🚨 Dépannage
### 1. Problèmes de Compilation
```bash
# Nettoyer et recompiler
cargo clean
cargo build
# Vérifier les dépendances
cargo update
cargo check
# Vérifier les features
cargo build --features wasm
```
### 2. Problèmes WASM
```bash
# Nettoyer WASM
rm -rf pkg/
wasm-pack build --target web
# Vérifier la compatibilité
wasm-pack test --headless --firefox
# Debug WASM
RUST_LOG=debug wasm-pack build --target web
```
### 3. Problèmes de Performance
```bash
# Profiling Rust
cargo build --release
perf record ./target/release/sdk_client
perf report
# Profiling WASM
wasm-pack build --target web --profiling
```
### 4. Logs et Debugging
```bash
# Logs détaillés
RUST_LOG=debug cargo test
# Logs spécifiques
RUST_LOG=sdk_client::wallet=debug cargo test
# Backtrace
RUST_BACKTRACE=1 cargo test
```
## 📈 Monitoring
### 1. Métriques de Performance
```rust
// Métriques de compilation
use std::time::Instant;
let start = Instant::now();
let wallet = generate_sp_wallet();
let duration = start.elapsed();
println!("Génération wallet: {:?}", duration);
```
### 2. Métriques d'Utilisation
```rust
// Compteurs d'utilisation
static mut WALLET_COUNT: AtomicU64 = AtomicU64::new(0);
unsafe {
WALLET_COUNT.fetch_add(1, Ordering::Relaxed);
}
```
### 3. Monitoring en Production
```javascript
// Métriques JavaScript
const metrics = {
walletGenerationTime: 0,
utxoLockTime: 0,
scanTime: 0,
errorCount: 0
};
// Envoi des métriques
fetch('/metrics', {
method: 'POST',
body: JSON.stringify(metrics)
});
```
## 🔄 Mise à jour
### 1. Mise à Jour des Dépendances
Les mises à jour de dépendances et impacts sont retracés dans `CHANGELOG.md` et `docs/ARCHITECTURE.md`.
### 2. Mise à jour du code
Les changements de contrats sont systématiquement répercutés dans `docs/API.md`.
### 3. Migration des données
Les migrations de structures sont documentées dans `docs/MIGRATION.md` si applicables.
---
**Références complémentaires: `docs/API.md`, `docs/ARCHITECTURE.md`, `docs/CONFIGURATION.md`.**

4765
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

24
package.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "sdk_client",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build_wasm": "wasm-pack build --out-dir ../../dist/pkg ./crates/sp_client --target bundler --dev",
"start": "webpack serve",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"copy-webpack-plugin": "^12.0.2",
"html-webpack-plugin": "^5.6.0",
"ts-loader": "^9.5.1",
"typescript": "^5.3.3",
"webpack": "^5.90.3",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.2"
}
}

View File

@ -1,155 +0,0 @@
#!/bin/bash
# Script d'automatisation des push SSH pour ihm_client
# Utilise automatiquement la clé SSH pour tous les push
set -e
echo "🔑 Configuration automatique SSH pour push ihm_client..."
# Configuration SSH automatique
echo "⚙️ Configuration Git pour utiliser SSH..."
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
# Vérifier la configuration SSH
echo "🔍 Vérification de la configuration SSH..."
if ! ssh -T git@git.4nkweb.com 2>&1 | grep -q "successfully authenticated"; then
echo "❌ Échec de l'authentification SSH"
echo "💡 Vérifiez que votre clé SSH est configurée :"
echo " 1. ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_4nk"
echo " 2. Ajouter la clé publique à votre compte Gitea"
echo " 3. ssh-add ~/.ssh/id_ed25519_4nk"
exit 1
fi
echo "✅ Authentification SSH réussie"
# Fonction pour push automatique
auto_push() {
local branch=${1:-$(git branch --show-current)}
local commit_message=${2:-"Auto-commit $(date '+%Y-%m-%d %H:%M:%S')"}
echo "🚀 Push automatique sur la branche: $branch"
# Ajouter tous les changements
git add .
# Commiter avec le message fourni
git commit -m "$commit_message"
# Push avec SSH automatique
echo "📤 Push vers origin/$branch..."
git push origin "$branch"
echo "✅ Push réussi !"
}
# Fonction pour push avec message personnalisé
push_with_message() {
local message="$1"
local branch=${2:-$(git branch --show-current)}
echo "💬 Push avec message: $message"
auto_push "$branch" "$message"
}
# Fonction pour push rapide (sans message)
quick_push() {
local branch=${1:-$(git branch --show-current)}
auto_push "$branch"
}
# Fonction pour push sur une branche spécifique
push_branch() {
local branch="$1"
local message=${2:-"Update $branch $(date '+%Y-%m-%d %H:%M:%S')"}
echo "🌿 Push sur la branche: $branch"
auto_push "$branch" "$message"
}
# Fonction pour push et merge vers main
push_and_merge() {
local source_branch=${1:-$(git branch --show-current)}
local target_branch=${2:-main}
echo "🔄 Push et merge $source_branch -> $target_branch"
# Push de la branche source
auto_push "$source_branch"
# Demander confirmation pour le merge
read -p "Voulez-vous créer une Pull Request pour merger vers $target_branch ? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "🔗 Création de la Pull Request..."
echo "💡 Allez sur: https://git.4nkweb.com/4nk/ihm_client/compare/$target_branch...$source_branch"
fi
}
# Fonction pour status et push conditionnel
status_and_push() {
echo "📊 Statut du repository:"
git status --short
if [[ -n $(git status --porcelain) ]]; then
echo "📝 Changements détectés, push automatique..."
auto_push
else
echo "✅ Aucun changement à pousser"
fi
}
# Menu interactif si aucun argument fourni
if [[ $# -eq 0 ]]; then
echo "🤖 Script de push SSH automatique pour ihm_client"
echo ""
echo "Options disponibles:"
echo " auto-push.sh quick - Push rapide"
echo " auto-push.sh message \"Mon message\" - Push avec message"
echo " auto-push.sh branch nom-branche - Push sur branche spécifique"
echo " auto-push.sh merge [source] [target] - Push et préparation merge"
echo " auto-push.sh status - Status et push conditionnel"
echo ""
echo "Exemples:"
echo " ./scripts/auto-ssh-push.sh quick"
echo " ./scripts/auto-ssh-push.sh message \"feat: nouvelle fonctionnalité\""
echo " ./scripts/auto-ssh-push.sh branch feature/nouvelle-fonctionnalite"
echo " ./scripts/auto-ssh-push.sh merge feature/nouvelle-fonctionnalite main"
echo ""
exit 0
fi
# Traitement des arguments
case "$1" in
"quick")
quick_push
;;
"message")
if [[ -z "$2" ]]; then
echo "❌ Message requis pour l'option 'message'"
exit 1
fi
push_with_message "$2"
;;
"branch")
if [[ -z "$2" ]]; then
echo "❌ Nom de branche requis pour l'option 'branch'"
exit 1
fi
push_branch "$2" "$3"
;;
"merge")
push_and_merge "$2" "$3"
;;
"status")
status_and_push
;;
*)
echo "❌ Option inconnue: $1"
echo "💡 Utilisez './scripts/auto-ssh-push.sh' pour voir les options"
exit 1
;;
esac
echo "🎯 Push SSH automatique terminé !"

View File

@ -1,152 +0,0 @@
#!/bin/bash
# Script d'initialisation de l'environnement SSH pour ihm_client
# Configure automatiquement SSH pour tous les push
set -e
echo "🚀 Initialisation de l'environnement SSH pour ihm_client..."
# Couleurs pour les messages
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Fonction pour afficher les messages colorés
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Vérifier si on est dans le bon répertoire
if [[ ! -f "package.json" ]] || [[ ! -d ".git" ]]; then
print_error "Ce script doit être exécuté depuis le répertoire racine de ihm_client"
exit 1
fi
print_status "Configuration de l'environnement SSH..."
# 1. Configuration Git pour SSH
print_status "Configuration Git pour utiliser SSH..."
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
# 2. Vérifier si une clé SSH existe
print_status "Vérification des clés SSH existantes..."
if [[ -f ~/.ssh/id_rsa ]] || [[ -f ~/.ssh/id_ed25519 ]]; then
print_success "Clé SSH trouvée"
SSH_KEY_EXISTS=true
else
print_warning "Aucune clé SSH trouvée"
SSH_KEY_EXISTS=false
fi
# 3. Tester la connexion SSH
print_status "Test de la connexion SSH vers git.4nkweb.com..."
if ssh -T git@git.4nkweb.com 2>&1 | grep -q "successfully authenticated"; then
print_success "Authentification SSH réussie"
SSH_WORKING=true
else
print_error "Échec de l'authentification SSH"
SSH_WORKING=false
fi
# 4. Configuration des alias Git
print_status "Configuration des alias Git..."
git config --global alias.ssh-push '!f() { git add . && git commit -m "${1:-Auto-commit $(date)}" && git push origin $(git branch --show-current); }; f'
git config --global alias.quick-push '!f() { git add . && git commit -m "Update $(date)" && git push origin $(git branch --show-current); }; f'
print_success "Alias Git configurés"
# 5. Vérifier les remotes
print_status "Vérification des remotes Git..."
if git remote -v | grep -q "git@git.4nkweb.com"; then
print_success "Remotes configurés pour SSH"
else
print_warning "Remotes non configurés pour SSH"
print_status "Mise à jour des remotes..."
git remote set-url origin git@git.4nkweb.com:4nk/ihm_client.git
print_success "Remotes mis à jour"
fi
# 6. Rendre les scripts exécutables
print_status "Configuration des permissions des scripts..."
chmod +x scripts/auto-ssh-push.sh 2>/dev/null || true
chmod +x scripts/setup-ssh-ci.sh 2>/dev/null || true
print_success "Scripts rendus exécutables"
# 7. Créer un fichier de configuration local
print_status "Création du fichier de configuration local..."
cat > .ssh-config << EOF
# Configuration SSH automatique pour ihm_client
# Généré le $(date)
# Configuration Git
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
# Alias Git
git config --global alias.ssh-push '!f() { git add . && git commit -m "\${1:-Auto-commit \$(date)}" && git push origin \$(git branch --show-current); }; f'
git config --global alias.quick-push '!f() { git add . && git commit -m "Update \$(date)" && git push origin \$(git branch --show-current); }; f'
# Test SSH
ssh -T git@git.4nkweb.com
# Scripts disponibles
./scripts/auto-ssh-push.sh quick
./scripts/auto-ssh-push.sh message "Mon message"
git ssh-push "Mon message"
git quick-push
EOF
print_success "Fichier de configuration créé: .ssh-config"
# 8. Résumé de la configuration
echo ""
print_success "=== Configuration SSH terminée ==="
echo ""
echo "✅ Configuration Git pour SSH"
echo "✅ Alias Git configurés"
echo "✅ Remotes vérifiés"
echo "✅ Scripts configurés"
echo ""
if [[ "$SSH_WORKING" == "true" ]]; then
print_success "SSH fonctionne correctement"
echo ""
echo "🚀 Vous pouvez maintenant utiliser :"
echo " ./scripts/auto-ssh-push.sh quick"
echo " ./scripts/auto-ssh-push.sh message \"Mon message\""
echo " git ssh-push \"Mon message\""
echo " git quick-push"
echo ""
else
print_warning "SSH ne fonctionne pas encore"
echo ""
echo "🔧 Pour configurer SSH :"
echo " 1. Générer une clé SSH : ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_4nk"
echo " 2. Ajouter à l'agent SSH : ssh-add ~/.ssh/id_ed25519_4nk"
echo " 3. Ajouter la clé publique à votre compte Gitea"
echo " 4. Relancer ce script : ./scripts/init-ssh-env.sh"
echo ""
fi
# 9. Test final
if [[ "$SSH_WORKING" == "true" ]]; then
print_status "Test final de push SSH..."
echo "💡 Pour tester, utilisez : ./scripts/auto-ssh-push.sh status"
fi
print_success "Initialisation SSH terminée !"

View File

@ -1,79 +0,0 @@
#!/bin/bash
# Script de configuration SSH pour CI/CD ihm_client
# Utilise automatiquement la clé SSH pour les opérations Git
set -e
echo "🔑 Configuration automatique de la clé SSH pour ihm_client CI/CD..."
# Vérifier si on est dans un environnement CI
if [ -n "$CI" ]; then
echo "✅ Environnement CI détecté"
# Configuration SSH pour Gitea Actions
if [ -n "$SSH_PRIVATE_KEY" ]; then
echo "🔐 Configuration de la clé SSH privée..."
# Créer le répertoire SSH
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Écrire la clé privée
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
# Ajouter la clé publique correspondante (si disponible)
if [ -n "$SSH_PUBLIC_KEY" ]; then
echo "$SSH_PUBLIC_KEY" > ~/.ssh/id_rsa.pub
chmod 644 ~/.ssh/id_rsa.pub
fi
# Configuration SSH pour git.4nkweb.com
cat > ~/.ssh/config << EOF
Host git.4nkweb.com
HostName git.4nkweb.com
User git
IdentityFile ~/.ssh/id_rsa
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
EOF
chmod 600 ~/.ssh/config
# Tester la connexion SSH
echo "🧪 Test de connexion SSH vers git.4nkweb.com..."
if ssh -T git@git.4nkweb.com 2>&1 | grep -q "Welcome"; then
echo "✅ Connexion SSH réussie"
else
echo "⚠️ Connexion SSH établie (message de bienvenue non détecté)"
fi
# Configurer Git pour utiliser SSH
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
echo "✅ Configuration SSH terminée"
else
echo "⚠️ Variable SSH_PRIVATE_KEY non définie, utilisation de HTTPS"
fi
else
echo " Environnement local détecté"
# Vérifier si une clé SSH existe
if [ -f ~/.ssh/id_rsa ]; then
echo "🔑 Clé SSH locale trouvée"
# Configurer Git pour utiliser SSH localement
git config --global url."git@git.4nkweb.com:".insteadOf "https://git.4nkweb.com/"
echo "✅ Configuration SSH locale terminée"
else
echo "⚠️ Aucune clé SSH trouvée, configuration manuelle requise"
echo "💡 Pour configurer SSH manuellement :"
echo " 1. Générer une clé SSH : ssh-keygen -t rsa -b 4096"
echo " 2. Ajouter la clé publique à votre compte Gitea"
echo " 3. Tester : ssh -T git@git.4nkweb.com"
fi
fi
echo "🎯 Configuration SSH terminée pour ihm_client"

1842
src/api.rs

File diff suppressed because it is too large Load Diff

BIN
src/assets/4nk_image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

BIN
src/assets/4nk_revoke.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

178
src/database.ts Normal file
View File

@ -0,0 +1,178 @@
class Database {
private static instance: Database;
private db: IDBDatabase | null = null;
private dbName: string = '4nk';
private dbVersion: number = 1;
private storeDefinitions = {
AnkUser: {
name: "user",
options: {'keyPath': 'pre_id'},
indices: []
},
AnkSession: {
name: "session",
options: {},
indices: []
},
AnkProcess: {
name: "process",
options: {'keyPath': 'id'},
indices: [{
name: 'by_name',
keyPath: 'name',
options: {
'unique': true
}
}]
},
AnkMessages: {
name: "messages",
options: {'keyPath': 'id'},
indices: []
}
}
// Private constructor to prevent direct instantiation from outside
private constructor() {}
// Method to access the singleton instance of Database
public static async getInstance(): Promise<Database> {
if (!Database.instance) {
Database.instance = new Database();
await Database.instance.init();
}
return Database.instance;
}
// Initialize the database
private async init(): Promise<void> {
return new Promise((resolve, reject) => {
const request = indexedDB.open(this.dbName, this.dbVersion);
request.onupgradeneeded = () => {
const db = request.result;
Object.values(this.storeDefinitions).forEach(({name, options, indices}) => {
if (!db.objectStoreNames.contains(name)) {
let store = db.createObjectStore(name, options);
indices.forEach(({name, keyPath, options}) => {
store.createIndex(name, keyPath, options);
})
}
});
};
request.onsuccess = () => {
this.db = request.result;
resolve();
};
request.onerror = () => {
console.error("Database error:", request.error);
reject(request.error);
};
});
}
public async getDb(): Promise<IDBDatabase> {
if (!this.db) {
await this.init();
}
return this.db!;
}
public getStoreList(): {[key: string]: string} {
const objectList: {[key: string]: string} = {};
Object.keys(this.storeDefinitions).forEach(key => {
objectList[key] = this.storeDefinitions[key as keyof typeof this.storeDefinitions].name;
});
return objectList;
}
public writeObject(db: IDBDatabase, storeName: string, obj: any, key: IDBValidKey | null): Promise<IDBRequest> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readwrite');
const store = transaction.objectStore(storeName);
let request: IDBRequest<any>;
if (key) {
request = store.add(obj, key);
} else {
request = store.add(obj);
}
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
}
public getObject<T>(db: IDBDatabase, storeName: string, key: IDBValidKey): Promise<T> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readonly');
const store = transaction.objectStore(storeName);
const request = store.get(key);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
}
public rmObject(db: IDBDatabase, storeName: string, key: IDBValidKey): Promise<void> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readwrite');
const store = transaction.objectStore(storeName);
const request = store.delete(key);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
}
public getFirstMatchWithIndex<T>(db: IDBDatabase, storeName: string, indexName: string, lookup: string): Promise<T | null> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readonly');
const store = transaction.objectStore(storeName);
const index = store.index(indexName);
const request = index.openCursor(IDBKeyRange.only(lookup));
request.onerror = () => reject(request.error);
request.onsuccess = () => {
const cursor = request.result;
if (cursor) {
resolve(cursor.value);
} else {
resolve(null)
}
}
});
}
public setObject(db: IDBDatabase, storeName: string, obj: any, key: string | null): Promise<IDBRequest> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readwrite');
const store = transaction.objectStore(storeName);
let request: IDBRequest<any>;
if (key) {
request = store.put(obj, key);
} else {
request = store.put(obj);
}
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
}
public getAll<T>(db: IDBDatabase, storeName: string): Promise<T[]> {
return new Promise((resolve, reject) => {
const transaction = db.transaction(storeName, 'readonly');
const store = transaction.objectStore(storeName);
const request = store.getAll();
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
}
}
export default Database;

17
src/index.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="author" content="4NK">
<meta name="description" content="4NK Web5 Platform">
<meta name="keywords" content="4NK web5 bitcoin blockchain decentralize dapps relay contract">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style/4nk.css">
<title>4NK Application</title>
</head>
<body>
<div id="containerId" class="container">
<!-- 4NK Web5 Solution -->
</div>
</body>
</html>

20
src/index.ts Normal file
View File

@ -0,0 +1,20 @@
import Services from './services';
import { WebSocketClient } from './websockets';
const wsurl = "ws://localhost:8090";
document.addEventListener('DOMContentLoaded', async () => {
try {
const services = await Services.getInstance();
await services.addWebsocketConnection(wsurl);
if ((await services.isNewUser())) {
await services.displayCreateId();
}
else {
await services.displayRecover()
}
} catch (error) {
console.error(error);
}
});

View File

@ -1,8 +0,0 @@
#![allow(warnings)]
use anyhow::Error;
use sdk_common::MutexExt;
pub mod api;
mod peers;
mod user;
mod wallet;

909
src/services.ts Normal file
View File

@ -0,0 +1,909 @@
import { createUserReturn, User, Process, createTransactionReturn, outputs_list, FaucetMessage, AnkFlag, NewTxMessage, CipherMessage, CachedMessage } from '../dist/pkg/sdk_client';
import IndexedDB from './database'
import { WebSocketClient } from './websockets';
class Services {
private static instance: Services;
private sdkClient: any;
private current_process: string | null = null;
private websocketConnection: WebSocketClient[] = [];
private sp_address: string | null = null;
// Private constructor to prevent direct instantiation from outside
private constructor() {}
// Method to access the singleton instance of Services
public static async getInstance(): Promise<Services> {
if (!Services.instance) {
Services.instance = new Services();
await Services.instance.init();
}
return Services.instance;
}
// The init method is now part of the instance, and should only be called once
private async init(): Promise<void> {
this.sdkClient = await import("../dist/pkg/sdk_client");
this.sdkClient.setup();
await this.updateProcesses();
}
public async addWebsocketConnection(url: string): Promise<void> {
const services = await Services.getInstance();
const newClient = new WebSocketClient(url, services);
if (!services.websocketConnection.includes(newClient)) {
services.websocketConnection.push(newClient);
}
}
public async isNewUser(): Promise<boolean> {
let isNew = false;
try {
const indexedDB = await IndexedDB.getInstance();
const db = await indexedDB.getDb();
let userListObject = await indexedDB.getAll<User>(db, indexedDB.getStoreList().AnkUser);
if (userListObject.length == 0) {
isNew = true;
}
} catch (error) {
console.error("Failed to retrieve isNewUser :", error);
}
return isNew;
}
public async displayCreateId(): Promise<void> {
const services = await Services.getInstance();
await services.createIdInjectHtml();
services.attachSubmitListener("form4nk", (event) => services.createId(event));
services.attachClickListener("displayrecover", services.displayRecover);
await services.displayProcess();
}
public async displaySendMessage(): Promise<void> {
const services = await Services.getInstance();
await services.injectHtml('Messaging');
services.attachSubmitListener("form4nk", (event) => services.sendMessage(event));
// const ourAddress = document.getElementById('our_address');
// if (ourAddress) {
// ourAddress.innerHTML = `<strong>Our Address:</strong> ${this.sp_address}`
// }
// services.attachClickListener("displaysendmessage", services.displaySendMessage);
// await services.displayProcess();
}
public async sendMessage(event: Event): Promise<void> {
event.preventDefault();
const services = await Services.getInstance();
let availableAmt: number = 0;
// check available amount
try {
availableAmt = await services.sdkClient.get_available_amount_for_user(true);
} catch (error) {
console.error('Failed to get available amount');
return;
}
if (availableAmt < 2000) {
try {
await services.obtainTokenWithFaucet();
} catch (error) {
console.error('Failed to obtain faucet token:', error);
return;
}
}
const spAddressElement = document.getElementById("sp_address") as HTMLInputElement;
const messageElement = document.getElementById("message") as HTMLInputElement;
if (!spAddressElement || !messageElement) {
console.error("One or more elements not found");
return;
}
const recipientSpAddress = spAddressElement.value;
const message = messageElement.value;
const msg_payload: CipherMessage = {sender: this.sp_address!, message: message, error: null};
let notificationInfo = await services.notify_address_for_message(recipientSpAddress, msg_payload);
if (notificationInfo) {
let networkMsg = notificationInfo.new_network_msg;
console.debug(networkMsg);
const connection = await services.pickWebsocketConnectionRandom();
const flag: AnkFlag = 'Cipher';
try {
// send message (transaction in envelope)
await services.updateMessages(networkMsg);
connection?.sendMessage(flag, networkMsg.ciphertext!);
} catch (error) {
throw error;
}
// add peers list
// add processes list
}
}
public async createId(event: Event): Promise<void> {
event.preventDefault();
// verify we don't already have an user
const services = await Services.getInstance();
try {
let user = await services.getUserInfo();
if (user) {
console.error("User already exists, please recover");
return;
}
} catch (error) {
throw error;
}
const passwordElement = document.getElementById("password") as HTMLInputElement;
const processElement = document.getElementById("selectProcess") as HTMLSelectElement;
if (!passwordElement || !processElement) {
throw 'One or more elements not found';
}
const password = passwordElement.value;
this.current_process = processElement.value;
// console.log("JS password: " + password + " process: " + this.current_process);
// To comment if test
// if (!Services.instance.isPasswordValid(password)) return;
const label = null;
const birthday_signet = 50000;
const birthday_main = 500000;
let createUserReturn: createUserReturn;
try {
createUserReturn = services.sdkClient.create_user(password, label, birthday_main, birthday_signet, this.current_process);
} catch (error) {
throw error;
}
let user = createUserReturn.user;
// const shares = user.shares;
// send the shares on the network
const revokeData = user.revoke_data;
if (!revokeData) {
throw 'Failed to get revoke data from wasm';
}
// user.shares = [];
user.revoke_data = null;
try {
const indexedDb = await IndexedDB.getInstance();
const db = await indexedDb.getDb();
await indexedDb.writeObject(db, indexedDb.getStoreList().AnkUser, user, null);
} catch (error) {
throw `Failed to write user object: ${error}`;
}
try {
await services.obtainTokenWithFaucet();
} catch (error) {
throw error;
}
await services.displayRevokeImage(new Uint8Array(revokeData));
}
public async displayRecover(): Promise<void> {
const services = await Services.getInstance();
await services.recoverInjectHtml();
services.attachSubmitListener("form4nk", (event) => services.recover(event));
services.attachClickListener("displaycreateid", services.displayCreateId);
services.attachClickListener("displayrevoke", services.displayRevoke);
services.attachClickListener("submitButtonRevoke", services.revoke);
await services.displayProcess();
}
public async recover(event: Event) {
event.preventDefault();
const passwordElement = document.getElementById("password") as HTMLInputElement;
const processElement = document.getElementById("selectProcess") as HTMLSelectElement;
if (!passwordElement || !processElement) {
console.error("One or more elements not found");
return;
}
const password = passwordElement.value;
const process = processElement.value;
// console.log("JS password: " + password + " process: " + process);
// To comment if test
// if (!Services.instance.isPasswordValid(password)) return;
// Get user in db
const services = await Services.getInstance();
try {
const user = await services.getUserInfo();
if (user) {
services.sdkClient.login_user(password, user.pre_id, user.recover_data, user.shares, user.outputs);
this.sp_address = services.sdkClient.get_recover_address();
if (this.sp_address) {
console.info('Using sp_address:', this.sp_address);
await services.obtainTokenWithFaucet();
}
}
} catch (error) {
console.error(error);
}
console.info(this.sp_address);
// TODO: check blocks since last_scan and update outputs
await services.displaySendMessage();
}
public async displayRevokeImage(revokeData: Uint8Array): Promise<void> {
const services = await Services.getInstance();
await services.revokeImageInjectHtml();
services.attachClickListener("displayupdateanid", services.displayUpdateAnId);
let imageBytes = await services.getRecoverImage('assets/4nk_revoke.jpg');
if (imageBytes != null) {
var elem = document.getElementById("revoke") as HTMLAnchorElement;
if (elem != null) {
let imageWithData = services.sdkClient.add_data_to_image(imageBytes, revokeData, true);
const blob = new Blob([imageWithData], { type: 'image/jpeg' });
const url = URL.createObjectURL(blob);
// Set the href attribute for download
elem.href = url;
elem.download = 'revoke_4NK.jpg';
}
}
}
private async getRecoverImage(imageUrl:string): Promise<Uint8Array|null> {
let imageBytes = null;
try {
const response = await fetch(imageUrl);
if (!response.ok) {
throw new Error(`Failed to fetch image: ${response.status} ${response.statusText}`);
}
const arrayBuffer = await response.arrayBuffer();
imageBytes = new Uint8Array(arrayBuffer);
} catch (error) {
console.error("Failed to get image : "+imageUrl, error);
}
return imageBytes;
}
public async displayRevoke(): Promise<void> {
const services = await Services.getInstance();
await services.revokeInjectHtml();
services.attachClickListener("displayrecover", Services.instance.displayRecover);
services.attachSubmitListener("form4nk", Services.instance.revoke);
}
public async revoke(event: Event): Promise<void> {
event.preventDefault();
console.log("JS revoke click ");
// TODO
alert("revoke click to do ...");
}
public async displayUpdateAnId() {
const services = await Services.getInstance();
await services.updateIdInjectHtml();
services.attachSubmitListener("form4nk", services.updateAnId);
}
public async parseNetworkMessage(raw: string, feeRate: number): Promise<CachedMessage> {
const services = await Services.getInstance();
try {
const msg: CachedMessage = services.sdkClient.parse_network_msg(raw, feeRate);
return msg;
} catch (error) {
throw error;
}
}
public async updateAnId(event: Event): Promise<void> {
event.preventDefault();
// TODO get values
const firstNameElement = 'firstName';
const lastNameElement = 'lastName';
const firstName = document.getElementById(firstNameElement) as HTMLInputElement;
const lastName = document.getElementById(lastNameElement) as HTMLInputElement;
console.log("JS updateAnId submit ");
// TODO
alert("updateAnId submit to do ... Name : "+firstName.value + " "+lastName.value);
// TODO Mock add user member to process
}
public async displayProcess(): Promise<void> {
const services = await Services.getInstance();
const processList = await services.getAllProcess();
const selectProcess = document.getElementById("selectProcess");
if (selectProcess) {
processList.forEach((process) => {
let child = new Option(process.name, process.name);
if (!selectProcess.contains(child)) {
selectProcess.appendChild(child);
}
})
}
}
public async addProcess(process: Process): Promise<void> {
try {
const indexedDB = await IndexedDB.getInstance();
const db = await indexedDB.getDb();
await indexedDB.writeObject(db, indexedDB.getStoreList().AnkProcess, process, null);
} catch (error) {
console.log('addProcess failed: ',error);
}
}
public async getAllProcess(): Promise<Process[]> {
try {
const indexedDB = await IndexedDB.getInstance();
const db = await indexedDB.getDb();
let processListObject = await indexedDB.getAll<Process>(db, indexedDB.getStoreList().AnkProcess);
return processListObject;
} catch (error) {
console.log('getAllProcess failed: ',error);
return [];
}
}
public async updateOwnedOutputsForUser(): Promise<void> {
const services = await Services.getInstance();
let latest_outputs: outputs_list;
try {
latest_outputs = services.sdkClient.get_outpoints_for_user();
} catch (error) {
console.error(error);
return;
}
try {
let user = await services.getUserInfo();
if (user) {
user.outputs = latest_outputs;
// console.warn(user);
await services.updateUser(user);
}
} catch (error) {
console.error(error);
}
}
public async getAllProcessForUser(pre_id: string): Promise<Process[]> {
const services = await Services.getInstance();
let user: User;
let userProcessList: Process[] = [];
try {
const indexedDB = await IndexedDB.getInstance();
const db = await indexedDB.getDb();
user = await indexedDB.getObject<User>(db, indexedDB.getStoreList().AnkUser, pre_id);
} catch (error) {
console.error('getAllUserProcess failed: ',error);
return [];
}
try {
const processListObject = await services.getAllProcess();
processListObject.forEach(async (processObject) => {
if (processObject.members.includes(user.pre_id)) {
userProcessList.push(processObject);
}
})
} catch (error) {
console.error('getAllUserProcess failed: ',error);
return [];
}
return userProcessList;
}
public async getProcessByName(name: string): Promise<Process | null> {
console.log('getProcessByName name: '+name);
const indexedDB = await IndexedDB.getInstance();
const db = await indexedDB.getDb();
const process = await indexedDB.getFirstMatchWithIndex<Process>(db, indexedDB.getStoreList().AnkProcess, 'by_name', name);
console.log('getProcessByName process: '+process);
return process;
}
public async updateMessages(message: CachedMessage): Promise<void> {
const indexedDb = await IndexedDB.getInstance();
const db = await indexedDb.getDb();
try {
await indexedDb.setObject(db, indexedDb.getStoreList().AnkMessages, message, null);
} catch (error) {
throw error;
}
}
public async removeMessage(id: number): Promise<void> {
const indexedDb = await IndexedDB.getInstance();
const db = await indexedDb.getDb();
try {
await indexedDb.rmObject(db, indexedDb.getStoreList().AnkMessages, id);
} catch (error) {
throw error;
}
}
public async updateProcesses(): Promise<void> {
const services = await Services.getInstance();
const processList: Process[] = services.sdkClient.get_processes();
processList.forEach(async (process: Process) => {
const indexedDB = await IndexedDB.getInstance();
const db = await indexedDB.getDb();
try {
const processStore = await indexedDB.getObject<Process>(db, indexedDB.getStoreList().AnkProcess, process.id);
if (!processStore) {
await indexedDB.writeObject(db, indexedDB.getStoreList().AnkProcess, process, null);
}
} catch (error) {
console.error('Error while writing process', process.name, 'to indexedDB:', error);
}
})
}
public attachClickListener(elementId: string, callback: (event: Event) => void): void {
const element = document.getElementById(elementId);
element?.removeEventListener("click", callback);
element?.addEventListener("click", callback);
}
public attachSubmitListener(elementId: string, callback: (event: Event) => void): void {
const element = document.getElementById(elementId);
element?.removeEventListener("submit", callback);
element?.addEventListener("submit", callback);
}
public async revokeInjectHtml() {
const container = document.getElementById('containerId');
if (!container) {
console.error("No html container");
return;
}
container.innerHTML =
` <div class='card'>
<div class='side-by-side'>
<h3>Revoke an Id</h3>
<div>
<a href='#' id='displayrecover'>Recover</a>
</div>
</div>
<form id='form4nk' action='#'>
<label for='password'>Password :</label>
<input type='password' id='password' />
<hr/>
<div class='image-container'>
<label class='image-label'>Revoke image</label>
<img src='assets/revoke.jpeg' alt='' />
</div>
<hr/>
<button type='submit' id='submitButton' class='recover bg-primary'>Revoke</button>
</form>
</div>
`;
}
public async revokeImageInjectHtml() {
const container = document.getElementById('containerId');
if (!container) {
console.error("No html container");
return;
}
container.innerHTML =
`<div class='card'>
<div class='side-by-side'>
<h3>Revoke image</h3>
<div><a href='#' id='displayupdateanid'>Update an Id</a></div>
</div>
</div>
<div class='card-revoke'>
<a href='#' download='revoke_4NK.jpg' id='revoke'>
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512'>
<path
d='M246.6 9.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192 109.3V320c0 17.7 14.3 32 32 32s32-14.3 32-32V109.3l73.4 73.4c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-128-128zM64 352c0-17.7-14.3-32-32-32s-32 14.3-32 32v64c0 53 43 96 96 96H352c53 0 96-43 96-96V352c0-17.7-14.3-32-32-32s-32 14.3-32 32v64c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V352z'
/>
</svg>
</a>
<div class='image-container'>
<img src='assets/4nk_revoke.jpg' alt='' />
</div>
</div>`;
}
public async recoverInjectHtml() {
const container = document.getElementById('containerId');
if (!container) {
console.error("No html container");
return;
}
const services = await Services.getInstance();
await services.updateProcesses();
container.innerHTML =
`<div class='card'>
<div class='side-by-side'>
<h3>Recover my Id</h3>
<div><a href='#'>Processes</a></div>
</div>
<form id='form4nk' action='#'>
<label for='password'>Password :</label>
<input type='password' id='password' />
<input type='hidden' id='currentpage' value='recover' />
<select id='selectProcess' class='custom-select'></select><hr/>
<div class='side-by-side'>
<button type='submit' id='submitButton' class='recover bg-primary'>Recover</button>
<div>
<a href='#' id='displaycreateid'>Create an Id</a>
</div>
</div><hr/>
<a href='#' id='displayrevoke' class='btn'>Revoke</a>
</form><br/>
<div id='passwordalert' class='passwordalert'></div>
</div>`;
}
public async createIdInjectHtml() {
const container = document.getElementById('containerId');
if (!container) {
console.error("No html container");
return;
}
container.innerHTML =
`<div class='card'>
<div class='side-by-side'>
<h3>Create an Id</h3>
<div><a href='#'>Processes</a></div>
</div>
<form id='form4nk' action='#'>
<label for='password'>Password :</label>
<input type='password' id='password' /><hr/>
<input type='hidden' id='currentpage' value='creatid' />
<select id='selectProcess' class='custom-select'></select><hr/>
<div class='side-by-side'>
<button type='submit' id='submitButton' class='bg-primary'>Create</button>
<div>
<a href='#' id='displayrecover'>Recover</a>
</div>
</div>
</form><br/>
<div id='passwordalert' class='passwordalert'></div>
</div>`;
}
public async updateIdInjectHtml() {
const container = document.getElementById('containerId');
if (!container) {
console.error("No html container");
return;
}
container.innerHTML =
`<body>
<div class='container'>
<div>
<h3>Update an Id</h3>
</div>
<hr />
<form id='form4nk' action='#'>
<label for='firstName'>First Name:</label>
<input type='text' id='firstName' name='firstName' required />
<label for='lastName'>Last Name:</label>
<input type='text' id='lastName' name='lastName' required />
<label for='Birthday'>Birthday:</label>
<input type='date' id='Birthday' name='birthday' />
<label for='file'>File:</label>
<input type='file' id='fileInput' name='file' />
<label>Third parties:</label>
<div id='sp-address-block'>
<div class='side-by-side'>
<input
type='text'
name='sp-address'
id='sp-address'
placeholder='sp address'
form='no-form'
/>
<button
type='button'
class='circle-btn bg-secondary'
id='add-sp-address-btn'
>
+
</button>
</div>
</div>
<div class='div-text-area'>
<textarea
name='bio'
id=''
cols='30'
rows='10'
placeholder='Bio'
></textarea>
</div>
<button type='submit' class='bg-primary'>Update</button>
</form>
</div>
</body>`;
}
public async injectHtml(processName: string) {
const container = document.getElementById('containerId');
if (!container) {
console.error("No html container");
return;
}
const services = await Services.getInstance();
// do we have all processes in db?
const knownProcesses = await services.getAllProcess();
const processesFromNetwork: Process[] = services.sdkClient.get_processes();
const processToAdd = processesFromNetwork.filter(processFromNetwork => !knownProcesses.some(knownProcess => knownProcess.id === processFromNetwork.id));
processToAdd.forEach(async p => {
await services.addProcess(p);
})
// get the process we need
const process = await services.getProcessByName(processName);
if (process) {
container.innerHTML = process.html;
} else {
console.error("No process ", processName);
}
}
// public async getCurrentProcess(): Promise<string> {
// let currentProcess = "";
// try {
// const indexedDB = await IndexedDB.getInstance();
// const db = indexedDB.getDb();
// currentProcess = await indexedDB.getObject<string>(db, indexedDB.getStoreList().AnkSession, Services.CURRENT_PROCESS);
// } catch (error) {
// console.error("Failed to retrieve currentprocess object :", error);
// }
// return currentProcess;
// }
public isPasswordValid(password: string) {
var alertElem = document.getElementById("passwordalert");
var success = true;
var strength = 0;
if (password.match(/[a-z]+/)) {
var strength = 0;
strength += 1;
}
if (password.match(/[A-Z]+/)) {
strength += 1;
}
if (password.match(/[0-9]+/)) {
strength += 1;
}
if (password.match(/[$@#&!]+/)) {
strength += 1;
}
if (alertElem !== null) {
// TODO Passer à 18
if (password.length < 4) {
alertElem.innerHTML = "Password size is < 4";
success = false;
} else {
if (password.length > 30) {
alertElem.innerHTML = "Password size is > 30";
success = false;
} else {
if (strength < 4) {
alertElem.innerHTML = "Password need [a-z] [A-Z] [0-9]+ [$@#&!]+";
success = false;
}
}
}
}
return success;
}
private async pickWebsocketConnectionRandom(): Promise<WebSocketClient | null> {
const services = await Services.getInstance();
const websockets = services.websocketConnection;
if (websockets.length === 0) {
console.error("No websocket connection available at the moment");
return null;
} else {
const random = Math.floor(Math.random() * websockets.length);
return websockets[random];
}
}
public async obtainTokenWithFaucet(): Promise<void> {
const services = await Services.getInstance();
const connection = await services.pickWebsocketConnectionRandom();
if (!connection) {
throw 'no available relay connections';
}
let cachedMsg: CachedMessage;
try {
const flag: AnkFlag = 'Faucet';
cachedMsg = services.sdkClient.create_faucet_msg();
if (cachedMsg.commitment && cachedMsg.recipient) {
let faucetMsg: FaucetMessage = {
sp_address: cachedMsg.recipient,
commitment: cachedMsg.commitment,
error: null,
}
connection.sendMessage(flag, JSON.stringify(faucetMsg));
}
} catch (error) {
throw `Failed to obtain tokens with relay ${connection.getUrl()}: ${error}`;
}
try {
await services.updateMessages(cachedMsg);
} catch (error) {
throw error;
}
}
public async updateUser(user: User): Promise<void> {
try {
const indexedDB = await IndexedDB.getInstance();
const db = await indexedDB.getDb();
await indexedDB.setObject(db, indexedDB.getStoreList().AnkUser, user, null);
} catch (error) {
throw error;
}
}
public async getUserInfo(): Promise<User | null> {
try {
const indexedDB = await IndexedDB.getInstance();
const db = await indexedDB.getDb();
let user = await indexedDB.getAll<User>(db, indexedDB.getStoreList().AnkUser);
// This should never happen
if (user.length > 1) {
throw "Multiple users in db";
} else {
let res = user.pop();
if (res === undefined) {
return null;
} else {
return res;
}
}
} catch (error) {
throw error;
}
}
public async answer_confirmation_message(msg: CachedMessage): Promise<void> {
const services = await Services.getInstance();
const connection = await services.pickWebsocketConnectionRandom();
if (!connection) {
throw new Error("No connection to relay");
}
let user: User;
try {
let possibleUser = await services.getUserInfo();
if (!possibleUser) {
throw new Error("No user loaded, please first create a new user or login");
} else {
user = possibleUser;
}
} catch (error) {
throw error;
}
let notificationInfo: createTransactionReturn;
try {
const feeRate = 1;
notificationInfo = services.sdkClient.answer_confirmation_transaction(msg.id, feeRate);
} catch (error) {
throw new Error(`Failed to create confirmation transaction: ${error}`);
}
const flag: AnkFlag = "NewTx";
const newTxMsg: NewTxMessage = {
'transaction': notificationInfo.transaction,
'tweak_data': null,
'error': null,
}
connection.sendMessage(flag, JSON.stringify(newTxMsg));
await services.updateMessages(notificationInfo.new_network_msg);
return;
}
public async confirm_sender_address(msg: CachedMessage): Promise<void> {
const services = await Services.getInstance();
const connection = await services.pickWebsocketConnectionRandom();
if (!connection) {
throw new Error("No connection to relay");
}
let user: User;
try {
let possibleUser = await services.getUserInfo();
if (!possibleUser) {
throw new Error("No user loaded, please first create a new user or login");
} else {
user = possibleUser;
}
} catch (error) {
throw error;
}
let notificationInfo: createTransactionReturn;
try {
const feeRate = 1;
notificationInfo = services.sdkClient.create_confirmation_transaction(msg.id, feeRate);
} catch (error) {
throw new Error(`Failed to create confirmation transaction: ${error}`);
}
const flag: AnkFlag = "NewTx";
const newTxMsg: NewTxMessage = {
'transaction': notificationInfo.transaction,
'tweak_data': null,
'error': null,
}
connection.sendMessage(flag, JSON.stringify(newTxMsg));
await services.updateMessages(notificationInfo.new_network_msg);
return;
}
public async notify_address_for_message(sp_address: string, message: CipherMessage): Promise<createTransactionReturn> {
const services = await Services.getInstance();
const connection = await services.pickWebsocketConnectionRandom();
if (!connection) {
throw 'No available connection';
}
try {
const feeRate = 1;
let notificationInfo: createTransactionReturn = services.sdkClient.create_notification_transaction(sp_address, message, feeRate);
const flag: AnkFlag = "NewTx";
const newTxMsg: NewTxMessage = {
'transaction': notificationInfo.transaction,
'tweak_data': null,
'error': null,
}
connection.sendMessage(flag, JSON.stringify(newTxMsg));
console.info('Successfully sent notification transaction');
return notificationInfo;
} catch (error) {
throw 'Failed to create notification transaction:", error';
}
}
}
export default Services;

170
src/style/4nk.css Normal file
View File

@ -0,0 +1,170 @@
body {
margin: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f4f4f4;
font-family: 'Arial', sans-serif;
}
.container {
text-align: center;
}
.card {
max-width: 400px;
width: 100%;
padding: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background-color: #ffffff;
border-radius: 8px;
text-align: left;
overflow: hidden;
}
form {
display: flex;
flex-direction: column;
/* flex-wrap: wrap; */
}
label {
font-weight: bold;
margin-bottom: 8px;
}
hr {
border: 0;
height: 1px;
background-color: #ddd;
margin: 10px 0;
}
input, select {
width: 100%;
padding: 10px;
margin: 8px 0;
box-sizing: border-box;
}
select {
padding: 10px;
background-color: #f9f9f9;
border: 1px solid #ddd;
border-radius: 4px;
cursor: pointer;
}
button {
display: inline-block;
background-color: #4caf50;
color: #fff;
border: none;
padding: 12px 17px;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
.side-by-side {
display: flex;
align-items: center;
justify-content: space-between;
}
.side-by-side>* {
display: inline-block;
}
button.recover {
display: inline-block;
text-align: center;
text-decoration: none;
display: inline-block;
background-color: #4caf50;
color: #fff;
border: none;
padding: 12px 17px;
border-radius: 4px;
cursor: pointer;
}
button.recover:hover {
background-color: #45a049;
}
a.btn {
display: inline-block;
text-align: center;
text-decoration: none;
display: inline-block;
background-color: #4caf50;
color: #fff;
border: none;
padding: 12px 17px;
border-radius: 4px;
cursor: pointer;
}
a.btn:hover {
background-color: #45a049;
}
a {
text-decoration: none;
color: #78a6de;
}
.bg-secondary {
background-color: #2b81ed;
}
.bg-primary {
background-color: #1A61ED;
}
.bg-primary:hover {
background-color: #457be8;
}
.card-revoke {
display: flex;
flex-direction: column;
max-width: 400px;
width: 100%;
padding: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
background-color: #ffffff;
border-radius: 8px;
text-align: center;
align-items: center;
overflow: hidden;
}
.card-revoke a {
max-width: 50px;
width: 100%;
background: none;
border: none;
cursor: pointer;
}
.card-revoke button {
max-width: 200px;
width: 100%;
background: none;
border: none;
cursor: pointer;
color: #78a6de;
}
.card-revoke svg {
width: 100%;
height: auto;
fill: #333;
}
.image-label {
display: block;
color: #fff;
padding: 5px;
margin-top: 10px;
}
.image-container {
width: 400px;
height: 300px;
overflow: hidden;
}
.image-container img {
text-align: center;
width: 100%;
height: 100%;
object-fit: cover;
object-position: center center;
}
.passwordalert {
color: #FF0000;
}

View File

@ -1,59 +0,0 @@
use anyhow::{Error, Result};
use rand::{self, thread_rng, Rng, RngCore};
use sdk_common::sp_client::bitcoin::consensus::{deserialize, serialize};
use sdk_common::sp_client::bitcoin::hashes::{Hash, HashEngine};
use sdk_common::sp_client::bitcoin::hex::{DisplayHex, FromHex};
use sdk_common::sp_client::bitcoin::key::{Parity, Secp256k1};
use sdk_common::sp_client::bitcoin::secp256k1::{PublicKey, SecretKey, ThirtyTwoByteHash};
use sdk_common::sp_client::bitcoin::{
Network, OutPoint, ScriptBuf, Transaction, Txid, XOnlyPublicKey,
};
use sdk_common::sp_client::SpClient;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
use tsify::Tsify;
use wasm_bindgen::convert::VectorFromWasmAbi;
use wasm_bindgen::prelude::*;
use std::collections::HashMap;
use std::fs::File;
use std::io::{Cursor, Read, Write};
use std::str::FromStr;
use std::sync::{Mutex, MutexGuard, OnceLock};
use sdk_common::device::Device;
use sdk_common::sp_client::bitcoin::secp256k1::constants::SECRET_KEY_SIZE;
use sdk_common::sp_client::silentpayments::bitcoin_hashes::sha256;
use sdk_common::sp_client::silentpayments::{
Network as SpNetwork,
SilentPaymentAddress
};
use crate::peers::Peer;
use crate::wallet::generate_sp_wallet;
use crate::MutexExt;
use sdk_common::crypto::{AeadCore, Aes256Gcm, KeyInit};
pub static LOCAL_DEVICE: OnceLock<Mutex<Device>> = OnceLock::new();
pub fn set_new_device(sp_client: SpClient) -> Result<String> {
let mut device = Device::new(sp_client);
let mut local_device = lock_local_device()?;
if *local_device.get_sp_client() != SpClient::default() {
return Err(Error::msg("Device already initialized".to_owned()));
} else {
*local_device = device;
}
let our_address = local_device
.get_address();
Ok(our_address.to_string())
}
pub fn lock_local_device() -> Result<MutexGuard<'static, Device>> {
LOCAL_DEVICE
.get_or_init(|| Mutex::new(Device::default()))
.lock_anyhow()
}

View File

@ -1,31 +0,0 @@
use std::{
collections::HashSet,
sync::{Mutex, MutexGuard, OnceLock},
};
use anyhow::Error;
use rand::Rng;
use sdk_common::sp_client::{
bitcoin::{secp256k1::SecretKey, Network, OutPoint},
silentpayments::SilentPaymentAddress,
SpClient, SpendKey,
};
use crate::MutexExt;
pub static FREEZED_UTXOS: OnceLock<Mutex<HashSet<OutPoint>>> = OnceLock::new();
pub fn lock_freezed_utxos() -> Result<MutexGuard<'static, HashSet<OutPoint>>, Error> {
FREEZED_UTXOS
.get_or_init(|| Mutex::new(HashSet::new()))
.lock_anyhow()
}
pub fn generate_sp_wallet(network: Network) -> anyhow::Result<SpClient> {
let mut rng = rand::thread_rng();
SpClient::new(
SecretKey::new(&mut rng),
SpendKey::Secret(SecretKey::new(&mut rng)),
network,
)
}

117
src/websockets.ts Normal file
View File

@ -0,0 +1,117 @@
import Services from "./services";
import { AnkFlag, AnkNetworkMsg, CachedMessage } from "../dist/pkg/sdk_client";
class WebSocketClient {
private ws: WebSocket;
private messageQueue: string[] = [];
constructor(url: string, private services: Services) {
this.ws = new WebSocket(url);
this.ws.addEventListener('open', (event) => {
console.log('WebSocket connection established');
// Once the connection is open, send all messages in the queue
while (this.messageQueue.length > 0) {
const message = this.messageQueue.shift();
if (message) {
this.ws.send(message);
}
}
});
// Listen for messages
this.ws.addEventListener('message', (event) => {
const msgData = event.data;
(async () => {
if (typeof(msgData) === 'string') {
console.log("Received text message: "+msgData);
try {
const feeRate = 1;
// By parsing the message, we can link it with existing cached message and return the updated version of the message
let res: CachedMessage = await services.parseNetworkMessage(msgData, feeRate);
console.debug(res);
if (res.status === 'FaucetComplete') {
// we received a faucet tx, there's nothing else to do
window.alert(`New faucet output\n${res.commited_in}`);
await services.updateMessages(res);
await services.updateOwnedOutputsForUser();
} else if (res.status === 'TxWaitingCipher') {
// we received a tx but we don't have the cipher
console.debug(`received notification in output ${res.commited_in}, waiting for cipher message`);
await services.updateMessages(res);
await services.updateOwnedOutputsForUser();
} else if (res.status === 'CipherWaitingTx') {
// we received a cipher but we don't have the key
console.debug(`received a cipher`);
await services.updateMessages(res);
} else if (res.status === 'SentWaitingConfirmation') {
// We are sender and we're waiting for the challenge that will confirm recipient got the transaction and the message
await services.updateMessages(res);
await services.updateOwnedOutputsForUser();
} else if (res.status === 'MustSpendConfirmation') {
// we received a challenge for a notification we made
// that means we can stop rebroadcasting the tx and we must spend the challenge to confirm
window.alert(`Spending ${res.confirmed_by} to prove our identity`);
console.debug(`sending confirm message to ${res.recipient}`);
await services.updateMessages(res);
await services.answer_confirmation_message(res);
} else if (res.status === 'ReceivedMustConfirm') {
// we found a notification and decrypted the cipher
window.alert(`Received message from ${res.sender}\n${res.plaintext}`);
// we must spend the commited_in output to sender
await services.updateMessages(res);
await services.confirm_sender_address(res);
} else if (res.status === 'Complete') {
window.alert(`Received confirmation that ${res.sender} is the author of message ${res.plaintext}`)
await services.updateMessages(res);
await services.updateOwnedOutputsForUser();
} else {
console.debug('Received an unimplemented valid message');
}
} catch (error) {
console.error('Received an invalid message:', error);
}
} else {
console.error('Received a non-string message');
}
})();
});
// Listen for possible errors
this.ws.addEventListener('error', (event) => {
console.error('WebSocket error:', event);
});
// Listen for when the connection is closed
this.ws.addEventListener('close', (event) => {
console.log('WebSocket is closed now.');
});
}
// Method to send messages
public sendMessage(flag: AnkFlag, message: string): void {
if (this.ws.readyState === WebSocket.OPEN) {
const networkMessage: AnkNetworkMsg = {
'flag': flag,
'content': message
}
// console.debug("Sending message:", JSON.stringify(networkMessage));
this.ws.send(JSON.stringify(networkMessage));
} else {
console.warn('WebSocket is not open. ReadyState:', this.ws.readyState);
this.messageQueue.push(message);
}
}
public getUrl(): string {
return this.ws.url;
}
// Method to close the WebSocket connection
public close(): void {
this.ws.close();
}
}
export { WebSocketClient };

View File

@ -1,199 +0,0 @@
use std::collections::HashMap;
use sdk_client::api::{
create_connect_transaction, create_device_from_sp_wallet, dump_device, get_address, get_outputs, parse_cipher, reset_device, reset_shared_secrets, restore_device, set_shared_secrets, setup, ApiReturn
};
use sdk_common::log::debug;
use sdk_common::pcd::Member;
use sdk_common::secrets::SecretsStore;
use sdk_common::sp_client::bitcoin::OutPoint;
use sdk_common::sp_client::spclient::OwnedOutput;
use sdk_common::sp_client::silentpayments::utils::SilentPaymentAddress;
use tsify::JsValueSerdeExt;
use wasm_bindgen_test::*;
mod utils;
use utils::*;
wasm_bindgen_test_configure!(run_in_browser);
#[wasm_bindgen_test]
/// Tests the connection process between two devices, Alice and Bob, by executing a secure
/// transaction to establish a shared secret for encrypted communication.
///
/// The basics are that one device will initiate the process by sending a transaction that pays another device.
/// The recipient of the transaction as soon as it finds it, can extract a shared secret and send an encrypted
/// message back. Upon receiving this message, the initiator answers with a similar message similarly encrypted.
/// Upon receiving this message, the recipient can be assured that the communication is safe, and start using
/// the secret to communicate.
///
/// The security of the shared secret rest on the soundness of the silent payment protocol for Bitcoin.
/// In its encrypted response, the initiator adds a signature that is proof that it indeed controls the
/// private key for the silent payment address it announced, so recipient knows there's no mitm or impostor.
///
/// # Detailed Process
///
/// ## Alice sends a transaction that pays Bob:
/// - Alice initializes her device from an `sp_wallet` object and sets it as the local device.
/// - She retrieves her own address and obtains Bobs address.
/// - Alice creates a new member using Bobs device address (this is mainly for testing purpose,
/// because `create_connection_transaction` would take members as argument).
/// - She generates a connection transaction (`connect_tx`) targeting Bob's device.
/// - Alice processes her own transaction and stores the derived shared secrets in `alice_secrets_store`,
/// associating the shared secret with Bob's addresses.
///
/// ## Bob parses the transaction:
/// - Bob initializes his device from his own `sp_wallet`.
/// - He parses Alices connection transaction to retrieve the shared secret Alice created for him.
/// - Bob saves these derived shared secrets in `bob_secrets_store` but can't index it with Alice's address yet.
///
/// ## Prd Connect exchange
/// - Bob then responds by sending a prd connect back to Alice encrypted with the shared secret.
/// This prd is very simple and basically contains the following:
/// * All Bob's devices addresses
/// * a commitment to the shared secret
/// * a proof signed with Bob's device spend key
/// - Alice receives and decrypts the message from Bob.
/// - She replies to Bob by encrypting another prd connect which is basically the same, but keeping Bob's proof and adding her own.
/// - **Bobs Confirmation**: Bob receives Alices confirmation message, decrypts it, and updates his secret in `bob_secrets_store`.
///
/// ## Verification:
/// - Finally, the function asserts that Alice and Bob now share the same secrets, confirming successful
/// connection and mutual authentication between the devices.
fn test_connect() {
setup();
let mut alice_secrets_store = SecretsStore::new();
let mut bob_secrets_store = SecretsStore::new();
debug!("==============================================\nStarting test_connect\n==============================================");
// ========================= Alice
reset_device().unwrap();
create_device_from_sp_wallet(ALICE_LOGIN_WALLET.to_owned()).unwrap();
// we get our own address
let alice_address = get_address().unwrap();
// we scan the qr code or get the address by any other means
let bob_address = helper_get_bob_address();
debug!("Alice establishes a shared secret with Bob");
// We just send a transaction to Bob device to allow them to share encrypted message
// Since we're not paired we can just put bob's address in a disposable member
// create_connect_transaction needs to take members though because most of the time we'd rather create secrets with all the devices of a member
let bob_member = Member::new(vec![SilentPaymentAddress::try_from(bob_address.as_str()).unwrap()]).unwrap();
let alice_connect_return = create_connect_transaction(vec![serde_json::to_string(&bob_member).unwrap()], 1).unwrap();
debug!("alice_connect_return: {:#?}", alice_connect_return);
let connect_tx_msg = alice_connect_return.new_tx_to_send.unwrap();
// This is only for testing, the relay takes care of that in prod
let get_outputs_result = get_outputs().unwrap();
let alice_outputs: HashMap<OutPoint, OwnedOutput> = get_outputs_result.into_serde().unwrap();
let alice_pairing_tweak_data =
helper_get_tweak_data(&connect_tx_msg.transaction, alice_outputs);
// End of the test only part
// Alice parses her own transaction
helper_parse_transaction(&connect_tx_msg.transaction, &alice_pairing_tweak_data);
let alice_connect_transaction = connect_tx_msg.transaction;
let alice_device = dump_device().unwrap();
// Below is how to update our secrets store when secrets is Some
let secrets_update = alice_connect_return.secrets.unwrap();
let unconfirmed_secrets = secrets_update.get_all_unconfirmed_secrets();
if !unconfirmed_secrets.is_empty() {
for secret in unconfirmed_secrets {
alice_secrets_store.add_unconfirmed_secret(secret);
}
}
let updated_confirmed_secrets = secrets_update.get_all_confirmed_secrets();
if !updated_confirmed_secrets.is_empty() {
for (address, secret) in updated_confirmed_secrets {
alice_secrets_store.confirm_secret_for_address(secret, address);
}
}
// ======================= Bob
reset_device().unwrap();
reset_shared_secrets().unwrap();
create_device_from_sp_wallet(BOB_LOGIN_WALLET.to_owned()).unwrap();
debug!("Bob parses Alice connect transaction");
let bob_parsed_transaction_return = helper_parse_transaction(&alice_connect_transaction, &alice_pairing_tweak_data);
let bob_to_alice_cipher = &bob_parsed_transaction_return.ciphers_to_send[0];
let bob_device = dump_device().unwrap();
let updated_secrets = bob_parsed_transaction_return.secrets.unwrap();
let updated_unconfirmed_secrets = updated_secrets.get_all_unconfirmed_secrets();
if !updated_unconfirmed_secrets.is_empty() {
for secret in updated_unconfirmed_secrets {
bob_secrets_store.add_unconfirmed_secret(secret);
}
}
let updated_confirmed_secrets = updated_secrets.get_all_confirmed_secrets();
if !updated_confirmed_secrets.is_empty() {
for (address, secret) in updated_confirmed_secrets {
bob_secrets_store.confirm_secret_for_address(secret, address);
}
}
// ======================= Alice
reset_device().unwrap();
restore_device(alice_device).unwrap();
set_shared_secrets(serde_json::to_string(&alice_secrets_store).unwrap()).unwrap();
debug!("Alice receives the connect Prd");
let alice_parsed_connect = parse_cipher(bob_to_alice_cipher.clone()).unwrap();
// debug!("alice_parsed_confirm: {:#?}", alice_parsed_confirm);
let alice_to_bob_cipher = alice_parsed_connect.ciphers_to_send.get(0).unwrap();
let secrets_update = alice_parsed_connect.secrets.unwrap();
let unconfirmed_secrets = secrets_update.get_all_unconfirmed_secrets();
if !unconfirmed_secrets.is_empty() {
for secret in unconfirmed_secrets {
alice_secrets_store.add_unconfirmed_secret(secret);
}
}
let updated_confirmed_secrets = secrets_update.get_all_confirmed_secrets();
if !updated_confirmed_secrets.is_empty() {
for (address, secret) in updated_confirmed_secrets {
alice_secrets_store.confirm_secret_for_address(secret, address);
}
}
// ======================= Bob
reset_device().unwrap();
restore_device(bob_device).unwrap();
set_shared_secrets(serde_json::to_string(&bob_secrets_store).unwrap()).unwrap();
debug!("Bob parses alice prd connect");
let bob_parsed_connect = parse_cipher(alice_to_bob_cipher.clone()).unwrap();
let updated_secrets = bob_parsed_connect.secrets.unwrap();
let updated_unconfirmed_secrets = updated_secrets.get_all_unconfirmed_secrets();
if !updated_unconfirmed_secrets.is_empty() {
for secret in updated_unconfirmed_secrets {
bob_secrets_store.add_unconfirmed_secret(secret);
}
}
let updated_confirmed_secrets = updated_secrets.get_all_confirmed_secrets();
if !updated_confirmed_secrets.is_empty() {
for (address, secret) in updated_confirmed_secrets {
bob_secrets_store.confirm_secret_for_address(secret, address);
}
}
// Assert that Alice and Bob now has the same secret
assert!(alice_secrets_store.get_secret_for_address(bob_address.try_into().unwrap()) == bob_secrets_store.get_secret_for_address(alice_address.try_into().unwrap()));
}

View File

@ -1,317 +0,0 @@
use std::collections::HashMap;
use std::str::FromStr;
use sdk_client::api::{
create_device_from_sp_wallet, create_new_process, create_response_prd, create_update_message, dump_device, get_address, pair_device, parse_cipher, reset_device, restore_device, set_process_cache, set_shared_secrets, setup, update_process_state, validate_state
};
use sdk_common::crypto::AnkSharedSecretHash;
use sdk_common::log::debug;
use sdk_common::pcd::{Member, Pcd, RoleDefinition};
use sdk_common::secrets::SecretsStore;
use serde_json::{json, Map, Value};
use wasm_bindgen_test::*;
mod utils;
use utils::*;
wasm_bindgen_test_configure!(run_in_browser);
/// # Pairing Process Documentation between Alice and Bob
///
/// This test describes the secure pairing process between two devices, Alice and Bob.
///
/// ## What's pairing?
/// Pairing is a process, and abide by the same rules than any other process. The goal of pairing
/// is to define an identity on the network as a set of devices (defined by their sp_address).
/// Being a process it is public and can be audited by anyone, and be used as one's proof of identity.
/// It also contains a session keypair that is updated as necessary. Since all devices are needed to
/// update the key in the process it can then be used to sign a proof that someone was indeed in control
/// of all the devices for some amount of time in a MFA setup.
/// It contains the following mandatory fields:
/// * `roles`: multiple devices represented as sp adresses linked together in the same member. It is recommended
/// to have one `owner` role with one member which is the actual identity and whose signatures are all
/// needed to modify anything in the process.
/// * `session_privkey`: a private key visible by all devices of the member defined in the process, but
/// not by other members. It *must* be changed at every update of the process. This key will be used
/// to sign documents and validate actions for other processes. It's valid as soon as the commitment
/// transaction for the process udpate is seen and it stays valid for _n_ blocks after the update being mined.
/// * `session_pubkey`: the x-only public key derived from the session private key. It's visible by everyone and
/// used for validation by any third party. Obviously it changes with the private key at any update.
/// * `parity`: the parity of the session_pubkey. We could use 33 bytes compressed public key format
/// but using 32 bytes publick key + parity allows for more standard serialization.
///
/// ## Detailed protocol
/// (Here Alice and Bob are used as a convention, but keep in mind they're not 2 different users, but
/// 2 devices belonging to the same user)
/// ## Step 0 - Preliminary step
/// 1. **Establishing a Shared Secret**: A shared secret is established to secure
/// communication between Alice and Bob (see `connect.rs`).
/// ## Step 1 - Pairing Preparation by Alice
/// 1. **Pairing Status Check**: Alice verifies that it's not already paired.
/// 2. **Adding Bob's Address**: Alice adds Bobs address to her own, setting the base for creating
/// a new `Member` object.
/// 3. **Creation of the pairing process**: Alice initializes pairing by creating a prd update that contains
/// both its address and Bob's, and send it to Bob.
///
/// ## Step 2 - Receiving and Confirming the `prd` by Bob
/// 1. **Receiving and Verifying**: Bob receives and decrypts the update `prd` message sent by Alice.
/// 2. **Updating Process State**: Bob identifies the new process and store it, but it doesn't have access
/// to the actual data for now.
/// 3. **Creating and Sending `Prd Confirm`**: Bob creates a confirmation `prd`, which he then
/// sends to Alice to get the pcd containing the state for this new process.
///
/// ## Step 3 - Alice gets confirmation and answers with a pcd
/// 1. **Receiving and Verifying**: Alice receives the `Prd Confirm` sent by Bob.
/// 2. **Sending PCD**: Alice having confirmation that Bob got the update proposal,
/// it now sends the actual data in a pcd.
/// 3. **User confirmation**: At this step we must get the approval of the user. If user confirms
/// the pairing we create a prd response with a valid signature from Alice spend key and send
/// it to Bob.
///
/// ## Step 4 - Finalizing Pairing by Bob
/// 1. **Receiving and Verifying `pcd`**: Bob received the `pcd` and only now can tell what's the
/// process was about.
/// 2. **Validating Pairing State**: Bob retrieves the latest process state and the state change
/// request, in this case, the pairing. User is prompted for validation, and if confirmed a prd response
/// is created and sent(see the **User confirmation** step for Alice).
///
/// ## Commiting the process state
/// 1. **Creating the `commit_msg`**: The first device that got both validations creates the commit_msg that
/// contains a transaction paying a relay to generate the first outpoint to commit the state of the process,
/// the hash of the encrypted state of the process (relay must have access to roles though, either it is clear
/// all along or it was provided with the encryption keys) and the proofs that all devices validated this state.
/// 2. **Actual commitment**: As soon as the relay validated the proofs it spends the outpoint and puts the hash of
/// the whole prd response (including pcd hash and all the proofs) in an OP_RETURN output. The process is now
/// public and can be used to prove identity for other processes.
#[wasm_bindgen_test]
fn test_pairing() {
const RELAY_ADDRESS: &str = "tsp1qqvfm6wvd55r68ltysdhmagg7qavxrzlmm9a7tujsp8qqy6x2vr0muqajt5p2jdxfw450wyeygevypxte29sxlxzgprmh2gwnutnt09slrcqqy5h4";
setup();
let mut alice_process_cache = HashMap::new();
let mut bob_process_cache = HashMap::new();
let mut alice_secrets_store = SecretsStore::new();
let mut bob_secrets_store = SecretsStore::new();
let mut alice_diff_cache = Vec::new();
let mut bob_diff_cache = Vec::new();
debug!("==============================================\nStarting test_pairing\n==============================================");
// ========================= Alice
reset_device().unwrap();
create_device_from_sp_wallet(ALICE_LOGIN_WALLET.to_owned()).unwrap();
// we get our own address
let alice_address = get_address().unwrap();
debug!("alice address: {}", alice_address);
// we scan the qr code or get the address by any other means
let bob_address = helper_get_bob_address();
debug!("bob_address: {}", bob_address);
// we add some shared_secret in both secrets_store
let shared_secret = AnkSharedSecretHash::from_str("c3f1a64e15d2e8d50f852c20b7f0b47cbe002d9ef80bc79582d09d6f38612d45").unwrap();
alice_secrets_store.confirm_secret_for_address(shared_secret, bob_address.as_str().try_into().unwrap());
bob_secrets_store.confirm_secret_for_address(shared_secret, alice_address.as_str().try_into().unwrap());
set_shared_secrets(serde_json::to_string(&alice_secrets_store).unwrap()).unwrap();
// Alice creates the new member with Bob address
let new_member = Member::new(vec![
alice_address.as_str().try_into().unwrap(),
bob_address.as_str().try_into().unwrap(),
])
.unwrap();
let initial_session_privkey = [0u8; 32]; // In reality we would generate a random new key here
let initial_session_pubkey = [0u8; 32];
let pairing_init_state = json!({
"html": "",
"js": "",
"style": "",
"zones": [],
"description": "AliceBob",
"roles": {
"owner": {
"members":
[
new_member
],
"validation_rules":
[
{
"quorum": 1.0,
"fields": [
"description",
"roles",
"session_privkey",
"session_pubkey",
"key_parity"
],
"min_sig_member": 1.0
}
],
"storages": []
}
},
"session_privkey": initial_session_privkey,
"session_pubkey": initial_session_pubkey,
"key_parity": true, // This allows us to use a 32 bytes array in serialization
});
debug!("Alice creates the pairing process");
let create_process_return = create_new_process(pairing_init_state.to_string(), None, RELAY_ADDRESS.to_owned(), 1).unwrap();
let commit_msg = create_process_return.commit_to_send.unwrap();
let secrets_update = create_process_return.secrets.unwrap();
let unconfirmed_secrets = secrets_update.get_all_unconfirmed_secrets();
if !unconfirmed_secrets.is_empty() {
for secret in unconfirmed_secrets {
alice_secrets_store.add_unconfirmed_secret(secret);
}
}
let updated_confirmed_secrets = secrets_update.get_all_confirmed_secrets();
if !updated_confirmed_secrets.is_empty() {
for (address, secret) in updated_confirmed_secrets {
alice_secrets_store.confirm_secret_for_address(secret, address);
}
}
let updated_process = create_process_return.updated_process.unwrap();
alice_process_cache.insert(updated_process.commitment_tx, updated_process.current_process);
// Alice keeps track of the change she needs to validate
let create_process_diffs = updated_process.new_diffs;
let new_state_id = &create_process_diffs.get(0).unwrap().state_id;
alice_diff_cache.extend(create_process_diffs.iter());
// We send the commit_msg to the relay we got the address from
// now we create prd update for this new process
debug!("Alice creates an update prd to Bob");
let create_update_return = create_update_message(updated_process.commitment_tx.to_string(), new_state_id.clone()).unwrap();
let updated_process = create_update_return.updated_process.unwrap();
alice_process_cache.insert(updated_process.commitment_tx, updated_process.current_process);
debug!("Alice pairs her device");
pair_device(updated_process.commitment_tx.to_string(), vec![helper_get_bob_address()]).unwrap();
let alice_to_bob_cipher = &create_update_return.ciphers_to_send[0];
// this is only for testing, as we're playing both parts
let alice_device = dump_device().unwrap();
// ======================= Bob
reset_device().unwrap();
create_device_from_sp_wallet(BOB_LOGIN_WALLET.to_owned()).unwrap();
set_shared_secrets(serde_json::to_string(&bob_secrets_store).unwrap()).unwrap();
debug!("Bob receives the update prd");
let bob_parsed_return = parse_cipher(alice_to_bob_cipher.to_owned()).unwrap();
let updated_process = bob_parsed_return.updated_process.unwrap();
let parsed_prd_diffs = updated_process.new_diffs;
// debug!("Bob creates process {} with state {}", updated_process.commitment_tx, new_state_id);
bob_process_cache.insert(updated_process.commitment_tx, updated_process.current_process);
// Bob also keeps track of changes
bob_diff_cache.extend(parsed_prd_diffs.into_iter());
debug!("Bob can now fetch the data from storage using the hashes");
// We have to cheat here and let Bob access Alice process cache
let process = alice_process_cache.get(&updated_process.commitment_tx).unwrap();
let state = process.get_state_for_id(&new_state_id).unwrap();
let hash2values: Map<String, Value> = bob_diff_cache.iter()
.filter(|diff| diff.state_id == *new_state_id)
.map(|diff| {
let encrypted_value = state.encrypted_pcd.as_object().unwrap().get(&diff.field).unwrap();
(diff.value_commitment.clone(), encrypted_value.clone())
})
.collect();
let update_process_res = update_process_state(updated_process.commitment_tx.to_string(), new_state_id.clone(), serde_json::to_string(&Value::Object(hash2values)).unwrap()).unwrap();
let updated_process = update_process_res.updated_process.unwrap();
let parsed_prd_diffs = updated_process.new_diffs;
bob_process_cache.insert(updated_process.commitment_tx, updated_process.current_process);
bob_diff_cache.extend(parsed_prd_diffs);
// We can also prune the old diffs from the cache
bob_diff_cache.retain(|diff| diff.new_value != Value::Null);
// this is only for testing, as we're playing both parts
let bob_device = dump_device().unwrap();
// ======================= Alice
reset_device().unwrap();
restore_device(alice_device).unwrap();
set_process_cache(serde_json::to_string(&alice_process_cache).unwrap()).unwrap();
set_shared_secrets(serde_json::to_string(&alice_secrets_store).unwrap()).unwrap();
let commitment_outpoint = alice_process_cache.keys().next().unwrap();
debug!("Alice can validate the new state of the process");
let relevant_process = alice_process_cache.get(&commitment_outpoint).unwrap();
for diff in alice_diff_cache {
debug!("User validate diff: {:#?}", diff);
}
// Alice can also sign her response and send it to Bob
let validate_state_return = validate_state(commitment_outpoint.to_string(), new_state_id.clone()).unwrap();
let updated_process = validate_state_return.updated_process.unwrap();
alice_process_cache.insert(updated_process.commitment_tx, updated_process.current_process);
let alice_response = create_response_prd(updated_process.commitment_tx.to_string(), new_state_id.clone()).unwrap();
// ======================= Bob
reset_device().unwrap();
restore_device(bob_device).unwrap();
set_process_cache(serde_json::to_string(&bob_process_cache).unwrap()).unwrap();
set_shared_secrets(serde_json::to_string(&bob_secrets_store).unwrap()).unwrap();
for diff in &bob_diff_cache {
if diff.need_validation {
debug!("Pop-up: User confirmation");
debug!("{:#?}", diff);
}
}
// If user is ok, we can add our own validation token
// Get the whole commitment from the process
let bob_validated_process = validate_state(updated_process.commitment_tx.to_string(), new_state_id.clone()).unwrap();
let updated_process = bob_validated_process.updated_process.unwrap();
bob_process_cache.insert(updated_process.commitment_tx, updated_process.current_process);
let bob_response = create_response_prd(updated_process.commitment_tx.to_string(), new_state_id.clone()).unwrap();
let ciphers = bob_response.ciphers_to_send; // We would send it to Alice to let her know we agree
debug!("Bob pairs device with Alice");
let roles: HashMap<String, RoleDefinition> = serde_json::from_value(bob_diff_cache.iter().find(|diff| diff.field == "roles").unwrap().new_value.clone()).unwrap();
let owner = roles.get("owner").unwrap();
let members_to_pair: Vec<String> = owner.members.iter().flat_map(|m| m.get_addresses()).collect();
pair_device(updated_process.commitment_tx.to_string(), members_to_pair).unwrap();
// We can also check alice response
let parsed_alice_response = parse_cipher(alice_response.ciphers_to_send[0].clone()).unwrap();
}

View File

@ -1,77 +0,0 @@
use std::collections::HashMap;
use sdk_client::api::{parse_new_tx, ApiReturn};
use sdk_common::network::NewTxMessage;
use sdk_common::sp_client::bitcoin::consensus::{deserialize, serialize};
use sdk_common::sp_client::bitcoin::hex::{DisplayHex, FromHex};
use sdk_common::sp_client::bitcoin::secp256k1::PublicKey;
use sdk_common::sp_client::bitcoin::{OutPoint, ScriptBuf, Transaction};
use sdk_common::sp_client::silentpayments::utils::receiving::{
calculate_tweak_data, get_pubkey_from_input,
};
use sdk_common::sp_client::spclient::{OwnedOutput, SpWallet};
use serde_json::{self, json, Value};
// We're using alice and bob for clarity, but it's important to remember that for pairing and login Alice and Bob are the same person
pub const ALICE_START_WALLET: &str = "{\"client\":{\"network\":\"testnet\",\"label\":\"default\",\"scan_sk\":\"e3d8922a41a7cb1a84a90f4334e987bb5ea2df6a1fdf44f789b5302de119f9e2\",\"spend_key\":{\"Secret\":\"93292e5b21042c6cfc742ba30e9d2a1e01609b12d154a1825184ed12c7b9631b\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Testnet\",\"scan_pubkey\":[2,104,242,105,185,6,124,208,34,44,149,52,163,38,63,221,150,12,198,24,95,143,126,235,37,149,233,88,118,32,86,233,152],\"spend_pubkey\":[3,198,82,196,243,12,59,126,109,143,144,157,128,176,168,94,54,134,232,139,115,102,11,178,128,244,239,251,40,228,67,153,72],\"change_label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"labels\":[[\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",[2,244,223,255,57,50,216,27,133,112,138,69,120,126,85,110,6,242,141,33,136,191,82,164,241,54,179,115,84,161,145,174,154]]]}},\"outputs\":{\"wallet_fingerprint\":[187,119,108,230,171,125,106,11],\"birthday\":1620,\"last_scan\":2146,\"outputs\":{\"9a4a67cc5a40bf882d8b300d91024d7c97024b3b68b2df7745a5b9ea1df1888c:1\":{\"blockheight\":1620,\"tweak\":\"b8b63b3ed97d297b744135cfac2fb4a344c881a77543b71f1fcd16bc67514f26\",\"amount\":3938643,\"script\":\"51205b7b324bb71d411e32f2c61fda5d1db23f5c7d6d416a77fab87c913a1b120be1\",\"label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"spend_status\":\"Unspent\"}}},\"tx_history\":[]}";
pub const ALICE_LOGIN_WALLET: &str = "{\"client\":{\"label\":\"default\",\"scan_sk\":\"e3d8922a41a7cb1a84a90f4334e987bb5ea2df6a1fdf44f789b5302de119f9e2\",\"spend_key\":{\"Secret\":\"93292e5b21042c6cfc742ba30e9d2a1e01609b12d154a1825184ed12c7b9631b\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Testnet\",\"scan_pubkey\":[2,104,242,105,185,6,124,208,34,44,149,52,163,38,63,221,150,12,198,24,95,143,126,235,37,149,233,88,118,32,86,233,152],\"spend_pubkey\":[3,198,82,196,243,12,59,126,109,143,144,157,128,176,168,94,54,134,232,139,115,102,11,178,128,244,239,251,40,228,67,153,72],\"change_label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"labels\":[[\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",[2,244,223,255,57,50,216,27,133,112,138,69,120,126,85,110,6,242,141,33,136,191,82,164,241,54,179,115,84,161,145,174,154]]]},\"network\":\"testnet\"},\"outputs\":{\"wallet_fingerprint\":[187,119,108,230,171,125,106,11],\"birthday\":1620,\"last_scan\":2146,\"outputs\":{\"e2c6ff9927c8a5f7a60087117732c07ab7cd82c0c65462e9c780eb5ce9c35292:1\":{\"blockheight\":0,\"tweak\":\"7c84a3074c18c23a65eceaca49a327989ef6e7240e0e080421afb80f06906d73\",\"amount\":306,\"script\":\"5120eb78084d7a2ccbdb7eb7e9bba7cf875c4e54a5aba0beac57c5d3e41133bd8fdd\",\"label\":null,\"spend_status\":\"Unspent\"},\"e2c6ff9927c8a5f7a60087117732c07ab7cd82c0c65462e9c780eb5ce9c35292:2\":{\"blockheight\":0,\"tweak\":\"e3e21d551e933199f8c977bc0362616bdfb128da7ca9728bd7254977541c39cc\",\"amount\":3936897,\"script\":\"5120df3af55a63bd056c5d6d09f47a3a19c382d938c08db8bc41a59c5235970209ad\",\"label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"spend_status\":\"Unspent\"},\"576c2e53fe924d68deb7262cfc0e4023b5889652dec35671e1e7cf255d61c28f:0\":{\"blockheight\":0,\"tweak\":\"6e5c1d4690b9ff4fa26e5185ada25af5c2987650e629a518db8a43fdaad7a26c\",\"amount\":349,\"script\":\"512088ac90e180c87b7fa6aa33db4c72a8620cd08fda3ba1c71430b904eb068c587f\",\"label\":null,\"spend_status\":\"Unspent\"},\"9a4a67cc5a40bf882d8b300d91024d7c97024b3b68b2df7745a5b9ea1df1888c:1\":{\"blockheight\":1620,\"tweak\":\"b8b63b3ed97d297b744135cfac2fb4a344c881a77543b71f1fcd16bc67514f26\",\"amount\":3938643,\"script\":\"51205b7b324bb71d411e32f2c61fda5d1db23f5c7d6d416a77fab87c913a1b120be1\",\"label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"spend_status\":{\"Spent\":\"e2c6ff9927c8a5f7a60087117732c07ab7cd82c0c65462e9c780eb5ce9c35292\"}}}},\"tx_history\":[]}";
pub const BOB_START_WALLET: &str = "{\"client\":{\"label\":\"default\",\"scan_sk\":\"0de90b7195c1380d5fde13de3f1d66d53423a9896314839e36ba672653af60b4\",\"spend_key\":{\"Secret\":\"affe686075ecbe17b8ce7de45ec31314804259d0a4bc1c863de21ffd6dc598f8\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Testnet\",\"scan_pubkey\":[2,85,96,92,243,247,237,192,205,9,178,146,101,237,132,232,15,2,69,138,31,118,76,140,142,207,90,13,192,94,254,150,133],\"spend_pubkey\":[3,5,157,91,250,169,41,61,190,37,30,98,152,253,180,138,250,86,162,102,82,148,130,220,44,153,127,83,43,246,93,17,232],\"change_label\":\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",\"labels\":[[\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",[2,237,237,247,213,154,87,34,239,168,235,87,122,152,94,41,35,101,184,201,58,201,6,185,58,157,52,208,129,167,2,224,198]]]},\"network\":\"testnet\"},\"outputs\":{\"wallet_fingerprint\":[203,200,4,248,139,36,241,232],\"birthday\":2146,\"last_scan\":2146,\"outputs\":{\"fbd9c63e0dd08c2569b51a0d6095a79ee2acfcac66acdb594328a095f1fadb63:1\":{\"blockheight\":2146,\"tweak\":\"678dbcbdb40cd3733c8dbbd508761a0937009cf75a9f466e3c98877e79037cbc\",\"amount\":99896595,\"script\":\"5120deab0c5a3d23de30477b0b5a95a261c96e29afdd9813c665d2bf025ad2b3f919\",\"label\":null,\"spend_status\":\"Unspent\"}}},\"tx_history\":[]}";
pub const BOB_LOGIN_WALLET: &str = "{\"client\":{\"label\":\"default\",\"scan_sk\":\"0de90b7195c1380d5fde13de3f1d66d53423a9896314839e36ba672653af60b4\",\"spend_key\":{\"Secret\":\"affe686075ecbe17b8ce7de45ec31314804259d0a4bc1c863de21ffd6dc598f8\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Testnet\",\"scan_pubkey\":[2,85,96,92,243,247,237,192,205,9,178,146,101,237,132,232,15,2,69,138,31,118,76,140,142,207,90,13,192,94,254,150,133],\"spend_pubkey\":[3,5,157,91,250,169,41,61,190,37,30,98,152,253,180,138,250,86,162,102,82,148,130,220,44,153,127,83,43,246,93,17,232],\"change_label\":\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",\"labels\":[[\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",[2,237,237,247,213,154,87,34,239,168,235,87,122,152,94,41,35,101,184,201,58,201,6,185,58,157,52,208,129,167,2,224,198]]]},\"network\":\"testnet\"},\"outputs\":{\"wallet_fingerprint\":[203,200,4,248,139,36,241,232],\"birthday\":2146,\"last_scan\":2146,\"outputs\":{\"93722ea2fb9b74954210b4cdd1360e280b7ff1bc156d6b75f847e62411c588fb:0\":{\"blockheight\":0,\"tweak\":\"da5e3aa2378e3a257f99eb1e0ae4c672916f6a2f32a8ed9a8e146f2074da981b\",\"amount\":443,\"script\":\"51209eb9e950127b6a7d81668f25b4d5b164b42dafe59ce40b80e6c489ec983540d7\",\"label\":null,\"spend_status\":\"Unspent\"},\"e2c6ff9927c8a5f7a60087117732c07ab7cd82c0c65462e9c780eb5ce9c35292:0\":{\"blockheight\":0,\"tweak\":\"0e3395ff27bde9187ffaeeb2521f6277d3b83911f16ccbaf59a1a68d99a0ab93\",\"amount\":1200,\"script\":\"512010f06f764cbc923ec3198db946307bf0c06a1b4f09206055e47a6fec0a33d52c\",\"label\":null,\"spend_status\":{\"Spent\":\"576c2e53fe924d68deb7262cfc0e4023b5889652dec35671e1e7cf255d61c28f\"}},\"576c2e53fe924d68deb7262cfc0e4023b5889652dec35671e1e7cf255d61c28f:1\":{\"blockheight\":0,\"tweak\":\"f0ad83734cdc7d73575e5a32651390cf30b92cc7e44cf94ec37da46900ecaf71\",\"amount\":654,\"script\":\"5120230cc1e85829be238e666f469653cbc2f1c0e3675a9bf33e1d1f91115f5dd306\",\"label\":\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",\"spend_status\":\"Unspent\"},\"fbd9c63e0dd08c2569b51a0d6095a79ee2acfcac66acdb594328a095f1fadb63:1\":{\"blockheight\":2146,\"tweak\":\"678dbcbdb40cd3733c8dbbd508761a0937009cf75a9f466e3c98877e79037cbc\",\"amount\":99896595,\"script\":\"5120deab0c5a3d23de30477b0b5a95a261c96e29afdd9813c665d2bf025ad2b3f919\",\"label\":null,\"spend_status\":\"Unspent\"}}},\"tx_history\":[]}";
pub const ALICE_PAIRED_DEVICE: &str = "{\"sp_wallet\":{\"client\":{\"label\":\"default\",\"scan_sk\":\"e3d8922a41a7cb1a84a90f4334e987bb5ea2df6a1fdf44f789b5302de119f9e2\",\"spend_key\":{\"Secret\":\"93292e5b21042c6cfc742ba30e9d2a1e01609b12d154a1825184ed12c7b9631b\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Testnet\",\"scan_pubkey\":[2,104,242,105,185,6,124,208,34,44,149,52,163,38,63,221,150,12,198,24,95,143,126,235,37,149,233,88,118,32,86,233,152],\"spend_pubkey\":[3,198,82,196,243,12,59,126,109,143,144,157,128,176,168,94,54,134,232,139,115,102,11,178,128,244,239,251,40,228,67,153,72],\"change_label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"labels\":[[\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",[2,244,223,255,57,50,216,27,133,112,138,69,120,126,85,110,6,242,141,33,136,191,82,164,241,54,179,115,84,161,145,174,154]]]},\"network\":\"testnet\"},\"outputs\":{\"wallet_fingerprint\":[187,119,108,230,171,125,106,11],\"birthday\":1620,\"last_scan\":2146,\"outputs\":{\"9a4a67cc5a40bf882d8b300d91024d7c97024b3b68b2df7745a5b9ea1df1888c:1\":{\"blockheight\":1620,\"tweak\":\"b8b63b3ed97d297b744135cfac2fb4a344c881a77543b71f1fcd16bc67514f26\",\"amount\":3938643,\"script\":\"51205b7b324bb71d411e32f2c61fda5d1db23f5c7d6d416a77fab87c913a1b120be1\",\"label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"spend_status\":{\"Spent\":\"e2c6ff9927c8a5f7a60087117732c07ab7cd82c0c65462e9c780eb5ce9c35292\"}},\"576c2e53fe924d68deb7262cfc0e4023b5889652dec35671e1e7cf255d61c28f:0\":{\"blockheight\":0,\"tweak\":\"6e5c1d4690b9ff4fa26e5185ada25af5c2987650e629a518db8a43fdaad7a26c\",\"amount\":349,\"script\":\"512088ac90e180c87b7fa6aa33db4c72a8620cd08fda3ba1c71430b904eb068c587f\",\"label\":null,\"spend_status\":{\"Spent\":\"8c701e6b62f4d2c4ddc779262f368dd156ea1c75a7097247fbdb6d344ac9c165\"}},\"8c701e6b62f4d2c4ddc779262f368dd156ea1c75a7097247fbdb6d344ac9c165:3\":{\"blockheight\":0,\"tweak\":\"ad5d59f98e2a49f2097d6847c4be66ab6e2125d3620924c5135c178afe0c450f\",\"amount\":3935006,\"script\":\"5120da6a7f478a357e277b4ebd295d65cc58900b29236f57cdf2d1541363c8eddd9d\",\"label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"spend_status\":\"Unspent\"},\"e2c6ff9927c8a5f7a60087117732c07ab7cd82c0c65462e9c780eb5ce9c35292:1\":{\"blockheight\":0,\"tweak\":\"7c84a3074c18c23a65eceaca49a327989ef6e7240e0e080421afb80f06906d73\",\"amount\":306,\"script\":\"5120eb78084d7a2ccbdb7eb7e9bba7cf875c4e54a5aba0beac57c5d3e41133bd8fdd\",\"label\":null,\"spend_status\":{\"Spent\":\"8c701e6b62f4d2c4ddc779262f368dd156ea1c75a7097247fbdb6d344ac9c165\"}},\"e2c6ff9927c8a5f7a60087117732c07ab7cd82c0c65462e9c780eb5ce9c35292:2\":{\"blockheight\":0,\"tweak\":\"e3e21d551e933199f8c977bc0362616bdfb128da7ca9728bd7254977541c39cc\",\"amount\":3936897,\"script\":\"5120df3af55a63bd056c5d6d09f47a3a19c382d938c08db8bc41a59c5235970209ad\",\"label\":\"ac14a827e2d023b8f7804303a47259366117d99ed932b641d4a8eaf1b82cc992\",\"spend_status\":{\"Spent\":\"8c701e6b62f4d2c4ddc779262f368dd156ea1c75a7097247fbdb6d344ac9c165\"}},\"8c701e6b62f4d2c4ddc779262f368dd156ea1c75a7097247fbdb6d344ac9c165:2\":{\"blockheight\":0,\"tweak\":\"c2ab55a30f0a575d139639ab2bc78e5e524dd85e5f1981297f601e890760c6d7\",\"amount\":546,\"script\":\"512040fb549d9cbb51f01fc29df8cd0714d33e3608507d1e3adaf015e35ed5e87b9f\",\"label\":null,\"spend_status\":\"Unspent\"},\"8c701e6b62f4d2c4ddc779262f368dd156ea1c75a7097247fbdb6d344ac9c165:0\":{\"blockheight\":0,\"tweak\":\"cfea493360d6ffe2bfd13e4c5c2f677351e0c038f1ce0cd5383fadad6adc79f1\",\"amount\":602,\"script\":\"51200f008ff13f876bf328c69f10ad8621c9770ff8d5eb1861cb67199189a6308bb9\",\"label\":null,\"spend_status\":\"Unspent\"}}},\"tx_history\":[]},\"pairing_process_commitment\":\"8c701e6b62f4d2c4ddc779262f368dd156ea1c75a7097247fbdb6d344ac9c165\",\"paired_member\":{\"sp_addresses\":[\"sprt1qqf2kqh8n7lkupngfk2fxtmvyaq8sy3v2ramyeryweadqmsz7l6tg2qc9n4dl42ff8klz28nznr7mfzh6263xv555stwzextl2v4lvhg3aqq7ru8u\",\"sprt1qqf50y6deqe7dqg3vj562xf3lmktqe3sct78ha6e9jh54sa3q2m5esq7x2tz0xrpm0ekclyyaszc2sh3ksm5gkumxpwegpa80lv5wgsuefqaufx8q\"]}}";
pub const BOB_PAIRED_DEVICE: &str = "{\"sp_wallet\":{\"client\":{\"label\":\"default\",\"scan_sk\":\"0de90b7195c1380d5fde13de3f1d66d53423a9896314839e36ba672653af60b4\",\"spend_key\":{\"Secret\":\"affe686075ecbe17b8ce7de45ec31314804259d0a4bc1c863de21ffd6dc598f8\"},\"mnemonic\":null,\"sp_receiver\":{\"version\":0,\"network\":\"Testnet\",\"scan_pubkey\":[2,85,96,92,243,247,237,192,205,9,178,146,101,237,132,232,15,2,69,138,31,118,76,140,142,207,90,13,192,94,254,150,133],\"spend_pubkey\":[3,5,157,91,250,169,41,61,190,37,30,98,152,253,180,138,250,86,162,102,82,148,130,220,44,153,127,83,43,246,93,17,232],\"change_label\":\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",\"labels\":[[\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",[2,237,237,247,213,154,87,34,239,168,235,87,122,152,94,41,35,101,184,201,58,201,6,185,58,157,52,208,129,167,2,224,198]]]},\"network\":\"testnet\"},\"outputs\":{\"wallet_fingerprint\":[203,200,4,248,139,36,241,232],\"birthday\":2146,\"last_scan\":2146,\"outputs\":{\"576c2e53fe924d68deb7262cfc0e4023b5889652dec35671e1e7cf255d61c28f:1\":{\"blockheight\":0,\"tweak\":\"f0ad83734cdc7d73575e5a32651390cf30b92cc7e44cf94ec37da46900ecaf71\",\"amount\":654,\"script\":\"5120230cc1e85829be238e666f469653cbc2f1c0e3675a9bf33e1d1f91115f5dd306\",\"label\":\"56572fc770b52096879662f97f98263d3e126f5a4a38f00f2895a9dde4c47c1c\",\"spend_status\":\"Unspent\"},\"93722ea2fb9b74954210b4cdd1360e280b7ff1bc156d6b75f847e62411c588fb:0\":{\"blockheight\":0,\"tweak\":\"da5e3aa2378e3a257f99eb1e0ae4c672916f6a2f32a8ed9a8e146f2074da981b\",\"amount\":443,\"script\":\"51209eb9e950127b6a7d81668f25b4d5b164b42dafe59ce40b80e6c489ec983540d7\",\"label\":null,\"spend_status\":\"Unspent\"},\"8c701e6b62f4d2c4ddc779262f368dd156ea1c75a7097247fbdb6d344ac9c165:1\":{\"blockheight\":0,\"tweak\":\"898284108952bd8b0e74030e00b81c1b387ee151a810ca3b40143da227707df2\",\"amount\":1000,\"script\":\"5120c0ff94a1318f0061960a713c927ff175a0d71a791497e94e70601c3baae739b8\",\"label\":null,\"spend_status\":\"Unspent\"},\"e2c6ff9927c8a5f7a60087117732c07ab7cd82c0c65462e9c780eb5ce9c35292:0\":{\"blockheight\":0,\"tweak\":\"0e3395ff27bde9187ffaeeb2521f6277d3b83911f16ccbaf59a1a68d99a0ab93\",\"amount\":1200,\"script\":\"512010f06f764cbc923ec3198db946307bf0c06a1b4f09206055e47a6fec0a33d52c\",\"label\":null,\"spend_status\":{\"Spent\":\"576c2e53fe924d68deb7262cfc0e4023b5889652dec35671e1e7cf255d61c28f\"}},\"fbd9c63e0dd08c2569b51a0d6095a79ee2acfcac66acdb594328a095f1fadb63:1\":{\"blockheight\":2146,\"tweak\":\"678dbcbdb40cd3733c8dbbd508761a0937009cf75a9f466e3c98877e79037cbc\",\"amount\":99896595,\"script\":\"5120deab0c5a3d23de30477b0b5a95a261c96e29afdd9813c665d2bf025ad2b3f919\",\"label\":null,\"spend_status\":\"Unspent\"}}},\"tx_history\":[]},\"pairing_process_commitment\":\"0000000000000000000000000000000000000000000000000000000000000000\",\"paired_member\":{\"sp_addresses\":[\"sprt1qqf50y6deqe7dqg3vj562xf3lmktqe3sct78ha6e9jh54sa3q2m5esq7x2tz0xrpm0ekclyyaszc2sh3ksm5gkumxpwegpa80lv5wgsuefqaufx8q\",\"sprt1qqf2kqh8n7lkupngfk2fxtmvyaq8sy3v2ramyeryweadqmsz7l6tg2qc9n4dl42ff8klz28nznr7mfzh6263xv555stwzextl2v4lvhg3aqq7ru8u\"]}}";
pub const PAIRING_PROCESS: &str = "{\"816fc00efc0e4ead5c6683f51e74433ea8b9a520cda48b23cdae6c42639c540f:0\":{\"states\":[],\"shared_secrets\":{\"sprt1qqf50y6deqe7dqg3vj562xf3lmktqe3sct78ha6e9jh54sa3q2m5esq7x2tz0xrpm0ekclyyaszc2sh3ksm5gkumxpwegpa80lv5wgsuefqaufx8q\":\"a86c30250a8e6a8dc9581b3ab2dacafda6446f6c65f4debe124f5870b6796ea1\"},\"impending_requests\":[{\"prd_type\":\"Update\",\"root_commitment\":\"816fc00efc0e4ead5c6683f51e74433ea8b9a520cda48b23cdae6c42639c540f:4294967295\",\"sender\":\"{\\\"sp_addresses\\\":[\\\"sprt1qqf2kqh8n7lkupngfk2fxtmvyaq8sy3v2ramyeryweadqmsz7l6tg2qc9n4dl42ff8klz28nznr7mfzh6263xv555stwzextl2v4lvhg3aqq7ru8u\\\",\\\"sprt1qqf50y6deqe7dqg3vj562xf3lmktqe3sct78ha6e9jh54sa3q2m5esq7x2tz0xrpm0ekclyyaszc2sh3ksm5gkumxpwegpa80lv5wgsuefqaufx8q\\\"]}\",\"keys\":{\"roles\":\"eb4e967297c40d55d96d61568849df75bf42ddd756a14b3309aa774f9d58cff1\",\"pairing_tx\":\"6484145ebc037a0b0033c103e47e211699473eef6172348e9a40a4d4c4d8c0ac\"},\"validation_tokens\":[],\"payload\":\"{\\\"html\\\":\\\"cd0e3fdb60ec8da76c16ca727e4bb486937f82e081cee8abc1ea6a5dbde8\\\",\\\"style\\\":\\\"24f6169aa2c4e9e46f34ac477347215f0b87f54cc333f24cf4f9b788e09f\\\",\\\"script\\\":\\\"ab6880c844ba8d3a14a47ae5ac586f60ac77aa8945288246d3894526c054\\\",\\\"description\\\":\\\"e30f5aa7999a169defb65f586d15764f80c952e9bfb6e864759cae9eea1184febb31d2d542c5\\\",\\\"roles\\\":\\\"849c2dca2c8bc9e28a7f22bc98a4e9a1ef18d9daea4c956421a6f66161cf6f2b1e0ed438814699b69770e9c6feb2ca62696a6d4800fa9c8973c989d35fdff01a1c72619510bceb025f020ad62e772924b9fa693ce10836ac542b754c8ef18788a34a01ca03fb3ed732db960a6a74b3ad22a2f638214c153a6c2586095f945c08df90cfa3e42686715cac878095228ad38de955a678d8f628eb85e894631d204b8441db7b87b5c67664831ed6dc97eba0334e15cbbe036b9767de703414277a08e40af83259a93e6aaaeff9471fb4e3a8a1f351d0a61450996288df8ecfe3b006c40d7e93f7f1b66267300c9e570dc425ed2d2cc6584b938f01dde2472c00f4a5b6122659ef834ec114abeceac9ed37be44faf99fa92f421b669818f40ae6a5c8d3092a76e17c478caa9ae43eef8e2ab60ad73d430637ad4056e0fc3547ab85ca859b2cda6dadd3f40c1dc297b9874ec5174f6a154ecd4a295d502ea497da534fb56294514713f3837950a30685d67e0dd2823855a0f4a35f86675ce8c4da2b254d6406b432a96dba5cc9503afc00490fb4\\\",\\\"pairing_tx\\\":\\\"95eb6b93f53d0909dc72ad53a1d0d3e54426276e0b3b360d44e6392fa1af01f64aac00a9ef633170186a13c2924d6397f3a8364d8921f2614dbb748090d90815842d48f5165e3f0782e0e648f017848c83a1b497b3a0ef1417dde26523b34e0234758f9719ecc21b43\\\"}\",\"proof\":{\"signature\":\"2f6a504567b53565a48e94b3bb21c2493d208534045dab69e68e813c466cd580058518d1f452cadabb51252b643a5bd1db515d4b157b61adffa28ba7b57b5266\",\"message\":{\"Message\":\"f4eea3b2932fc02aab2b84fbdc071b50b93f544fb4e2f732d6491d5c64f9af5b\"},\"key\":\"c652c4f30c3b7e6d8f909d80b0a85e3686e88b73660bb280f4effb28e4439948\"}}]}}";
pub const RELAY_ADDRESS: &str = "sprt1qqfmqt0ngq99y8t4ke6uhtm2a2vc2zxvhj7hjrqu599kn30d4cs9rwqn6n079mdr4dfqg72yrtvuxf43yswscw86nvvl09mc5ljx65vfh75fkza35";
pub const DEFAULT_NYM: &str = "AliceBob";
pub fn helper_get_alice_address() -> String {
let wallet: SpWallet = serde_json::from_str(ALICE_START_WALLET).unwrap();
wallet.get_client().get_receiving_address()
}
pub fn helper_get_bob_address() -> String {
let wallet: SpWallet = serde_json::from_str(BOB_START_WALLET).unwrap();
wallet.get_client().get_receiving_address()
}
pub fn helper_get_tweak_data(tx: &str, outpoints: HashMap<OutPoint, OwnedOutput>) -> String {
let tx: Transaction = deserialize(&Vec::from_hex(tx).unwrap()).unwrap();
let mut outpoint_data = vec![];
let mut witnesses = vec![];
let mut spks = vec![];
for prevout in tx.input.iter() {
outpoint_data.push((
prevout.previous_output.txid.to_string(),
prevout.previous_output.vout,
));
witnesses.push(prevout.witness.clone());
if let Some(output) = outpoints.get(&prevout.previous_output) {
spks.push(ScriptBuf::from_hex(&output.script).unwrap());
}
}
let mut input_pubkeys = vec![];
for (spk, witness) in spks.iter().zip(witnesses) {
let input_pubkey =
get_pubkey_from_input(&vec![], &witness.to_vec(), spk.as_bytes()).unwrap();
input_pubkeys.push(input_pubkey.unwrap());
}
let ref_pubkeys: Vec<&PublicKey> = input_pubkeys.iter().collect();
let tweak_data = calculate_tweak_data(&ref_pubkeys, &outpoint_data).unwrap();
tweak_data.to_string()
}
pub fn helper_parse_transaction(transaction: &str, tweak_data: &str) -> ApiReturn {
let tx: Transaction = deserialize(&Vec::from_hex(transaction).unwrap()).unwrap();
let new_tx_msg = serde_json::to_string(&NewTxMessage::new(
serialize(&tx).to_lower_hex_string(),
Some(tweak_data.to_owned()),
))
.unwrap();
// debug!("new_tx_msg: {:?}", new_tx_msg);
let result = parse_new_tx(new_tx_msg, 0);
match result {
Ok(m) => m,
Err(e) => panic!("Unexpected error: {}", e.message),
}
}

110
tsconfig.json Normal file
View File

@ -0,0 +1,110 @@
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "ES2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "ESNext", /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"include": ["./src/**/*"]
}

46
webpack.config.js Normal file
View File

@ -0,0 +1,46 @@
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
mode: 'development',
entry: './src/index.ts',
devtool: 'inline-source-map',
experiments: {
asyncWebAssembly: true,
},
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
{
test: /\.wasm$/,
type: 'webassembly/async',
}
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
output: {
filename: 'index.js',
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
}),
new CopyWebpackPlugin({
patterns: [
{ from: 'src/assets', to: './assets' },
{ from: 'src/style', to: './style' }
],
}),
],
devServer: {
static: './dist',
},
};