cryptofoundry

Contacter cryptofoundry

Dites-nous ce que vous voulez construire ou automatiser.

currencyinfo

Currencyinfo v4.2.0

Currencyinfo 4.2.0 reconstruit la couche de sources de taux autour de fournisseurs sans clé après la disparition de deux niveaux gratuits en amont, renforce le runtime et le conteneur, et propose un site de documentation ainsi qu’une suite de tests réelle.

Sécurité auditée par cryptofoundry.

Mise à niveau depuis la version 4.1.2 ou antérieure

Les consommateurs de l’API n’ont besoin d’aucune modification : les formats de réponse /get, /getHistory et /status restent inchangés. Deux étapes obligatoires sont requises pour les opérateurs.

Un fichier config.jsonc standard de la version 4.1.2 ne démarrera pas sur la version 4.2.0. CryptoCompare et CoinGecko nécessitent désormais tous deux une clé API, et comme ils sont tous deux activés dans le modèle 4.1.2, une configuration non modifiée échouera à la validation avant l’ouverture du port HTTP. Désactivez-les ou fournissez des identifiants, ajoutez les remplaçants sans clé pour restaurer la couverture, et mettez à jour les priorities.

Les index tickers sont reconstruits. Trois index triés par date remplacent trois anciens. Mongoose crée les nouveaux lors de la connexion mais ne supprime jamais les anciens ; une mise à niveau directe construira donc les trois au démarrage, ce qui peut retarder la disponibilité. Construisez-les d’abord hors ligne.

Mesuré sur deux déploiements en production contenant environ 238 millions de documents de tickers chacun : sur NVMe avec 12 cœurs et 64 Go de RAM, la construction des trois index a pris 17 minutes avec une indexSize passant de 9,1 à 19,3 Go ; sur SATA avec 4 cœurs et 16 Go de RAM, la même opération a pris 50 minutes avec une indexSize passant de 8,7 à 18,9 Go.

Node.js 22.12 ou une version ultérieure est désormais requis. Le retour à la version 4.1.2 est sûr : la structure des documents stockés est inchangée.

Sources de taux

L’ensemble des fournisseurs a été retravaillé après que CryptoCompare a retiré son offre gratuite le 21 mai 2026 et que le plan sans clé de CoinGecko est devenu inutilisable. Quatre connecteurs sont nouveaux, et tous les quatre sont sans clé.

CoinPaprika effectue un appel groupé classé par cycle, plus un nombre limité d’appels par pièce pour les pièces hors de la plage groupée. bulk_limit et max_individual_requests limitent le budget de requêtes, et les pièces hors plage sont exclues au démarrage avec un avertissement au lieu de consommer le quota à chaque cycle.

CoinLore renvoie l’ensemble des pièces dans une seule requête multi-ID. Les ID numériques de CoinLore étant réattribués entre les listes, une réponse dont le symbole ne correspond pas à l’ID configuré est rejetée au runtime plutôt que considérée comme fiable.

Binance fournit des données de marché spot publiques provenant d’une plateforme d’échange plutôt que d’un agrégateur, ce qui garantit une indépendance réelle par rapport aux quatre agrégateurs qui partagent partiellement les données en amont. Binance n’ayant pas de paires USD directes, les taux sont demandés par rapport à un quote_asset configurable (USDT par défaut) et servis en USD ; un découplage sépare les taux affectés dans leur propre groupe de divergence au lieu d’être masqués par un mappage. Le blocage géographique HTTP 451 désactive le connecteur et génère une alerte unique au lieu d’échouer à chaque cycle.

ExchangeRate-API fournit des taux fiat sans clé pour 166 devises avec des mises à jour quotidiennes.

CryptoCompare est obsolète et désactivé par défaut, supprimé des priorities, et sa suppression est prévue pour la prochaine version majeure. Une clé API est obligatoire lorsqu’il est activé. CoinGecko est désactivé par défaut et nécessite désormais une clé de démonstration gratuite, car le plan public sans clé limite le débit à 5–15 appels par minute de manière imprévisible.

