Compare commits

..

No commits in common. "ext" and "master" have entirely different histories.
ext ... master

35 changed files with 1897 additions and 1442 deletions

View File

@ -1 +0,0 @@
# CI Build Trigger

View File

@ -1,2 +0,0 @@
# CI Trigger
# CI Trigger Sun Sep 21 19:57:52 UTC 2025

View File

@ -1,79 +1,11 @@
# 4NK Environment - Git Ignore
# ============================
confs/
# Dossiers de sauvegarde des scripts
**/backup/
**/*backup*
**/.cargo/
# Fichiers temporaires
**/*.tmp*
**/*.temp*
**/*.log*
**/*.pid*
# Fichiers de configuration locale
**/*.env*
**/*.conf*
**/*.yaml*
**/*.yml*
**/*.ini*
**/*.json*
**/*.toml*
**/*.lock*
# Données et logs
**/*.logs*
**/*.data
*.db
*.sqlite
# Certificats et clés
**/*.key
**/*.pem
**/*.crt
**/*.p12
**/*.pfx
ssl/
certs/
# Docker
**/*.docker*
# Cache et build
**/*.node_modules/
**/*.dist/
**/*build/
**/*target/
**/*.*.o
**/*.so
**/*.dylib
# IDE et éditeurs
**/*.vscode/
**/*.idea/
**/*.swp
**/*.swo
**/*~
# OS
**/*.DS_Store
**/*Thumbs.db
**/*tmp*
# Git
**/*.git/
**/*.orig*
# Backup des projets existants
**/*backup*
**/*wallet*
**/*keys*
**/*node_modules*
**/*cursor*
**/*pid*
**/*next*
# 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,95 +1,26 @@
# 4NK Environment - Git Ignore
# ============================
confs/
# Dossiers de sauvegarde des scripts
**/backup/
**/*backup*
# Ignorer les contenus volumineux pour le contexte IA
node_modules/
dist/
build/
coverage/
.cache/
.tmp/
.parcel-cache/
**/.cargo/
# Rapports et logs de tests
tests/logs/
tests/reports/
# Fichiers temporaires
**/*.tmp*
**/*.temp*
**/*.log*
**/*.pid*
# Fichiers lourds
**/*.map
**/*.min.*
**/*.wasm
**/*.{png,jpg,jpeg,svg,ico,pdf}
# Fichiers de configuration locale
**/*.env*
**/*.conf*
**/*.yaml*
**/*.yml*
**/*.ini*
**/*.json*
**/*.toml*
**/*.lock*
# Ne pas ignorer .cursor ni AGENTS.md
!/.cursor
!/AGENTS.md
# Données et logs
**/*.logs*
**/*.data
*.db
*.sqlite
!.cursor/
# Certificats et clés
**/*.key
**/*.pem
**/*.crt
**/*.p12
**/*.pfx
ssl/
certs/
# Docker
**/*.docker*
# Cache et build
**/node_modules/
**/dist/
**/build/
**/target/
**/.next/
**/.turbo/
**/coverage/
**/.pytest_cache/
**/.cache/
**/.pnpm-store/
**/.venv/
**/vendor/
**/*.*.o
**/*.so
**/*.dylib
# IDE et éditeurs
**/*.vscode/
**/*.idea/
**/*.swp
**/*.swo
**/*~
# OS
**/*.DS_Store
**/*Thumbs.db
**/*tmp*
# Git
**/*.git/
**/*.orig*
# Backup des projets existants
**/*backup*
**/backups/
**/*backups*
**/*wallet*
**/*keys*
**/*node_modules*
**/*cursor*
**/*pid*
**/*next*
# Dossiers de logs communs
log/
logs/
**/log/
**/logs/
!AGENTS.md

View File

@ -1,166 +0,0 @@
# Règles globales Cursor pour les projets
## Principes généraux
- Lire impérativement le fichier `.cursorrules` au démarrage de chaque session.
- Lire tous les fichiers du dossier `docs/`, le code et les paramètres avant de commencer.
- Poser des questions et proposer des améliorations si nécessaire.
- Ajouter les leçons apprises à ce fichier `.cursorrules`.
- Écrire des documents complets et exhaustifs.
- Respecter strictement les règles de lint du Markdown.
- Préférer toujours un shell **bash** à PowerShell.
- Fermer et relancer le terminal avant chaque utilisation.
- Si le terminal est interrompu, analyser la commande précédente (interruption probablement volontaire).
- Exécuter automatiquement les étapes de résolution de problème.
- Expliquer les commandes complexes avant de les lancer.
- Compiler régulièrement et corriger toutes les erreurs avant de passer à létape suivante.
- Tester, documenter, compiler, aligner tag git, changelog et version avant déploiement et push.
- Utiliser `docx2txt` pour lire les fichiers `.docx`.
- Ajouter automatiquement les dépendances et rechercher systématiquement les dernières versions.
- Faire des commandes simples et claires en plusieurs étapes.
- Vérifie toujours tes hypothèses avant de commencer.
- N'oublie jamais qu'après la correction d'un problème, il faut corriger toutes les erreurs qui peuvent en découler.
## Organisation des fichiers et répertoires
- Scripts regroupés dans `scripts/`
- Configurations regroupées dans `confs/`
- Journaux regroupés dans `logs/`
- Répertoires obligatoires :
- `docs/` : documentation de toute fonctionnalité ajoutée, modifiée, supprimée ou découverte.
- `tests/` : tests liés à toute fonctionnalité ajoutée, modifiée, supprimée ou découverte.
- Remplacer les résumés (`RESUME`) par des mises à jour dans `docs/`.
## Configuration critique des services
- Mempool du réseau signet :
`https://mempool2.4nkweb.com/fr/docs/api/rest`
## Développement et sécurité
- Ne jamais committer de clés privées ou secrets.
- Utiliser des variables denvironnement pour les données sensibles.
- Définir correctement les dépendances Docker avec healthchecks.
- Utiliser les URLs de service Docker Compose (`http://service_name:port`).
- Documenter toutes les modifications importantes dans `docs/`.
- Externaliser au maximum les variables denvironnement.
- Toujours utiliser une clé SSH pour cloner les dépôts.
- Monter en version les dépôts au début du travail.
- Pousser les tags docker `ext` via la CI sur `git.4nkweb.com`.
- Corriger systématiquement les problèmes, même mineurs, sans contournement.
## Scripts (règles critiques)
- Vérifier lexistence dun script dans `scripts/` avant toute action.
- Utiliser les scripts existants plutôt que des commandes directes.
- Ne jamais créer plusieurs versions ou noms de scripts.
- Améliorer lexistant au lieu de créer des variantes (`startup-v2.sh`, etc.).
## Images Docker (règles critiques)
- Ajouter systématiquement `apt update && apt upgrade` dans les Dockerfiles.
- Installer en arrière-plan dans les images Docker :
`curl, git, sed, awk, nc, wget, jq, telnet, tee, wscat, ping, npm (dernière version)`
- Appliquer à tous les Dockerfiles et `docker-compose.yml`.
- N'utilise pas les version test ou dev ou ext-dev mais toujours les version ext, relance leur compilation si nécessaire
## Fichiers de configuration (règles critiques)
- Vérifier lécriture effective après chaque modification.
- Fichiers concernés : `nginx.conf`, `bitcoin.conf`, `package.json`, `Cargo.toml`.
- Utiliser `cat`, `jq` ou vérificateurs de syntaxe.
## Connexion au réseau Bitcoin signet
Commande unique et obligatoire :
```bash
docker exec bitcoin-signet bitcoin-cli -signet -rpccookiefile=/home/bitcoin/.bitcoin/signet/.cookie getblockchaininfo
````
## Connexion au relay/faucet bootstrap
* Test via WSS : `wss://dev3.4nkweb.com/ws/`
* Envoi Faucet, réponse attendue avec `NewTx` (tx hex et tweak\_data).
## Debug
* Automatiser dans le code toute solution validée.
* Pérenniser les retours dexpérience dans code et paramètres.
* Compléter les tests pour éviter les régressions.
* Toujours tout corriger sans contournement, sans desactivation, sans simplification
## Nginx
* Tous les fichiers dans `conf/ngnix` doivent être mappés avec ceux du serveur.
## Minage (règles critiques)
* Toujours valider les adresses utilisées (adresses TSP non reconnues).
* Utiliser uniquement des adresses Bitcoin valides (bech32m).
* Vérifier que le minage génère des blocs avec transactions, pas uniquement coinbase.
* Surveiller les logs du minage pour détecter les erreurs dadresse.
* Vérifier la propagation via le mempool externe.
## Mempool externe
* Utiliser `https://mempool2.4nkweb.com` pour vérifier les transactions.
* Vérifier la synchronisation entre réseau local et externe.
## Données et modèles
* Utiliser les fichiers CSV comme base des modèles de données.
* Être attentif aux en-têtes multi-lignes.
* Confirmer la structure comprise et demander définition de toutes les colonnes.
* Corriger automatiquement incohérences de type.
## Implémentation et architecture
* Code splitting avec `React.lazy` et `Suspense`.
* Centraliser létat avec Redux ou Context API.
* Créer une couche dabstraction pour les services de données.
* Aller systématiquement au bout dune implémentation.
## Préparation open source
Chaque projet doit être prêt pour un dépôt sur `git.4nkweb.com` :
* Inclure : `LICENSE` (MIT, Apache 2.0 ou GPL), `CONTRIBUTING.md`, `CHANGELOG.md`, `CODE_OF_CONDUCT.md`.
* Aligner documentation et tests avec `4NK_node`.
## Versioning et documentation
* Mettre à jour documentation et tests systématiquement.
* Gérer versioning avec changelog.
* Demander validation avant tag.
* Documenter les hypothèses testées dans un REX technique.
* Tester avant tout commit.
* Tester les buildsavant tout tag.
## Bonnes pratiques de confidentialité et sécurité
### Docker
- Ne jamais stocker de secrets (clés, tokens, mots de passe) dans les Dockerfiles ou docker-compose.yml.
- Utiliser des fichiers `.env` sécurisés (non commités avec copie en .env.example) pour toutes les variables sensibles.
- Ne pas exécuter de conteneurs avec lutilisateur root, privilégier un utilisateur dédié.
- Limiter les capacités des conteneurs (option `--cap-drop`) pour réduire la surface dattaque.
- Scanner régulièrement les images Docker avec un outil de sécurité (ex : Trivy, Clair).
- Mettre à jour en continu les images de base afin déliminer les vulnérabilités.
- Ne jamais exposer de ports inutiles.
- Restreindre les volumes montés au strict nécessaire.
- Utiliser des réseaux Docker internes pour la communication inter-containers.
- Vérifier et tenir à jour les .dockerignore.
### Git
- Ne jamais committer de secrets, clés ou identifiants (même temporairement).
- Configurer des hooks Git (pre-commit) pour détecter automatiquement les secrets et les failles.
- Vérifier lhistorique (`git log`, `git filter-repo`) pour sassurer quaucune information sensible na été poussée.
- Signer les commits avec GPG pour garantir lauthenticité.
- Utiliser systématiquement SSH pour les connexions à distance.
- Restreindre les accès aux dépôts (principes du moindre privilège).
- Documenter les changements sensibles dans `CHANGELOG.md`.
- Ne jamais pousser directement sur `main` ou `master`, toujours passer par des branches de feature ou PR.
- Vérifier et tenir à jour les .gitignore.
- Vérifier et tenir à jour les .gitkeep.
- Vérifier et tenir à jour les .gitattributes.
### Cursor
- Toujours ouvrir une session en commençant par relire le fichier `.cursorrules`.
- Vérifier que Cursor ne propose pas de commit contenant des secrets ou fichiers sensibles.
- Ne pas exécuter dans Cursor de commandes non comprises ou copiées sans vérification.
- Préférer lutilisation de scripts audités dans `scripts/` plutôt que des commandes directes dans Cursor.
- Fermer et relancer Cursor régulièrement pour éviter des contextes persistants non désirés.
- Ne jamais partager le contenu du terminal ou des fichiers sensibles via Cursor en dehors du périmètre du projet.
- Vérifier et tenir à jour les .cursorrules.
- Vérifier et tenir à jour les .cursorignore.