Cinq sources sont désormais activées par défaut sans aucun identifiant, ce qui fait du fichier config.default.jsonc fourni une configuration fonctionnelle : trois sources crypto sans clé et deux sources fiat sans clé signifient que minSources: 2 est satisfait dès le départ.

L’accès sans clé ne signifie pas l’autorisation de republier. CoinPaprika et ExchangeRate-API restreignent tous deux la redistribution par une instance publique ou commerciale. Lisez les conditions des sources et la documentation sur la redistribution avant de servir ces taux.

Calcul des taux et exactitude de l’API

Les index tickers sont triés par date ({ base: 1, date: -1 }, { quote: 1, date: -1 }, { base: 1, quote: 1, date: -1 }), de sorte que les tris de /getHistory sont fournis par l’index au lieu de bloquer les tris en mémoire. Mesuré sur une collection de 238 millions de documents, la même requête de paire et de plage est passée de 22,8 s à 8 ms.

Les filtres historiques coin utilisent désormais l’ordre documenté BASE/QUOTE. Sur la version 4.1.x, le filtre de paire était inversé, donc coin=ADM/USD ne correspondait à rien. Les déploiements utilisant une solution de contournement côté client doivent la supprimer.

minSources est mesuré par rapport aux sources à jour pour la durée de vie demandée ; un fournisseur obsolète ne peut donc plus satisfaire la condition du nombre de sources. Le seuil effectif est min(minSources, coverage), ce qui permet de servir une paire à fournisseur unique tout en la signalant dans l’avertissement de démarrage.

La triangulation rejette les taux croisés qui s’arrondissent à zéro ou qui ne sont pas finis. Les schémas de /get et /getHistory sont .strict(), donc un paramètre de requête inconnu renvoie une erreur 400 au lieu d’être ignoré silencieusement. Les erreurs de validation renvoient désormais 400 au lieu de 500.

Les symboles de pièces acceptés des fournisseurs et des filtres de requête sont sous une forme Unicode plus large, de sorte que chaque paire stockée est adressable — $CWIF en est un exemple réel — tandis que les fautes de frappe dans base_coins et mappings échouent toujours au démarrage.

/status rapporte updating à partir de l’état de mise à jour réel plutôt que de l’inférer d’une comparaison d’horodatage, et les cycles de rafraîchissement simultanés sont ignorés plutôt que superposés.

Sécurité

Les URL de webhook, les clés API et les mots de passe sont masqués dans les journaux, les fichiers de log et l’envoi de notifications. Cela corrige une fuite réelle : une réponse d’erreur en amont plaçait une clé API dans le journal via l’URL d’erreur Axios.

Le répertoire logs est créé en 0o750 et les fichiers de log en 0o600, au mieux pour qu’un volume monté appartenant à un autre utilisateur ne bloque jamais le démarrage. Les noms de fichiers de log ne contiennent plus de deux-points, ce qui les rendait impossibles à ouvrir sur certains systèmes de fichiers.

Le conteneur s’exécute en tant qu’utilisateur non privilégié node, npm/pnpm/yarn sont supprimés de l’image d’exécution, apk upgrade applique les mises à jour Alpine en attente au moment de la construction, et une protection lors de la construction échoue si une dépendance de production contient une liaison native. config.jsonc est délibérément absent de l’image, donc aucune couche ne peut transporter d’identifiant. x-powered-by est désactivé, et la validation de la configuration rejette les clés inconnues et les valeurs dont la casse ne correspond pas.

L’analyse Trivy est exécutée dans la CI, et la politique de vulnérabilité est documentée. multer et js-yaml sont épinglés via overrides, de sorte que pnpm audit et pnpm audit --prod reviennent propres.

Plateforme et dépendances

Node.js >= 22.12.0 est requis, avec pnpm épinglé à 12.3.4 via packageManager. NestJS a été mis à niveau de 10 à 12, Mongoose de 8 à 9, Zod de 3 à 4, adamant-api de 2 à 3, et chalk de 4 à 6. ESLint a été mis à niveau de 8 à 10 avec une configuration plate, TypeScript de 5 à 6, Jest de 29 à 30, et Prettier à 3.9.

pnpm-workspace.yaml contient la liste d’autorisation des scripts d’installation sur laquelle pnpm run deps:setup s’appuie. Les erreurs de connexion MongoDB sont enregistrées plutôt qu’ignorées, et le chemin d’échec du bootstrap se termine avec un code non nul et un message nettoyé.

Distribution

publish-docker.yml effectue une publication multi-plateforme pilotée par les versions sur ghcr.io/adamant-im/currencyinfo pour linux/amd64 et linux/arm64, avec des étiquettes OCI, un SBOM et une attestation de provenance de construction. Le job refuse de continuer à moins que le tag de version ne soit un ancêtre de master, et latest ne change que pour la nouvelle version non préliminaire.

docker-ci.yml construit l’image de production sur les pull requests et les teste par rapport au fichier config.default.jsonc fourni, prouvant que la configuration par défaut démarre et renvoie des taux sans clé API. Il vérifie les étiquettes OCI, confirme que l’image ne contient aucune configuration ou secret, et confirme que le conteneur s’exécute en tant que non-root. Il ne pousse jamais.

docker-compose.prod.yaml extrait l’image publiée au lieu de la construire, monte la configuration en lecture seule, et épingle mongo:8.0. Le fichier Compose de développement lie MongoDB à 127.0.0.1 au lieu de toutes les interfaces.

docker pull ghcr.io/adamant-im/currencyinfo:4.2.0

Documentation et tests

Un site de documentation est disponible sur https://currencyinfo.docs.adamant.im couvrant le démarrage rapide, l’installation, l’architecture, le calcul des taux, l’historique, les notifications, les opérations, la sécurité, le dépannage, la mise à niveau, ainsi qu’une référence complète REST et de configuration, et une page par source de taux documentant le quota, la forme de l’identifiant, le mode de défaillance et les conditions de redistribution.

LICENSE (GPL-3.0) a été ajouté en tant que fichier pour la première fois, avec CONTRIBUTING.md et AGENTS.md.

La suite de tests est passée de 3 fichiers spec à 28, couvrant chaque connecteur de source, le fusionneur et ses stratégies, le gestionnaire de sources, le chargement de la configuration, la migration et la validation de schéma, le logger, le notificateur, les deux schémas de requête, le filtre d’exception, le pipe de validation, l’intercepteur, le contrôleur et les utilitaires partagés. pnpm test exécute 266 tests.

Changements majeurs

Un fichier config.jsonc standard de la version 4.1.2 ne démarre pas sur la version 4.2.0 car CryptoCompare et CoinGecko nécessitent désormais une clé API et sont tous deux activés dans le modèle 4.1.2. Les opérateurs doivent les désactiver ou fournir des identifiants, ajouter les remplaçants sans clé pour restaurer la couverture, et mettre à jour les priorities. Trois index tickers triés par date remplacent trois anciens ; Mongoose crée les nouveaux lors de la connexion mais ne supprime jamais les anciens, donc construisez-les d’abord hors ligne pour éviter de retarder la disponibilité. Node.js 22.12 ou une version ultérieure est désormais requis. Les filtres historiques coin utilisent désormais l’ordre documenté BASE/QUOTE ; sur 4.1.x, le filtre de paire était inversé, donc les déploiements utilisant une solution de contournement côté client doivent la supprimer. Les schémas /get et /getHistory sont .strict(), donc un paramètre de requête inconnu renvoie désormais une erreur 400 au lieu d’être ignoré silencieusement, et les erreurs de validation renvoient 400 au lieu de 500.