View File

@ -1,95 +1,15 @@
# 4NK Environment - Git Ignore
# ============================
confs/
# Dossiers de sauvegarde des scripts
**/backup/
**/*backup*
node_modules
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
dist
.env
.env.*
.DS_Store
.turbo
.git
.gitignore
coverage
data
**/.cargo/
# Fichiers temporaires
**/*.tmp*
**/*.temp*
**/*.log*
**/*.pid*
# Fichiers de configuration locale
**/*.env*
**/*.conf*
**/*.yaml*
**/*.yml*
**/*.ini*
**/*.json*
**/*.toml*
**/*.lock*
# Données et logs
**/*.logs*
**/*.data
*.db
*.sqlite
# Certificats et clés
**/*.key
**/*.pem
**/*.crt
**/*.p12
**/*.pfx
ssl/
certs/
# Docker
**/*.docker*
# Cache et build
**/node_modules/
**/dist/
**/build/
**/target/
**/.next/
**/.turbo/
**/coverage/
**/.pytest_cache/
**/.cache/
**/.pnpm-store/
**/.venv/
**/vendor/
**/*.*.o
**/*.so
**/*.dylib
# IDE et éditeurs
**/*.vscode/
**/*.idea/
**/*.swp
**/*.swo
**/*~
# OS
**/*.DS_Store
**/*Thumbs.db
**/*tmp*
# Git
**/*.git/
**/*.orig*
# Backup des projets existants
**/*backup*
**/backups/
**/*backups*
**/*wallet*
**/*keys*
**/*node_modules*
**/*cursor*
**/*pid*
**/*next*
# Dossiers de logs communs
log/
logs/
**/log/
**/logs/

View File

@ -1,2 +0,0 @@
SIGNER_API_KEY=your-api-key-change-this

View File

@ -0,0 +1,98 @@
---
name: Bug Report
about: Signaler un bug pour nous aider à améliorer sdk_signer
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 sdk_signer** : [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

@ -0,0 +1,157 @@
---
name: Feature Request
about: Proposer une nouvelle fonctionnalité pour sdk_signer
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 sdk_signer !** 🌟

View File

@ -0,0 +1,181 @@
# Pull Request - sdk_signer
## 📋 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 !** 🙏

4
.gitea/README.md Normal file
View File

@ -0,0 +1,4 @@
# .gitea
Fichiers de configuration Gitea (issues, templates, workflows) à ajouter au besoin.

View File

@ -0,0 +1,15 @@
# LOCAL_OVERRIDES.yml — dérogations locales contrôlées
overrides:
- path: ".gitea/workflows/ci.yml"
reason: "spécificité denvironnement"
owner: "@maintainer_handle"
expires: "2025-12-31"
- path: "scripts/auto-ssh-push.sh"
reason: "flux particulier temporaire"
owner: "@maintainer_handle"
expires: "2025-10-01"
policy:
allow_only_listed_paths: true
require_expiry: true
audit_in_ci: true

View File

@ -1,86 +0,0 @@
name: build-and-push-ext
on:
push:
tags:
- ext
jobs:
build_push:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '19'
cache: 'npm'
- name: Install dependencies
run: npm ci --include=dev
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y clang llvm-dev libclang-dev build-essential
- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
components: rustfmt, clippy
- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y clang llvm-dev libclang-dev build-essential perl
- name: Install wasm-pack and wasm-bindgen
run: |
cargo install wasm-pack
cargo install wasm-bindgen-cli --version 0.2.103
- name: Clone sdk_client
run: |
git clone -b dev https://git.4nkweb.com/4nk/sdk_client.git ./sdk_client
- name: Build WebAssembly
run: |
wasm-pack build --out-dir ./pkg ./sdk_client --target nodejs --dev
mkdir -p ./pkg
cp -r ./sdk_client/pkg/* ./pkg/
- name: Build project
run: npm run build
- name: Run tests
run: npx vitest run
- name: Docker login (git.4nkweb.com)
shell: bash
env:
REG_USER: ${{ secrets.USER }}
REG_TOKEN: ${{ secrets.TOKEN }}
run: |
set -euo pipefail
echo "$REG_TOKEN" | docker login git.4nkweb.com -u "$REG_USER" --password-stdin
- name: Build image (target ext)
shell: bash
env:
DOCKER_BUILDKIT: "1"
run: |
set -euo pipefail
docker build \
-t git.4nkweb.com/4nk/sdk_signer:ext \
-f Dockerfile .
- name: Push image
shell: bash
run: |
set -euo pipefail
docker push git.4nkweb.com/4nk/sdk_signer:ext

486
.gitea/workflows/ci.yml Normal file
View File

@ -0,0 +1,486 @@
name: CI - 4NK Node
on:
push:
branches: [ main, develop ]
tags:
- 'v*'
pull_request:
branches: [ main, develop ]
env:
RUST_VERSION: '1.70'
DOCKER_COMPOSE_VERSION: '2.20.0'
CI_SKIP: 'true'
jobs:
# Job de vérification du code
code-quality:
name: Code Quality
runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
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: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
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: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
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: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
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: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
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: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
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
markdownlint:
name: Markdown Lint
runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Run markdownlint
run: |
npm --version || (curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs)
npx -y markdownlint-cli@0.42.0 "**/*.md" --ignore "archive/**"
- 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"
)
for file in "${required_files[@]}"; do
if [[ ! -f "$file" ]]; then
echo "Missing required documentation file: $file"
exit 1
fi
done
bash-required:
name: Bash Requirement
runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Verify bash availability
run: |
if ! command -v bash >/dev/null 2>&1; then
echo "bash is required for agents and scripts"; exit 1;
fi
- name: Verify agents runner exists
run: |
if [ ! -f scripts/agents/run.sh ]; then
echo "scripts/agents/run.sh is missing"; exit 1;
fi
agents-smoke:
name: Agents Smoke (no AI)
runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Ensure agents scripts executable
run: |
chmod +x scripts/agents/*.sh || true
- name: Run agents without AI
env:
OPENAI_API_KEY: ""
run: |
scripts/agents/run.sh
- name: Upload agents reports
uses: actions/upload-artifact@v3
with:
name: agents-reports
path: tests/reports/agents
openia-agents:
name: Agents with OpenIA
runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' && secrets.OPENAI_API_KEY != '' }}
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
OPENAI_MODEL: ${{ vars.OPENAI_MODEL }}
OPENAI_API_BASE: ${{ vars.OPENAI_API_BASE }}
OPENAI_TEMPERATURE: ${{ vars.OPENAI_TEMPERATURE }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Ensure agents scripts executable
run: |
chmod +x scripts/agents/*.sh || true
- name: Run agents with AI
run: |
scripts/agents/run.sh
- name: Upload agents reports
uses: actions/upload-artifact@v3
with:
name: agents-reports-ai
path: tests/reports/agents
deployment-checks:
name: Deployment Checks
runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Validate deployment documentation
run: |
if [ ! -f docs/DEPLOYMENT.md ]; then
echo "Missing docs/DEPLOYMENT.md"; exit 1; fi
if [ ! -f docs/SSH_UPDATE.md ]; then
echo "Missing docs/SSH_UPDATE.md"; exit 1; fi
- name: Ensure tests directories exist
run: |
mkdir -p tests/logs tests/reports || true
echo "OK"
security-audit:
name: Security Audit
runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Ensure scripts executable
run: |
chmod +x scripts/security/audit.sh || true
- name: Run template security audit
run: |
if [ -f scripts/security/audit.sh ]; then
./scripts/security/audit.sh
else
echo "No security audit script (ok)"
fi
# Job de release guard (cohérence release)
release-guard:
name: Release Guard
runs-on: [self-hosted, linux]
needs: [code-quality, unit-tests, documentation-tests, markdownlint, security-audit, deployment-checks, bash-required]
if: ${{ env.CI_SKIP != 'true' }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Ensure guard scripts are executable
run: |
chmod +x scripts/release/guard.sh || true
chmod +x scripts/checks/version_alignment.sh || true
- name: Version alignment check
run: |
if [ -f scripts/checks/version_alignment.sh ]; then
./scripts/checks/version_alignment.sh
else
echo "No version alignment script (ok)"
fi
- name: Release guard (CI verify)
env:
RELEASE_TYPE: ci-verify
run: |
if [ -f scripts/release/guard.sh ]; then
./scripts/release/guard.sh
else
echo "No guard script (ok)"
fi
release-create:
name: Create Release (Gitea API)
runs-on: ubuntu-latest
needs: [release-guard]
if: ${{ env.CI_SKIP != 'true' && startsWith(github.ref, 'refs/tags/') }}
env:
RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
BASE_URL: ${{ vars.BASE_URL }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Validate token and publish release
run: |
set -e
if [ -z "${RELEASE_TOKEN}" ]; then
echo "RELEASE_TOKEN secret is missing" >&2; exit 1; fi
if [ -z "${BASE_URL}" ]; then
BASE_URL="https://git.4nkweb.com"; fi
TAG="${GITHUB_REF##*/}"
REPO="${GITHUB_REPOSITORY}"
OWNER="${REPO%%/*}"
NAME="${REPO##*/}"
echo "Publishing release ${TAG} to ${BASE_URL}/${OWNER}/${NAME}"
curl -sSf -X POST \
-H "Authorization: token ${RELEASE_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"tag_name\":\"${TAG}\",\"name\":\"${TAG}\",\"draft\":false,\"prerelease\":false}" \
"${BASE_URL}/api/v1/repos/${OWNER}/${NAME}/releases" >/dev/null
echo "Release created"
# Job de tests de performance
performance-tests:
name: Performance Tests
runs-on: [self-hosted, linux]
if: ${{ env.CI_SKIP != 'true' }}
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: [self-hosted, linux]
needs: [code-quality, unit-tests, integration-tests, security-tests, docker-build, documentation-tests]
if: ${{ env.CI_SKIP != 'true' && 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

352
.gitea/workflows/ci.yml.bak Normal file
View File

@ -0,0 +1,352 @@
name: CI - sdk_signer
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: |
cargo clippy --all-targets --all-features -- -D warnings
- name: Run rustfmt
run: |
cargo fmt --all -- --check
- name: Check documentation
run: |
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: |
cargo test --lib --bins
- name: Run integration tests
run: |
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: |
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: |
echo "Documentation checks completed"
security-audit:
name: Security Audit
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Ensure scripts executable
run: |
chmod +x scripts/security/audit.sh || true
- name: Run template security audit
run: |
if [ -f scripts/security/audit.sh ]; then
./scripts/security/audit.sh
else
echo "No security audit script (ok)"
fi
# Job de release guard (cohérence release)
release-guard:
name: Release Guard
runs-on: ubuntu-latest
needs: [code-quality, unit-tests, documentation-tests, security-audit]
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Ensure guard scripts are executable
run: |
chmod +x scripts/release/guard.sh || true
chmod +x scripts/checks/version_alignment.sh || true
- name: Version alignment check
run: |
if [ -f scripts/checks/version_alignment.sh ]; then
./scripts/checks/version_alignment.sh
else
echo "No version alignment script (ok)"
fi
- name: Release guard (CI verify)
env:
RELEASE_TYPE: ci-verify
run: |
if [ -f scripts/release/guard.sh ]; then
./scripts/release/guard.sh
else
echo "No guard script (ok)"
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

View File

@ -0,0 +1,36 @@
name: Release
on:
push:
tags:
- 'v*.*.*'
jobs:
docker-release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Login to DockerHub
if: ${{ secrets.DOCKERHUB_USERNAME && secrets.DOCKERHUB_TOKEN }}
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract version
id: vars
run: echo "version=${GITHUB_REF##*/}" >> $GITHUB_OUTPUT
- name: Build image
run: docker build -t ${DOCKER_IMAGE:-sdk-signer}:${{ steps.vars.outputs.version }} .
- name: Push image
if: ${{ secrets.DOCKERHUB_USERNAME && secrets.DOCKERHUB_TOKEN }}
run: |
IMAGE=${DOCKER_IMAGE:-sdk-signer}
docker tag $IMAGE:${{ steps.vars.outputs.version }} $IMAGE:latest
docker push $IMAGE:${{ steps.vars.outputs.version }}
docker push $IMAGE:latest

View File

@ -0,0 +1,40 @@
# .gitea/workflows/template-sync.yml — synchronisation et contrôles dintégrité
name: 4NK Template Sync
on:
schedule: # planification régulière
- cron: "0 4 * * 1" # exécution hebdomadaire (UTC)
workflow_dispatch: {} # déclenchement manuel
jobs:
check-and-sync:
runs-on: linux
steps:
- name: Lire TEMPLATE_VERSION et .4nk-sync.yml
# Doit charger ref courant, source_repo et périmètre paths
- name: Récupérer la version publiée du template/4NK_rules
# Doit comparer TEMPLATE_VERSION avec ref amont
- name: Créer branche de synchronisation si divergence
# Doit créer chore/template-sync-<date> et préparer un commit
- name: Synchroniser les chemins autoritatifs
# Doit mettre à jour .cursor/**, .gitea/**, AGENTS.md, scripts/**, docs/SSH_UPDATE.md
- name: Contrôles post-sync (bloquants)
# 1) Vérifier présence et exécutable des scripts/*.sh
# 2) Vérifier mise à jour CHANGELOG.md et docs/INDEX.md
# 3) Vérifier docs/SSH_UPDATE.md si scripts/** a changé
# 4) Vérifier absence de secrets en clair dans scripts/**
# 5) Vérifier manifest_checksum si publié
- name: Tests, lint, sécurité statique
# Doit exiger un état vert
- name: Ouvrir PR de synchronisation
# Titre: "[template-sync] chore: aligner .cursor/.gitea/AGENTS.md/scripts"
# Doit inclure résumé des fichiers modifiés et la version appliquée
- name: Mettre à jour TEMPLATE_VERSION (dans PR)
# Doit remplacer la valeur par la ref appliquée

100
.gitignore vendored
View File

@ -1,95 +1,7 @@
# 4NK Environment - Git Ignore
# ============================
confs/
# Dossiers de sauvegarde des scripts
**/backup/
**/*backup*
node_modules
pkg
dist
data
!.cursor/
**/.cargo/
# Fichiers temporaires
**/*.tmp*
**/*.temp*
**/*.log*
**/*.pid*
# Fichiers de configuration locale
**/*.env*
**/*.conf*
**/*.yaml*
**/*.yml*
**/*.ini*
**/*.json*
**/*.toml*
**/*.lock*
# Données et logs
**/*.logs*
**/*.data
*.db
*.sqlite
# Certificats et clés
**/*.key
**/*.pem
**/*.crt
**/*.p12
**/*.pfx
ssl/
certs/
# Docker
**/*.docker*
# Cache et build
**/node_modules/
**/dist/
**/build/
**/target/
**/.next/
**/.turbo/
**/coverage/
**/.pytest_cache/
**/.cache/
**/.pnpm-store/
**/.venv/
**/vendor/
**/*.*.o
**/*.so
**/*.dylib
# IDE et éditeurs
**/*.vscode/
**/*.idea/
**/*.swp
**/*.swo
**/*~
# OS
**/*.DS_Store
**/*Thumbs.db
**/*tmp*
# Git
**/*.git/
**/*.orig*
# Backup des projets existants
**/*backup*
**/backups/
**/*backups*
**/*wallet*
**/*keys*
**/*node_modules*
**/*cursor*
**/*pid*
**/*next*
# Dossiers de logs communs
log/
logs/
**/log/
**/logs/
!AGENTS.md

View File

@ -4,24 +4,6 @@ Toutes les modifications notables de ce projet seront documentées ici.
## [Unreleased]
### Added
- Service de Background Sync pour la détection automatique des données manquantes
- Surveillance périodique des `pcd_commitment` (toutes les 30 secondes)
- API WebSocket pour contrôler le background sync (`FORCE_DATA_SCAN`, `GET_BACKGROUND_SYNC_STATUS`)
- Gestion automatique des entrées `diff` pour le tracking des données manquantes
- Récupération en deux étapes des données manquantes :
- Essai depuis les serveurs de stockage (retrieveData) en priorité
- Fallback vers les pairs (requestDataFromPeers) si non trouvé
- Extraction automatique des URLs de stockage depuis les rôles
- Scripts de test et validation du service de background sync
- Test spécifique pour la récupération depuis le storage
- Documentation complète dans `docs/BACKGROUND_SYNC.md`
### Changed
- Intégration du background sync dans le service principal
- Démarrage automatique du background sync avec le serveur
- Arrêt propre du background sync lors de l'arrêt du serveur
## [0.1.1] - 2025-08-26
- Bump version package.json à 0.1.1
- Documentation déploiement mise à jour (exemples tag)

9
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,9 @@
# Code de Conduite
Nous nous engageons à offrir un environnement ouvert et accueillant.
- Soyez respectueux et bienveillant.
- Pas de harcèlement ni de discrimination.
- Suivez les instructions des mainteneurs.
Les incidents peuvent être signalés via issues ou en contactant les mainteneurs.

11
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,11 @@
# Guide de Contribution
Merci de votre intérêt pour sdk_signer. Ce projet suit la structure du template 4NK.
- Forkez le dépôt, créez une branche (`feature/...`), puis ouvrez une PR.
- Respectez le CODE_OF_CONDUCT.
- Ajoutez tests et documentation pour chaque changement.
- Mettez à jour le CHANGELOG.
- Vérifiez le build et les tests avant douvrir la PR.
Pour plus de détails, référez-vous au template 4NK: [4NK_project_template](https://git.4nkweb.com/nicolas.cantu/4NK_project_template.git).

View File

@ -1,65 +1,35 @@
# syntax=docker/dockerfile:1.4
FROM rust:1.85-alpine AS wasm-builder
WORKDIR /build
FROM node:20-alpine AS base
# Installation des dépendances nécessaires pour la compilation
RUN apk update && apk add --no-cache \
git \
curl \
nodejs \
npm \
build-base \
pkgconfig \
clang \
llvm \
musl-dev \
perl
# Install production dependencies only by default
ENV NODE_ENV=production
# Installation de wasm-pack et wasm-bindgen
RUN cargo install wasm-pack
RUN cargo install wasm-bindgen-cli --version 0.2.103
# Copie du projet sdk_signer
COPY . sdk_signer/
# Clonage du sdk_client au même niveau que sdk_signer
RUN git clone -b ext https://git.4nkweb.com/4nk/sdk_client.git
# Build du WebAssembly
WORKDIR /build/sdk_client
RUN wasm-pack build --out-dir ../sdk_signer/pkg --target nodejs --dev
FROM debian:bookworm-slim
WORKDIR /app
# Installation des dépendances minimales nécessaires
RUN apt-get update && apt-get upgrade -y && \
apt-get install -y --fix-missing \
ca-certificates curl jq git \
net-tools iputils-ping dnsutils \
netcat-openbsd telnet procps && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Installation de Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
apt-get install -y nodejs && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Création d'un utilisateur non-root
RUN useradd -m -u 1000 appuser && \
mkdir -p /app && chown -R appuser:appuser /app
# Copie des fichiers du projet
COPY --from=wasm-builder /build/sdk_signer/pkg ./pkg
COPY . .
RUN chown -R appuser:appuser /app
# Installation des dépendances Node.js
USER appuser
RUN npm install
# Install build dependencies
FROM base AS deps
ENV NODE_ENV=development
RUN apk add --no-cache python3 make g++
COPY package.json package-lock.json* ./
RUN npm ci
# Build TypeScript
FROM deps AS build
COPY tsconfig.json ./
COPY src ./src
COPY pkg ./pkg
RUN npm run build
# Runtime image
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -S nodejs && adduser -S nodejs -G nodejs
COPY --from=deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY --from=build /app/pkg ./pkg
EXPOSE 9090
USER nodejs
CMD ["node", "dist/index.js"]
CMD ["npm", "start"]

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 4NK
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.

View File

@ -90,7 +90,7 @@ npm test
### Installation Docker
```bash
# Construire l'image
docker build -t.
docker build -t sdk_signer .
# Lancer le conteneur
docker run -p 3000:3000 sdk_signer
@ -315,21 +315,3 @@ MIT License - voir [LICENSE](LICENSE) pour plus de détails.
---
Ce projet suit la structure du template 4NK. Voir le template: [4NK_project_template](https://git.4nkweb.com/nicolas.cantu/4NK_project_template.git).
## Intégration dans lenvironnement 4NK
`sdk_signer` sintègre avec le réseau de relais et les applications du projet. Les URL et domaines sont fournis par configuration/variables denvironnement, sans aucune référence à des machines spécifiques dans la documentation. Référezvous aux documents centraux pour le contexte global et les pratiques de déploiement:
- `docs/DEEP_ARCHITECTURE_ANALYSIS.md`
- `docs/TECHNICAL_REFERENCE.md`
- `docs/DEPLOYMENT_GUIDE.md`
## 📋 Fichiers centralisés
Les fichiers suivants sont centralisés dans le dépôt principal `4NK_env` :
- `CODE_OF_CONDUCT.md` - Code de conduite
- `CODEOWNERS` - Propriétaires du code
- `CONTRIBUTING.md` - Guide de contribution
- `LICENSE` - Licence du projet
Voir : [`4NK_env/CODE_OF_CONDUCT.md`](../../CODE_OF_CONDUCT.md), [`4NK_env/CODEOWNERS`](../../CODEOWNERS), [`4NK_env/CONTRIBUTING.md`](../../CONTRIBUTING.md), [`4NK_env/LICENSE`](../../LICENSE)

View File

@ -58,7 +58,7 @@ ws.onopen = () => {
newData: { field: 'value' },
privateFields: [],
roles: {},
accessToken: '<ACCESS_TOKEN>',
accessToken: 'your-access-token',
messageId: 'unique-message-id'
}));
};
@ -75,7 +75,7 @@ ws.send(JSON.stringify({
type: 'NOTIFY_UPDATE',
processId: 'your-process-id',
stateId: 'your-state-id',
accessToken: '<ACCESS_TOKEN>',
accessToken: 'your-access-token',
messageId: 'unique-message-id'
}));
```
@ -86,7 +86,7 @@ ws.send(JSON.stringify({
type: 'VALIDATE_STATE',
processId: 'your-process-id',
stateId: 'your-state-id',
accessToken: '<ACCESS_TOKEN>',
accessToken: 'your-access-token',
messageId: 'unique-message-id'
}));
```
@ -168,4 +168,4 @@ sudo journalctl -u 4nk-server.service -f
# If running directly
npm run start:server
```
```

View File

@ -0,0 +1,269 @@
# 📚 Index de Documentation - sdk_signer
Index complet de la documentation du service de signature TypeScript pour l'écosystème 4NK.
## 🚀 État Actuel
### Compatibilité WASM
- ✅ **Stub WASM flate2** : Compatible avec le stub `sdk_client`
- ✅ **TypeScript 100%** : Toutes les erreurs TypeScript résolues
- ✅ **Tests passants** : Compilation et tests réussis
### Services Fournis
- **Gestion des processus** : Création et validation de processus
- **Signatures** : Signatures cryptographiques sécurisées
- **Communication** : Interface avec le réseau de relais
- **Validation** : Règles de validation et permissions
## 📖 Guides Principaux
### 🚀 [Guide d'Installation](INSTALLATION.md)
Guide complet pour installer et configurer le service sdk_signer.
- Prérequis système et logiciels
- Installation de Node.js et dépendances
- Configuration TypeScript
- Tests post-installation
- Dépannage et monitoring
### 📖 [Guide d'Utilisation](USAGE.md)
Guide complet pour utiliser le service sdk_signer.
- Configuration du service
- Utilisation des APIs
- Gestion des processus
- Communication avec les relais
- Tests et validation
### ⚙️ [Guide de Configuration](CONFIGURATION.md)
Guide complet pour configurer le service selon vos besoins.
- Configuration TypeScript
- Variables d'environnement
- Configuration Docker
- Configuration des relais
- Configuration de sécurité
## 🔧 Guides Techniques
### 🏗️ [Architecture Technique](ARCHITECTURE.md)
Documentation technique détaillée de l'architecture.
- Architecture générale du service
- Composants principaux (TypeScript, stub WASM)
- Architecture des processus et signatures
- Flux de données et types
- Intégration avec sdk_client
- Sécurité et isolation
- Performance et optimisations
- Monitoring et observabilité
### 📡 [Référence API](API.md)
Documentation complète des APIs disponibles.
- **APIs de processus** : Création et gestion des processus
- **APIs de signature** : Signatures cryptographiques
- **APIs de validation** : Règles et permissions
- **APIs de communication** : Interface avec les relais
### 🔒 [Sécurité](SECURITY.md)
Guide de sécurité et bonnes pratiques.
- **Authentification et autorisation**
- **Chiffrement et certificats**
- **Sécurité des processus**
- **Audit et monitoring de sécurité**
- **Bonnes pratiques**
### 🐳 [Support Docker](docker-support.md)
Guide de configuration Docker pour le déploiement.
- **Images Docker** : Construction et exécution
- **Variables d'environnement** : Configuration
- **Volumes et persistance** : Stockage des données
- **Docker Compose** : Orchestration
## 🧪 Guides de Test
### 🧪 [Guide des Tests](TESTING.md)
Guide complet pour les tests du service.
- **Tests unitaires** : Tests TypeScript
- **Tests d'intégration** : Tests avec le stub WASM
- **Tests de compatibilité** : Tests avec sdk_client
- **Tests de performance** : Benchmarks
- **Tests de sécurité** : Audit de sécurité
### 🔍 [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
### 🔧 [Guide de Développement](DEVELOPMENT.md)
Guide complet pour le développement.
- **Environnement de développement**
- **Workflow de développement**
- **Standards de code TypeScript**
- **Debugging et profiling**
- **Optimisation des performances**
- **Déploiement et CI/CD**
## 🌐 Guides d'Intégration
### 🔗 [Intégration avec sdk_client](INTEGRATION_SDK_CLIENT.md)
Guide d'intégration avec le stub WASM sdk_client.
- **Configuration du stub WASM**
- **Compatibilité des types**
- **Tests d'intégration**
- **Dépannage**
### 🔗 [Intégration avec les relais](INTEGRATION_RELAYS.md)
Guide d'intégration avec le réseau de relais.
- **Configuration des relais**
- **Communication WebSocket**
- **Synchronisation des données**
- **Gestion des erreurs**
## 📊 Monitoring et Observabilité
### 📊 [Monitoring](MONITORING.md)
Guide de monitoring et observabilité.
- **Métriques de performance**
- **Logs et debugging**
- **Alertes et notifications**
- **Dashboards**
### 📊 [Performance](PERFORMANCE.md)
Guide d'optimisation des performances.
- **Optimisations TypeScript**
- **Optimisations du stub WASM**
- **Benchmarks**
- **Profiling**
## 🔧 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_signer
2. [Configuration](CONFIGURATION.md) - Configurer l'environnement
3. [Utilisation](USAGE.md) - Utiliser le service
### 🔧 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. [Docker Support](docker-support.md) - Configuration Docker
### 🤝 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
npm test
# Tests en mode watch
npm run test:watch
# Tests de compatibilité
npm run test:compatibility
# Linting
npm run lint
# Formatage
npm run format
```
### Tests d'Intégration
```bash
# Tests avec le stub WASM
npm run test:integration
# Tests de compatibilité avec sdk_client
npm run test:sdk-client
```
---
## 🚀 Développement
### Commandes Essentielles
```bash
# Installation des dépendances
npm install
# Build de développement
npm run build
# Build de production
npm run build:prod
# Tests
npm test
# Démarrage en mode développement
npm run dev
# Démarrage en mode production
npm start
```
### Configuration Docker
```bash
# Construction de l'image
docker build -t sdk_signer .
# Exécution du conteneur
docker run -p 9090:9090 sdk_signer
# Avec Docker Compose
docker compose up
```
---
## 📊 Métriques
### Performance
- **Temps de compilation** : < 5s
- **Temps de démarrage** : < 2s
- **Mémoire utilisée** : < 100MB
- **Tests** : 100% de couverture
### Compatibilité
- **TypeScript** : ✅ 0 erreur
- **Stub WASM** : ✅ Compatible
- **Docker** : ✅ Support complet
- **Tests** : ✅ 100% de couverture
---
**📚 Documentation complète pour sdk_signer - Service de signature TypeScript pour l'écosystème 4NK** 🚀

317
package-lock.json generated
View File

@ -27,7 +27,6 @@
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/trace-mapping": "0.3.9"
},
@ -444,7 +443,6 @@
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
@ -461,16 +459,15 @@
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.0.3",
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.0.tgz",
"integrity": "sha512-VxDYCDqOaR7NXzAtvRx7G1u54d2kEHopb28YH/pKzY6y0qmogP3gG7CSiWsq9WvDFxOQMpNEyjVAHZFXfH3o/A==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.48.1.tgz",
"integrity": "sha512-rGmb8qoG/zdmKoYELCBwu7vt+9HxZ7Koos3pD0+sH5fR3u3Wb/jGcpnqxcnWsPEKDUyzeLSqksN8LJtgXjqBYw==",
"cpu": [
"arm"
],
@ -482,9 +479,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.0.tgz",
"integrity": "sha512-pqDirm8koABIKvzL59YI9W9DWbRlTX7RWhN+auR8HXJxo89m4mjqbah7nJZjeKNTNYopqL+yGg+0mhCpf3xZtQ==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.48.1.tgz",
"integrity": "sha512-4e9WtTxrk3gu1DFE+imNJr4WsL13nWbD/Y6wQcyku5qadlKHY3OQ3LJ/INrrjngv2BJIHnIzbqMk1GTAC2P8yQ==",
"cpu": [
"arm64"
],
@ -496,9 +493,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.0.tgz",
"integrity": "sha512-YCdWlY/8ltN6H78HnMsRHYlPiKvqKagBP1r+D7SSylxX+HnsgXGCmLiV3Y4nSyY9hW8qr8U9LDUx/Lo7M6MfmQ==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.48.1.tgz",
"integrity": "sha512-+XjmyChHfc4TSs6WUQGmVf7Hkg8ferMAE2aNYYWjiLzAS/T62uOsdfnqv+GHRjq7rKRnYh4mwWb4Hz7h/alp8A==",
"cpu": [
"arm64"
],
@ -510,9 +507,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.0.tgz",
"integrity": "sha512-z4nw6y1j+OOSGzuVbSWdIp1IUks9qNw4dc7z7lWuWDKojY38VMWBlEN7F9jk5UXOkUcp97vA1N213DF+Lz8BRg==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.48.1.tgz",
"integrity": "sha512-upGEY7Ftw8M6BAJyGwnwMw91rSqXTcOKZnnveKrVWsMTF8/k5mleKSuh7D4v4IV1pLxKAk3Tbs0Lo9qYmii5mQ==",
"cpu": [
"x64"
],
@ -524,9 +521,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.0.tgz",
"integrity": "sha512-Q/dv9Yvyr5rKlK8WQJZVrp5g2SOYeZUs9u/t2f9cQ2E0gJjYB/BWoedXfUT0EcDJefi2zzVfhcOj8drWCzTviw==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.48.1.tgz",
"integrity": "sha512-P9ViWakdoynYFUOZhqq97vBrhuvRLAbN/p2tAVJvhLb8SvN7rbBnJQcBu8e/rQts42pXGLVhfsAP0k9KXWa3nQ==",
"cpu": [
"arm64"
],
@ -538,9 +535,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.0.tgz",
"integrity": "sha512-kdBsLs4Uile/fbjZVvCRcKB4q64R+1mUq0Yd7oU1CMm1Av336ajIFqNFovByipciuUQjBCPMxwJhCgfG2re3rg==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.48.1.tgz",
"integrity": "sha512-VLKIwIpnBya5/saccM8JshpbxfyJt0Dsli0PjXozHwbSVaHTvWXJH1bbCwPXxnMzU4zVEfgD1HpW3VQHomi2AQ==",
"cpu": [
"x64"
],
@ -552,9 +549,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.0.tgz",
"integrity": "sha512-aL6hRwu0k7MTUESgkg7QHY6CoqPgr6gdQXRJI1/VbFlUMwsSzPGSR7sG5d+MCbYnJmJwThc2ol3nixj1fvI/zQ==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.48.1.tgz",
"integrity": "sha512-3zEuZsXfKaw8n/yF7t8N6NNdhyFw3s8xJTqjbTDXlipwrEHo4GtIKcMJr5Ed29leLpB9AugtAQpAHW0jvtKKaQ==",
"cpu": [
"arm"
],
@ -566,9 +563,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.0.tgz",
"integrity": "sha512-BTs0M5s1EJejgIBJhCeiFo7GZZ2IXWkFGcyZhxX4+8usnIo5Mti57108vjXFIQmmJaRyDwmV59Tw64Ap1dkwMw==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.48.1.tgz",
"integrity": "sha512-leo9tOIlKrcBmmEypzunV/2w946JeLbTdDlwEZ7OnnsUyelZ72NMnT4B2vsikSgwQifjnJUbdXzuW4ToN1wV+Q==",
"cpu": [
"arm"
],
@ -580,9 +577,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.0.tgz",
"integrity": "sha512-uj672IVOU9m08DBGvoPKPi/J8jlVgjh12C9GmjjBxCTQc3XtVmRkRKyeHSmIKQpvJ7fIm1EJieBUcnGSzDVFyw==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.48.1.tgz",
"integrity": "sha512-Vy/WS4z4jEyvnJm+CnPfExIv5sSKqZrUr98h03hpAMbE2aI0aD2wvK6GiSe8Gx2wGp3eD81cYDpLLBqNb2ydwQ==",
"cpu": [
"arm64"
],
@ -594,9 +591,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.0.tgz",
"integrity": "sha512-/+IVbeDMDCtB/HP/wiWsSzduD10SEGzIZX2945KSgZRNi4TSkjHqRJtNTVtVb8IRwhJ65ssI56krlLik+zFWkw==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.48.1.tgz",
"integrity": "sha512-x5Kzn7XTwIssU9UYqWDB9VpLpfHYuXw5c6bJr4Mzv9kIv242vmJHbI5PJJEnmBYitUIfoMCODDhR7KoZLot2VQ==",
"cpu": [
"arm64"
],
@ -607,10 +604,10 @@
"linux"
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.0.tgz",
"integrity": "sha512-U1vVzvSWtSMWKKrGoROPBXMh3Vwn93TA9V35PldokHGqiUbF6erSzox/5qrSMKp6SzakvyjcPiVF8yB1xKr9Pg==",
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.48.1.tgz",
"integrity": "sha512-yzCaBbwkkWt/EcgJOKDUdUpMHjhiZT/eDktOPWvSRpqrVE04p0Nd6EGV4/g7MARXXeOqstflqsKuXVM3H9wOIQ==",
"cpu": [
"loong64"
],
@ -622,9 +619,9 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.0.tgz",
"integrity": "sha512-X/4WfuBAdQRH8cK3DYl8zC00XEE6aM472W+QCycpQJeLWVnHfkv7RyBFVaTqNUMsTgIX8ihMjCvFF9OUgeABzw==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.48.1.tgz",
"integrity": "sha512-UK0WzWUjMAJccHIeOpPhPcKBqax7QFg47hwZTp6kiMhQHeOYJeaMwzeRZe1q5IiTKsaLnHu9s6toSYVUlZ2QtQ==",
"cpu": [
"ppc64"
],
@ -636,9 +633,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.0.tgz",
"integrity": "sha512-xIRYc58HfWDBZoLmWfWXg2Sq8VCa2iJ32B7mqfWnkx5mekekl0tMe7FHpY8I72RXEcUkaWawRvl3qA55og+cwQ==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.48.1.tgz",
"integrity": "sha512-3NADEIlt+aCdCbWVZ7D3tBjBX1lHpXxcvrLt/kdXTiBrOds8APTdtk2yRL2GgmnSVeX4YS1JIf0imFujg78vpw==",
"cpu": [
"riscv64"
],
@ -650,9 +647,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.0.tgz",
"integrity": "sha512-mbsoUey05WJIOz8U1WzNdf+6UMYGwE3fZZnQqsM22FZ3wh1N887HT6jAOjXs6CNEK3Ntu2OBsyQDXfIjouI4dw==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.48.1.tgz",
"integrity": "sha512-euuwm/QTXAMOcyiFCcrx0/S2jGvFlKJ2Iro8rsmYL53dlblp3LkUQVFzEidHhvIPPvcIsxDhl2wkBE+I6YVGzA==",
"cpu": [
"riscv64"
],
@ -664,9 +661,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.0.tgz",
"integrity": "sha512-qP6aP970bucEi5KKKR4AuPFd8aTx9EF6BvutvYxmZuWLJHmnq4LvBfp0U+yFDMGwJ+AIJEH5sIP+SNypauMWzg==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.48.1.tgz",
"integrity": "sha512-w8mULUjmPdWLJgmTYJx/W6Qhln1a+yqvgwmGXcQl2vFBkWsKGUBRbtLRuKJUln8Uaimf07zgJNxOhHOvjSQmBQ==",
"cpu": [
"s390x"
],
@ -678,9 +675,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.0.tgz",
"integrity": "sha512-nmSVN+F2i1yKZ7rJNKO3G7ZzmxJgoQBQZ/6c4MuS553Grmr7WqR7LLDcYG53Z2m9409z3JLt4sCOhLdbKQ3HmA==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.48.1.tgz",
"integrity": "sha512-90taWXCWxTbClWuMZD0DKYohY1EovA+W5iytpE89oUPmT5O1HFdf8cuuVIylE6vCbrGdIGv85lVRzTcpTRZ+kA==",
"cpu": [
"x64"
],
@ -692,9 +689,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.0.tgz",
"integrity": "sha512-2d0qRo33G6TfQVjaMR71P+yJVGODrt5V6+T0BDYH4EMfGgdC/2HWDVjSSFw888GSzAZUwuska3+zxNUCDco6rQ==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.48.1.tgz",
"integrity": "sha512-2Gu29SkFh1FfTRuN1GR1afMuND2GKzlORQUP3mNMJbqdndOg7gNsa81JnORctazHRokiDzQ5+MLE5XYmZW5VWg==",
"cpu": [
"x64"
],
@ -705,24 +702,10 @@
"linux"
]
},
"node_modules/@rollup/rollup-openharmony-arm64": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.0.tgz",
"integrity": "sha512-A1JalX4MOaFAAyGgpO7XP5khquv/7xKzLIyLmhNrbiCxWpMlnsTYr8dnsWM7sEeotNmxvSOEL7F65j0HXFcFsw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.0.tgz",
"integrity": "sha512-YQugafP/rH0eOOHGjmNgDURrpYHrIX0yuojOI8bwCyXwxC9ZdTd3vYkmddPX0oHONLXu9Rb1dDmT0VNpjkzGGw==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.48.1.tgz",
"integrity": "sha512-6kQFR1WuAO50bxkIlAVeIYsz3RUx+xymwhTo9j94dJ+kmHe9ly7muH23sdfWduD0BA8pD9/yhonUvAjxGh34jQ==",
"cpu": [
"arm64"
],
@ -734,9 +717,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.0.tgz",
"integrity": "sha512-zYdUYhi3Qe2fndujBqL5FjAFzvNeLxtIqfzNEVKD1I7C37/chv1VxhscWSQHTNfjPCrBFQMnynwA3kpZpZ8w4A==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.48.1.tgz",
"integrity": "sha512-RUyZZ/mga88lMI3RlXFs4WQ7n3VyU07sPXmMG7/C1NOi8qisUg57Y7LRarqoGoAiopmGmChUhSwfpvQ3H5iGSQ==",
"cpu": [
"ia32"
],
@ -747,24 +730,10 @@
"win32"
]
},
"node_modules/@rollup/rollup-win32-x64-gnu": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.0.tgz",
"integrity": "sha512-fGk03kQylNaCOQ96HDMeT7E2n91EqvCDd3RwvT5k+xNdFCeMGnj5b5hEgTGrQuyidqSsD3zJDQ21QIaxXqTBJw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.0.tgz",
"integrity": "sha512-6iKDCVSIUQ8jPMoIV0OytRKniaYyy5EbY/RRydmLW8ZR3cEBhxbWl5ro0rkUNe0ef6sScvhbY79HrjRm8i3vDQ==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.48.1.tgz",
"integrity": "sha512-8a/caCUN4vkTChxkaIJcMtwIVcBhi4X2PQRoT+yCK3qRYaZ7cURrmJFL5Ux9H9RaMIXj9RuihckdmkBX3zZsgg==",
"cpu": [
"x64"
],
@ -786,29 +755,25 @@
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
"dev": true,
"license": "MIT"
"dev": true
},
"node_modules/@tsconfig/node12": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
"dev": true,
"license": "MIT"
"dev": true
},
"node_modules/@tsconfig/node14": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
"dev": true,
"license": "MIT"
"dev": true
},
"node_modules/@tsconfig/node16": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
"dev": true,
"license": "MIT"
"dev": true
},
"node_modules/@types/estree": {
"version": "1.0.8",
@ -818,9 +783,9 @@
"license": "MIT"
},
"node_modules/@types/node": {
"version": "22.18.6",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.6.tgz",
"integrity": "sha512-r8uszLPpeIWbNKtvWRt/DbVi5zbqZyj1PTmhRMqBMvDnaz1QpmSKujUtJLrqGZeoM8v72MfYggDceY4K1itzWQ==",
"version": "22.18.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.0.tgz",
"integrity": "sha512-m5ObIqwsUp6BZzyiy4RdZpzWGub9bqLJMvZDD0QMXhxjqMHMENlj+SqF5QxoUwaQNFe+8kz8XM8ZQhqkQPTgMQ==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
@ -830,7 +795,6 @@
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz",
"integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
@ -913,7 +877,6 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/abstract-level/-/abstract-level-3.1.0.tgz",
"integrity": "sha512-j2e+TsAxy7Ri+0h7dJqwasymgt0zHBWX4+nMk3XatyuqgHfdstBJ9wsMfbiGwE1O+QovRyPcVAqcViMYdyPaaw==",
"license": "MIT",
"dependencies": {
"buffer": "^6.0.3",
"is-buffer": "^2.0.5",
@ -931,7 +894,6 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
@ -944,7 +906,6 @@
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
"dev": true,
"license": "MIT",
"dependencies": {
"acorn": "^8.11.0"
},
@ -969,8 +930,7 @@
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"dev": true,
"license": "MIT"
"dev": true
},
"node_modules/assertion-error": {
"version": "1.1.0",
@ -985,14 +945,12 @@
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
"license": "MIT",
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz",
"integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.4",
@ -1016,14 +974,12 @@
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
]
},
"node_modules/browser-level": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/browser-level/-/browser-level-3.0.0.tgz",
"integrity": "sha512-kGXtLh29jMwqKaskz5xeDLtCtN1KBz/DbQSqmvH7QdJiyGRC7RAM8PPg6gvUiNMa+wVnaxS9eSmEtP/f5ajOVw==",
"license": "MIT",
"dependencies": {
"abstract-level": "^3.1.0"
}
@ -1046,7 +1002,6 @@
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
@ -1066,7 +1021,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
@ -1112,7 +1066,6 @@
"resolved": "https://registry.npmjs.org/classic-level/-/classic-level-3.0.0.tgz",
"integrity": "sha512-yGy8j8LjPbN0Bh3+ygmyYvrmskVita92pD/zCoalfcC9XxZj6iDtZTAnz+ot7GG8p9KLTG+MZ84tSA4AhkgVZQ==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"abstract-level": "^3.1.0",
"module-error": "^1.0.1",
@ -1127,7 +1080,6 @@
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
@ -1146,8 +1098,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
"dev": true,
"license": "MIT"
"dev": true
},
"node_modules/cross-spawn": {
"version": "7.0.6",
@ -1165,9 +1116,9 @@
}
},
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -1199,7 +1150,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
@ -1209,7 +1159,6 @@
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
@ -1228,7 +1177,6 @@
"version": "16.6.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
"integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
@ -1240,7 +1188,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
@ -1254,7 +1201,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
@ -1263,7 +1209,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
@ -1272,7 +1217,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
@ -1284,7 +1228,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
@ -1378,7 +1321,6 @@
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
@ -1392,7 +1334,6 @@
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
"integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
@ -1423,7 +1364,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@ -1442,7 +1382,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
@ -1466,7 +1405,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
@ -1492,7 +1430,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
@ -1504,7 +1441,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
@ -1516,7 +1452,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
@ -1531,7 +1466,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
@ -1566,8 +1500,7 @@
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "BSD-3-Clause"
]
},
"node_modules/is-buffer": {
"version": "2.0.5",
@ -1587,7 +1520,6 @@
"url": "https://feross.org/support"
}
],
"license": "MIT",
"engines": {
"node": ">=4"
}
@ -1623,7 +1555,6 @@
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/level/-/level-10.0.0.tgz",
"integrity": "sha512-aZJvdfRr/f0VBbSRF5C81FHON47ZsC2TkGxbBezXpGGXAUEL/s6+GP73nnhAYRSCIqUNsmJjfeOF4lzRDKbUig==",
"license": "MIT",
"dependencies": {
"abstract-level": "^3.1.0",
"browser-level": "^3.0.0",
@ -1641,7 +1572,6 @@
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/level-supports/-/level-supports-6.2.0.tgz",
"integrity": "sha512-QNxVXP0IRnBmMsJIh+sb2kwNCYcKciQZJEt+L1hPCHrKNELllXhvrlClVHXBYZVT+a7aTSM6StgNXdAldoab3w==",
"license": "MIT",
"engines": {
"node": ">=16"
}
@ -1650,7 +1580,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz",
"integrity": "sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==",
"license": "MIT",
"dependencies": {
"buffer": "^6.0.3",
"module-error": "^1.0.1"
@ -1687,9 +1616,9 @@
}
},
"node_modules/magic-string": {
"version": "0.30.19",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz",
"integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==",
"version": "0.30.18",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.18.tgz",
"integrity": "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -1700,14 +1629,12 @@
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true,
"license": "ISC"
"dev": true
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
@ -1716,7 +1643,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/maybe-combine-errors/-/maybe-combine-errors-1.0.0.tgz",
"integrity": "sha512-eefp6IduNPT6fVdwPp+1NgD0PML1NU5P6j1Mj5nz1nidX8/sWY7119WL8vTAHgqfsY74TzW0w1XPgdYEKkGZ5A==",
"license": "MIT",
"engines": {
"node": ">=10"
}
@ -1732,7 +1658,6 @@
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
@ -1741,7 +1666,6 @@
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
@ -1786,7 +1710,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz",
"integrity": "sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==",
"license": "MIT",
"engines": {
"node": ">=10"
}
@ -1820,14 +1743,12 @@
"node_modules/napi-macros": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.2.2.tgz",
"integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g==",
"license": "MIT"
"integrity": "sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g=="
},
"node_modules/node-gyp-build": {
"version": "4.8.4",
"resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz",
"integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==",
"license": "MIT",
"bin": {
"node-gyp-build": "bin.js",
"node-gyp-build-optional": "optional.js",
@ -1995,8 +1916,7 @@
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"node_modules/react-is": {
"version": "18.3.1",
@ -2006,9 +1926,9 @@
"license": "MIT"
},
"node_modules/rollup": {
"version": "4.52.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.0.tgz",
"integrity": "sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g==",
"version": "4.48.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.48.1.tgz",
"integrity": "sha512-jVG20NvbhTYDkGAty2/Yh7HK6/q3DGSRH4o8ALKGArmMuaauM9kLfoMZ+WliPwA5+JHr2lTn3g557FxBV87ifg==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -2022,28 +1942,26 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.52.0",
"@rollup/rollup-android-arm64": "4.52.0",
"@rollup/rollup-darwin-arm64": "4.52.0",
"@rollup/rollup-darwin-x64": "4.52.0",
"@rollup/rollup-freebsd-arm64": "4.52.0",
"@rollup/rollup-freebsd-x64": "4.52.0",
"@rollup/rollup-linux-arm-gnueabihf": "4.52.0",
"@rollup/rollup-linux-arm-musleabihf": "4.52.0",
"@rollup/rollup-linux-arm64-gnu": "4.52.0",
"@rollup/rollup-linux-arm64-musl": "4.52.0",
"@rollup/rollup-linux-loong64-gnu": "4.52.0",
"@rollup/rollup-linux-ppc64-gnu": "4.52.0",
"@rollup/rollup-linux-riscv64-gnu": "4.52.0",
"@rollup/rollup-linux-riscv64-musl": "4.52.0",
"@rollup/rollup-linux-s390x-gnu": "4.52.0",
"@rollup/rollup-linux-x64-gnu": "4.52.0",
"@rollup/rollup-linux-x64-musl": "4.52.0",
"@rollup/rollup-openharmony-arm64": "4.52.0",
"@rollup/rollup-win32-arm64-msvc": "4.52.0",
"@rollup/rollup-win32-ia32-msvc": "4.52.0",
"@rollup/rollup-win32-x64-gnu": "4.52.0",
"@rollup/rollup-win32-x64-msvc": "4.52.0",
"@rollup/rollup-android-arm-eabi": "4.48.1",
"@rollup/rollup-android-arm64": "4.48.1",
"@rollup/rollup-darwin-arm64": "4.48.1",
"@rollup/rollup-darwin-x64": "4.48.1",
"@rollup/rollup-freebsd-arm64": "4.48.1",
"@rollup/rollup-freebsd-x64": "4.48.1",
"@rollup/rollup-linux-arm-gnueabihf": "4.48.1",
"@rollup/rollup-linux-arm-musleabihf": "4.48.1",
"@rollup/rollup-linux-arm64-gnu": "4.48.1",
"@rollup/rollup-linux-arm64-musl": "4.48.1",
"@rollup/rollup-linux-loongarch64-gnu": "4.48.1",
"@rollup/rollup-linux-ppc64-gnu": "4.48.1",
"@rollup/rollup-linux-riscv64-gnu": "4.48.1",
"@rollup/rollup-linux-riscv64-musl": "4.48.1",
"@rollup/rollup-linux-s390x-gnu": "4.48.1",
"@rollup/rollup-linux-x64-gnu": "4.48.1",
"@rollup/rollup-linux-x64-musl": "4.48.1",
"@rollup/rollup-win32-arm64-msvc": "4.48.1",
"@rollup/rollup-win32-ia32-msvc": "4.48.1",
"@rollup/rollup-win32-x64-msvc": "4.48.1",
"fsevents": "~2.3.2"
}
},
@ -2172,7 +2090,6 @@
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@ -2222,11 +2139,10 @@
}
},
"node_modules/typescript": {
"version": "5.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -2252,13 +2168,12 @@
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
"dev": true,
"license": "MIT"
"dev": true
},
"node_modules/vite": {
"version": "5.4.20",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.20.tgz",
"integrity": "sha512-j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g==",
"version": "5.4.19",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz",
"integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==",
"dev": true,
"license": "MIT",
"dependencies": {
@ -2441,7 +2356,6 @@
"version": "8.18.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz",
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
@ -2463,7 +2377,6 @@
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}

@ -1 +0,0 @@
Subproject commit c09135c4eb785fa5ef242cd106bb1e628d5f68fa

View File

@ -1,352 +0,0 @@
// Service de surveillance en arrière-plan pour Node.js
// Équivalent du service worker pour la détection des données manquantes
import { Service } from './service';
import Database from './database.service';
import { config } from './config';
import { retrieveData } from './storage.service';
export class BackgroundSyncService {
private static instance: BackgroundSyncService;
private service: Service;
private db: Database | null = null;
private scanInterval: NodeJS.Timeout | null = null;
private isRunning: boolean = false;
private readonly SCAN_INTERVAL_MS = 30000; // 30 secondes
private readonly EMPTY32BYTES = '0'.repeat(64);
private constructor() {
this.service = Service.getInstance();
console.log('🔧 BackgroundSyncService initialized');
}
static async getInstance(): Promise<BackgroundSyncService> {
if (!BackgroundSyncService.instance) {
BackgroundSyncService.instance = new BackgroundSyncService();
await BackgroundSyncService.instance.init();
}
return BackgroundSyncService.instance;
}
private async init(): Promise<void> {
this.db = await Database.getInstance();
}
/**
* Démarre le service de surveillance en arrière-plan
*/
public async start(): Promise<void> {
if (this.isRunning) {
console.log('⚠️ BackgroundSyncService already running');
return;
}
console.log('🚀 Starting background sync service...');
this.isRunning = true;
// Scan immédiat au démarrage
await this.scanMissingData();
// Puis scan périodique
this.scanInterval = setInterval(async () => {
try {
await this.scanMissingData();
} catch (error) {
console.error('❌ Error in background scan:', error);
}
}, this.SCAN_INTERVAL_MS);
console.log('✅ Background sync service started');
}
/**
* Arrête le service de surveillance
*/
public stop(): void {
if (!this.isRunning) {
return;
}
console.log('🛑 Stopping background sync service...');
this.isRunning = false;
if (this.scanInterval) {
clearInterval(this.scanInterval);
this.scanInterval = null;
}
console.log('✅ Background sync service stopped');
}
/**
* Scan manuel des données manquantes (équivalent à scanMissingData du service worker)
*/
public async scanMissingData(): Promise<string[]> {
console.log('🔍 Scanning for missing data...');
try {
const myProcesses = await this.getMyProcesses();
if (!myProcesses || myProcesses.length === 0) {
console.log('No processes to scan');
return [];
}
const toDownload = new Set<string>();
for (const processId of myProcesses) {
const process = await this.service.getProcess(processId);
if (!process) continue;
for (const state of process.states) {
if (state.state_id === this.EMPTY32BYTES) continue;
// Vérifier chaque pcd_commitment
for (const [field, hash] of Object.entries(state.pcd_commitment)) {
// Ignorer les champs publics
if (state.public_data[field] !== undefined || field === 'roles') continue;
// Vérifier que hash est une string
if (typeof hash !== 'string') continue;
// Vérifier si on a déjà les données
const existingData = await this.getBlob(hash);
if (!existingData) {
toDownload.add(hash);
// Ajouter une entrée diff si elle n'existe pas
await this.addDiff(processId, state.state_id, hash, state.roles, field);
}
}
}
}
const missingHashes = Array.from(toDownload);
if (missingHashes.length > 0) {
console.log(`📥 Found ${missingHashes.length} missing data hashes:`, missingHashes);
await this.requestMissingData(missingHashes);
} else {
console.log('✅ No missing data found');
}
return missingHashes;
} catch (error) {
console.error('❌ Error scanning missing data:', error);
throw error;
}
}
/**
* Récupère les processus de l'utilisateur
*/
private async getMyProcesses(): Promise<string[]> {
try {
return await this.service.getMyProcesses() || [];
} catch (error) {
console.error('Error getting my processes:', error);
return [];
}
}
/**
* Vérifie si un blob existe en base
*/
private async getBlob(hash: string): Promise<Buffer | null> {
try {
return await this.service.getBufferFromDb(hash);
} catch (error) {
return null;
}
}
/**
* Ajoute une entrée diff pour tracking
*/
private async addDiff(
processId: string,
stateId: string,
hash: string,
roles: any,
field: string
): Promise<void> {
try {
if (!this.db) {
console.error('Database not initialized');
return;
}
const existingDiff = await this.db.getObject('diffs', hash);
if (!existingDiff) {
const newDiff = {
process_id: processId,
state_id: stateId,
value_commitment: hash,
roles: roles,
field: field,
description: null,
previous_value: null,
new_value: null,
notify_user: false,
need_validation: false,
validation_status: 'None'
};
await this.db.addObject({
storeName: 'diffs',
object: newDiff,
key: hash
});
console.log(`📝 Added diff entry for hash: ${hash}`);
}
} catch (error) {
console.error('Error adding diff:', error);
}
}
/**
* Demande les données manquantes aux pairs
*/
private async requestMissingData(hashes: string[]): Promise<void> {
try {
console.log('🔄 Requesting missing data from peers...');
// Récupérer tous les processus pour déterminer les rôles
const myProcesses = await this.getMyProcesses();
const processesToRequest: Record<string, any> = {};
for (const processId of myProcesses) {
const process = await this.service.getProcess(processId);
if (process) {
processesToRequest[processId] = process;
}
}
// Pour chaque hash manquant, essayer de le récupérer
for (const hash of hashes) {
try {
// Trouver le diff correspondant
const diffs = await this.service.getDiffsFromDb();
const diff = Object.values(diffs).find((d: any) => d.value_commitment === hash);
if (diff) {
const processId = diff.process_id;
const stateId = diff.state_id;
const roles = diff.roles;
if (processesToRequest[processId]) {
// D'abord essayer de récupérer depuis les serveurs de stockage
const retrievedFromStorage = await this.tryRetrieveFromStorage(hash, roles);
if (retrievedFromStorage) {
console.log(`✅ Data retrieved from storage for hash ${hash}`);
// Sauvegarder les données récupérées en base
await this.service.saveBufferToDb(hash, Buffer.from(retrievedFromStorage));
continue; // Passer au hash suivant
}
// Si pas trouvé en storage, demander aux pairs
console.log(`🔄 Requesting data for hash ${hash} from process ${processId}`);
await this.service.requestDataFromPeers(processId, [stateId], [roles]);
}
}
} catch (error) {
console.error(`Error requesting data for hash ${hash}:`, error);
}
}
} catch (error) {
console.error('Error requesting missing data:', error);
}
}
/**
* Essaie de récupérer les données depuis les serveurs de stockage
*/
private async tryRetrieveFromStorage(hash: string, roles: any): Promise<ArrayBuffer | null> {
try {
// Extraire les URLs de stockage depuis les rôles
const storageUrls = this.extractStorageUrls(roles);
if (storageUrls.length === 0) {
console.log(`No storage URLs found for hash ${hash}`);
return null;
}
console.log(`🔍 Trying to retrieve hash ${hash} from storage servers:`, storageUrls);
// Essayer de récupérer depuis les serveurs de stockage
const data = await retrieveData(storageUrls, hash);
if (data) {
console.log(`✅ Successfully retrieved data for hash ${hash} from storage`);
return data;
} else {
console.log(`❌ Data not found in storage for hash ${hash}`);
return null;
}
} catch (error) {
console.error(`Error retrieving data from storage for hash ${hash}:`, error);
return null;
}
}
/**
* Extrait les URLs de stockage depuis les rôles
*/
private extractStorageUrls(roles: any): string[] {
const storageUrls = new Set<string>();
try {
if (roles && typeof roles === 'object') {
for (const role of Object.values(roles)) {
if (role && typeof role === 'object' && 'storages' in role && Array.isArray((role as any).storages)) {
for (const storageUrl of (role as any).storages) {
if (typeof storageUrl === 'string' && storageUrl.trim()) {
storageUrls.add(storageUrl.trim());
}
}
}
}
}
} catch (error) {
console.error('Error extracting storage URLs from roles:', error);
}
return Array.from(storageUrls);
}
/**
* Force un scan immédiat (pour tests ou usage manuel)
*/
public async forceScan(): Promise<string[]> {
console.log('🔄 Forcing immediate scan...');
return await this.scanMissingData();
}
/**
* Obtient le statut du service
*/
public getStatus(): { isRunning: boolean; scanInterval: number } {
return {
isRunning: this.isRunning,
scanInterval: this.SCAN_INTERVAL_MS
};
}
/**
* Met à jour l'intervalle de scan
*/
public setScanInterval(intervalMs: number): void {
if (this.isRunning && this.scanInterval) {
clearInterval(this.scanInterval);
this.scanInterval = setInterval(async () => {
try {
await this.scanMissingData();
} catch (error) {
console.error('❌ Error in background scan:', error);
}
}, intervalMs);
}
}
}

View File

@ -1,4 +1,7 @@
// Configuration via variables d'environnement (centralisées dans lecoffre_node/.env.master)
import dotenv from 'dotenv';
// Load environment variables from .env file
dotenv.config();
export interface AppConfig {
port: number;
@ -27,4 +30,4 @@ export const config: AppConfig = loadConfig();
// Validate required environment variables
if (!config.apiKey || config.apiKey === 'your-api-key-change-this') {
console.warn('⚠️ Warning: Using default API key. Set API_KEY environment variable for production.');
}
}

View File

@ -37,11 +37,6 @@ export enum MessageType {
// Account management
ADD_DEVICE = 'ADD_DEVICE',
DEVICE_ADDED = 'DEVICE_ADDED',
// Background sync
FORCE_DATA_SCAN = 'FORCE_DATA_SCAN',
DATA_SCAN_RESULT = 'DATA_SCAN_RESULT',
GET_BACKGROUND_SYNC_STATUS = 'GET_BACKGROUND_SYNC_STATUS',
BACKGROUND_SYNC_STATUS = 'BACKGROUND_SYNC_STATUS',
}
// Re-export AnkFlag from WASM for relay message typing

View File

@ -309,7 +309,7 @@ export class RelayManager {
}
// Relay Message Handling
private async handleRelayMessage(relayId: string, message: any): Promise<void> {
private handleRelayMessage(relayId: string, message: any): void {
console.log(`📨 Received message from relay ${relayId}:`);
if (message.flag === 'Handshake') {
@ -321,7 +321,7 @@ export class RelayManager {
// Handle different types of relay responses
if (message.flag) {
// Handle protocol-specific responses
await this.handleProtocolMessage(relayId, message);
this.handleProtocolMessage(relayId, message);
} else if (message.type === 'heartbeat') {
// Update heartbeat
const relay = this.relays.get(relayId);
@ -337,16 +337,14 @@ export class RelayManager {
}
}
private async handleProtocolMessage(relayId: string, message: any): Promise<void> {
private handleProtocolMessage(relayId: string, message: any): void {
// Handle different AnkFlag responses
switch (message.flag) {
case "NewTx":
console.log(`📨 NewTx response from relay ${relayId}`);
try {
await Service.getInstance().parseNewTx(message.content);
} catch (error) {
console.error(`❌ Error parsing NewTx from relay ${relayId}:`, error);
}
setImmediate(() => {
Service.getInstance().parseNewTx(message.content);
});
break;
case "Commit":
console.log(`📨 Commit response from relay ${relayId}`);
@ -355,11 +353,9 @@ export class RelayManager {
break;
case "Cipher":
console.log(`📨 Cipher response from relay ${relayId}`);
try {
await Service.getInstance().parseCipher(message.content);
} catch (error) {
console.error(`❌ Error parsing Cipher from relay ${relayId}:`, error);
}
setImmediate(() => {
Service.getInstance().parseCipher(message.content);
});
break;
case "Handshake":
console.log(`📨 Handshake response from relay ${relayId}`);

View File

@ -16,7 +16,6 @@ export class Service {
private membersList: any = {};
private relayManager: RelayManager;
private storages: string[] = []; // storage urls
private backgroundSync: any = null; // BackgroundSyncService
private constructor() {
console.log('🔧 Service initialized');
@ -1159,12 +1158,8 @@ export class Service {
}
if (apiReturn.new_tx_to_send && apiReturn.new_tx_to_send.transaction.length != 0) {
try {
await this.sendNewTxMessage(JSON.stringify(apiReturn.new_tx_to_send));
await new Promise(r => setTimeout(r, 500));
} catch (error) {
console.error('❌ Error sending NewTx message:', error);
}
await this.sendNewTxMessage(JSON.stringify(apiReturn.new_tx_to_send));
await new Promise(r => setTimeout(r, 500));
}
if (apiReturn.secrets) {
@ -1249,19 +1244,11 @@ export class Service {
if (apiReturn.commit_to_send) {
const commit = apiReturn.commit_to_send;
try {
await this.sendCommitMessage(JSON.stringify(commit));
} catch (error) {
console.error('❌ Error sending Commit message:', error);
}
await this.sendCommitMessage(JSON.stringify(commit));
}
if (apiReturn.ciphers_to_send && apiReturn.ciphers_to_send.length != 0) {
try {
await this.sendCipherMessages(apiReturn.ciphers_to_send);
} catch (error) {
console.error('❌ Error sending Cipher messages:', error);
}
await this.sendCipherMessages(apiReturn.ciphers_to_send);
}
}
@ -1461,54 +1448,4 @@ export class Service {
throw new Error(`Failed to dump device: ${e}`);
}
}
/**
* Démarre le service de surveillance en arrière-plan
*/
public async startBackgroundSync(): Promise<void> {
if (!this.backgroundSync) {
const { BackgroundSyncService } = await import('./background-sync.service');
this.backgroundSync = await BackgroundSyncService.getInstance();
}
await this.backgroundSync.start();
}
/**
* Arrête le service de surveillance
*/
public stopBackgroundSync(): void {
if (this.backgroundSync) {
this.backgroundSync.stop();
}
}
/**
* Force un scan manuel des données manquantes
*/
public async forceDataScan(): Promise<string[]> {
if (!this.backgroundSync) {
const { BackgroundSyncService } = await import('./background-sync.service');
this.backgroundSync = await BackgroundSyncService.getInstance();
}
return await this.backgroundSync.forceScan();
}
/**
* Obtient le statut du service de background sync
*/
public getBackgroundSyncStatus(): { isRunning: boolean; scanInterval: number } | null {
if (!this.backgroundSync) {
return null;
}
return this.backgroundSync.getStatus();
}
/**
* Configure l'intervalle de scan du background sync
*/
public setBackgroundSyncInterval(intervalMs: number): void {
if (this.backgroundSync) {
this.backgroundSync.setScanInterval(intervalMs);
}
}
}

View File

@ -321,57 +321,6 @@ class SimpleProcessHandlers {
}
}
async handleForceDataScan(event: ServerMessageEvent): Promise<ServerResponse> {
if (event.data.type !== MessageType.FORCE_DATA_SCAN) {
throw new Error('Invalid message type');
}
try {
const { apiKey } = event.data;
if (!apiKey || !this.validateApiKey(apiKey)) {
throw new Error('Invalid API key');
}
const missingHashes = await this.service.forceDataScan();
return {
type: MessageType.DATA_SCAN_RESULT,
missingHashes,
count: missingHashes.length,
messageId: event.data.messageId
};
} catch (e) {
const errorMessage = e instanceof Error ? e.message : String(e || 'Unknown error');
throw new Error(errorMessage);
}
}
async handleGetBackgroundSyncStatus(event: ServerMessageEvent): Promise<ServerResponse> {
if (event.data.type !== MessageType.GET_BACKGROUND_SYNC_STATUS) {
throw new Error('Invalid message type');
}
try {
const { apiKey } = event.data;
if (!apiKey || !this.validateApiKey(apiKey)) {
throw new Error('Invalid API key');
}
const status = this.service.getBackgroundSyncStatus();
return {
type: MessageType.BACKGROUND_SYNC_STATUS,
status,
messageId: event.data.messageId
};
} catch (e) {
const errorMessage = e instanceof Error ? e.message : String(e || 'Unknown error');
throw new Error(errorMessage);
}
}
async handleMessage(event: ServerMessageEvent): Promise<ServerResponse> {
try {
switch (event.data.type) {
@ -387,10 +336,6 @@ class SimpleProcessHandlers {
return await this.handleGetMyProcesses(event);
case MessageType.GET_PAIRING_ID:
return await this.handleGetPairingId(event);
case MessageType.FORCE_DATA_SCAN:
return await this.handleForceDataScan(event);
case MessageType.GET_BACKGROUND_SYNC_STATUS:
return await this.handleGetBackgroundSyncStatus(event);
default:
throw new Error(`Unhandled message type: ${event.data.type}`);
}
@ -488,20 +433,10 @@ export class Server {
// Connect to relays
await service.connectToRelaysAndWaitForHandshake();
// Start background sync service for missing data detection
try {
await service.startBackgroundSync();
console.log('🔄 Background sync service started');
} catch (error) {
console.error('❌ Failed to start background sync service:', error);
// Don't exit, continue without background sync
}
console.log(`✅ Simple server running on port ${this.wss.options.port}`);
console.log('📋 Supported operations: UPDATE_PROCESS, NOTIFY_UPDATE, VALIDATE_STATE');
console.log('🔑 Authentication: API key required for all operations');
console.log('🔧 Services: Integrated with SimpleService protocol logic');
console.log('🔄 Background sync: Automatic missing data detection enabled');
} catch (error) {
console.error('❌ Failed to initialize server:', error);
@ -574,15 +509,6 @@ export class Server {
public shutdown() {
console.log('🛑 Shutting down server...');
// Stop background sync service
try {
const service = Service.getInstance();
service.stopBackgroundSync();
console.log('🔄 Background sync service stopped');
} catch (error) {
console.error('❌ Error stopping background sync service:', error);
}
// Close all active client connections first
for (const [ws, clientId] of this.clients.entries()) {
console.log(`🔌 Closing connection to ${clientId}...`);

View File

@ -50,24 +50,11 @@ export async function retrieveData(servers: string[], key: string): Promise<Arra
});
if (response.status === 200) {
// Handle both ArrayBuffer and Buffer (Node.js)
// Validate that we received an ArrayBuffer
if (response.data instanceof ArrayBuffer) {
return response.data;
} else if (Buffer.isBuffer(response.data)) {
// Convert Buffer to ArrayBuffer
return (response.data.buffer as ArrayBuffer).slice(
response.data.byteOffset,
response.data.byteOffset + response.data.byteLength
);
} else if (response.data && typeof response.data === 'object' && 'buffer' in response.data) {
// Handle Uint8Array or similar typed arrays
const buffer = response.data.buffer;
return (buffer as ArrayBuffer).slice(
response.data.byteOffset,
response.data.byteOffset + response.data.byteLength
);
} else {
console.error('Server returned unsupported data type:', typeof response.data, response.data?.constructor?.name);
console.error('Server returned non-ArrayBuffer data:', typeof response.data);
continue;
}
} else {