cryptofoundry

cryptofoundry kontaktieren

Sagen Sie uns, was Sie bauen oder automatisieren möchten.

currencyinfo

Currencyinfo v4.2.0

Currencyinfo 4.2.0 baut die Ebene der Ratenquellen auf schlüssellose Anbieter um, nachdem zwei vorgelagerte kostenlose Tarife weggefallen sind. Zudem wurde die Laufzeitumgebung sowie der Container gehärtet und eine Dokumentationsseite sowie eine vollständige Test-Suite hinzugefügt.

Sicherheitsprüfung durch cryptofoundry.

Upgrade von 4.1.2 oder älter

Für API-Konsumenten sind keine Änderungen erforderlich: Die Antwortstrukturen von /get, /getHistory und /status bleiben unverändert. Für Betreiber sind jedoch zwei Schritte zwingend erforderlich.

Eine Standard-config.jsonc aus Version 4.1.2 startet unter 4.2.0 nicht. Da sowohl CryptoCompare als auch CoinGecko nun einen API-Schlüssel erfordern und beide in der 4.1.2-Vorlage aktiviert sind, schlägt eine unveränderte Konfiguration bei der Validierung fehl, bevor der HTTP-Port geöffnet wird. Deaktivieren Sie diese oder hinterlegen Sie Zugangsdaten, fügen Sie die schlüssellosen Ersatzanbieter hinzu, um die Abdeckung wiederherzustellen, und aktualisieren Sie die priorities.

Die tickers-Indizes wurden neu erstellt. Drei datumsbasierte Indizes ersetzen drei ältere. Mongoose erstellt die neuen Indizes beim Verbindungsaufbau, löscht die alten jedoch nicht. Ein direktes Upgrade führt daher beim Start zum Aufbau aller drei Indizes, was die Einsatzbereitschaft verzögern kann. Erstellen Sie diese daher vorab manuell.

Messungen bei zwei Produktionsumgebungen mit jeweils ca. 238 Millionen Ticker-Dokumenten: Auf NVMe mit 12 Kernen und 64 GB RAM dauerte der Aufbau aller drei Indizes 17 Minuten, wobei die indexSize von 9,1 auf 19,3 GB anwuchs; auf SATA mit 4 Kernen und 16 GB RAM dauerte derselbe Vorgang 50 Minuten, bei einem Anstieg der indexSize von 8,7 auf 18,9 GB.

Node.js 22.12 oder neuer ist nun erforderlich. Ein Rollback auf 4.1.2 ist sicher, da das Layout der gespeicherten Dokumente unverändert bleibt.

Ratenquellen

Die Auswahl der Anbieter wurde überarbeitet, nachdem CryptoCompare seinen kostenlosen Tarif am 21. Mai 2026 eingestellt hat und der schlüssellose Plan von CoinGecko unbrauchbar wurde. Es wurden vier neue Konnektoren hinzugefügt, die alle schlüssellos sind.

CoinPaprika führt pro Zyklus einen gruppierten Massenabruf sowie eine begrenzte Anzahl an Einzelabrufen für Coins außerhalb des Massenbereichs durch. bulk_limit und max_individual_requests begrenzen das Anfragebudget; Coins außerhalb des Bereichs werden beim Start mit einer Warnung ausgeschlossen, anstatt das Kontingent in jedem Zyklus zu belasten.

CoinLore gibt den gesamten Coin-Satz in einer einzigen Anfrage mit mehreren IDs zurück. Numerische CoinLore-IDs werden über verschiedene Listings hinweg neu zugewiesen; daher wird eine Antwort, deren Symbol nicht mit der konfigurierten ID übereinstimmt, zur Laufzeit abgelehnt, anstatt ihr zu vertrauen.

Binance liefert öffentliche Spot-Marktdaten direkt von der Börse und nicht von einem Aggregator, was eine echte Quellenunabhängigkeit von den vier Aggregatoren bietet, die teilweise dieselben Quelldaten nutzen. Da Binance keine direkten USD-Paare anbietet, werden Raten gegen ein konfigurierbares quote_asset (standardmäßig USDT) abgefragt und als USD bereitgestellt; ein Depeg führt dazu, dass die betroffenen Raten in eine eigene Divergenzgruppe aufgeteilt werden, anstatt durch ein Mapping verborgen zu werden. HTTP 451 Geo-Blocking deaktiviert den Konnektor und warnt einmalig, anstatt in jedem Zyklus einen Fehler zu erzeugen.

ExchangeRate-API bietet schlüssellose Fiat-Raten für 166 Währungen mit täglichen Updates.

CryptoCompare ist als veraltet markiert, standardmäßig deaktiviert, aus den priorities entfernt und für die nächste Hauptversion zur Löschung vorgesehen. Bei Aktivierung ist ein API-Schlüssel zwingend erforderlich. CoinGecko ist standardmäßig deaktiviert und erfordert nun einen kostenlosen Demo-Schlüssel, da der schlüssellose öffentliche Plan unvorhersehbar auf 5–15 Anrufe pro Minute gedrosselt wird.

Fünf Quellen sind nun standardmäßig ohne Zugangsdaten aktiviert, was die mitgelieferte config.default.jsonc zu einer funktionsfähigen Konfiguration macht: Drei schlüssellose Krypto-Quellen und zwei schlüssellose Fiat-Quellen bedeuten, dass minSources: 2 sofort erfüllt ist.

Schlüsselloser Zugriff ist nicht gleichbedeutend mit der Erlaubnis zur Weiterverbreitung. Sowohl CoinPaprika als auch ExchangeRate-API schränken die Weiterverbreitung durch öffentliche oder kommerzielle Instanzen ein. Lesen Sie die Nutzungsbedingungen der Quellen und die Dokumentation zur Weiterverbreitung, bevor Sie diese Raten weitergeben.

Ratenberechnung und API-Korrektheit

Die tickers-Indizes sind nach Datum sortiert ({ base: 1, date: -1 }, { quote: 1, date: -1 }, { base: 1, quote: 1, date: -1 }), sodass Sortierungen bei /getHistory direkt über den Index erfolgen, anstatt speicherintensive Sortierungen zu blockieren. Bei einer Sammlung von 238 Millionen Dokumenten sank die Abfragezeit für Paare und Zeiträume von 22,8 s auf 8 ms.

Historische coin-Filter verwenden nun die dokumentierte Reihenfolge BASE/QUOTE. In Version 4.1.x war der Paarfilter invertiert, sodass coin=ADM/USD keine Treffer lieferte. Bereitstellungen, die einen clientseitigen Workaround zur Umkehrung verwenden, müssen diesen entfernen.

minSources wird nun anhand von Quellen gemessen, die für den angeforderten Zeitraum aktuell sind, sodass ein veralteter Anbieter die Anforderung für die Mindestanzahl an Quellen nicht mehr erfüllen kann. Der effektive Schwellenwert ist min(minSources, coverage), was die Bereitstellung eines Paares mit nur einem Anbieter ermöglicht, während dies dennoch in der Startwarnung gemeldet wird.

Die Triangulation lehnt Kreuzkurse ab, die auf Null runden oder nicht-endlich sind. Die Schemata für /get und /getHistory sind nun .strict(), sodass ein unbekannter Abfrageparameter zu einem 400-Fehler führt, anstatt stillschweigend ignoriert zu werden. Validierungsfehler geben nun 400 anstelle von 500 zurück.

Coin-Symbole, die von Anbietern und Abfragefiltern akzeptiert werden, unterstützen nun ein breiteres Unicode-Format, sodass jedes gespeicherte Paar adressierbar ist – $CWIF ist ein konkretes Beispiel –, während Tippfehler in base_coins und mappings weiterhin beim Start zu Fehlern führen.

/status meldet den Status updating basierend auf dem tatsächlichen Aktualisierungszustand, anstatt ihn aus einem Zeitstempelvergleich abzuleiten; gleichzeitige Aktualisierungszyklen werden übersprungen, anstatt sich zu überschneiden.

Sicherheit

Webhook-URLs, API-Schlüssel und Passphrasen werden in Log-Ausgaben, Log-Dateien und Benachrichtigungen geschwärzt. Dies schließt eine reale Sicherheitslücke: Eine vorgelagerte Fehlerantwort fügte einen API-Schlüssel über die Axios-Fehler-URL in das Log ein.

Das Verzeichnis logs wird mit 0o750 und Log-Dateien mit 0o600 erstellt. Dies geschieht nach dem Best-Effort-Prinzip, damit ein eingehängtes Volume, das einem anderen Benutzer gehört, den Start nicht blockiert. Log-Dateinamen enthalten keine Doppelpunkte mehr, was sie auf einigen Dateisystemen unlesbar machte.

Der Container läuft als nicht privilegierter node-Benutzer, npm/pnpm/yarn wurden aus dem Laufzeit-Image entfernt, apk upgrade wendet ausstehende Alpine-Updates zur Build-Zeit an, und eine Build-Zeit-Prüfung schlägt fehl, falls eine Produktionsabhängigkeit eine native Bindung enthält. config.jsonc ist absichtlich nicht im Image enthalten, sodass keine Ebene Zugangsdaten enthalten kann. x-powered-by ist deaktiviert, und die Konfigurationsvalidierung lehnt unbekannte Schlüssel sowie Werte mit falscher Groß-/Kleinschreibung ab.

Trivy-Scans werden in der CI ausgeführt und die Sicherheitsrichtlinie ist dokumentiert. multer und js-yaml sind über overrides fixiert, sodass pnpm audit und pnpm audit --prod keine Fehler melden.

Plattform und Abhängigkeiten

Node.js >= 22.12.0 ist erforderlich, wobei pnpm über packageManager auf 12.3.4 fixiert ist. NestJS wurde von 10 auf 12, Mongoose von 8 auf 9, Zod von 3 auf 4, adamant-api von 2 auf 3 und chalk von 4 auf 6 aktualisiert. ESLint wurde auf 10 mit Flat-Konfiguration, TypeScript auf 6, Jest auf 30 und Prettier auf 3.9 aktualisiert.

pnpm-workspace.yaml enthält die Whitelist für Installationsskripte, auf die sich pnpm run deps:setup stützt. MongoDB-Verbindungsfehler werden protokolliert, anstatt unterdrückt zu werden, und der Bootstrap-Fehlerpfad beendet den Prozess mit einem bereinigten Fehlercode und einer Nachricht.

Distribution

publish-docker.yml führt eine release-gesteuerte Multi-Plattform-Publikation nach ghcr.io/adamant-im/currencyinfo für linux/amd64 und linux/arm64 durch, inklusive OCI-Labels, SBOM und Build-Provenienz-Attestierung. Der Job verweigert die Fortsetzung, sofern der Release-Tag kein Vorfahre von master ist, und latest wird nur für das neueste Nicht-Prerelease aktualisiert.

docker-ci.yml baut das Produktions-Image bei Pull-Requests und führt Smoke-Tests mit der mitgelieferten config.default.jsonc durch, um zu beweisen, dass die Standardkonfiguration startet und Raten ohne API-Schlüssel liefert. Es verifiziert OCI-Labels, bestätigt, dass das Image keine Konfiguration oder Geheimnisse enthält, und bestätigt, dass der Container nicht als Root läuft. Es erfolgt kein Push.

docker-compose.prod.yaml zieht das veröffentlichte Image anstatt es zu bauen, bindet die Konfiguration schreibgeschützt ein und fixiert mongo:8.0. Die Compose-Datei für die Entwicklung bindet MongoDB an 127.0.0.1 statt an alle Schnittstellen.

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

Dokumentation und Tests

Eine Dokumentationsseite ist unter https://currencyinfo.docs.adamant.im verfügbar. Sie umfasst Schnellstart, Installation, Architektur, Ratenberechnung, Historie, Benachrichtigungen, Betrieb, Sicherheit, Fehlerbehebung, Upgrades sowie eine vollständige REST- und Konfigurationsreferenz und eine Seite pro Ratenquelle, die Kontingente, Identifikatorformate, Fehlermodi und Weiterverbreitungsbedingungen dokumentiert.

LICENSE (GPL-3.0) wurde erstmals als Datei hinzugefügt, ebenso wie CONTRIBUTING.md und AGENTS.md.

Die Test-Suite wuchs von 3 auf 28 Spezifikationsdateien und deckt nun jeden Quell-Konnektor, den Merger und seine Strategien, den Quellen-Manager, das Laden der Konfiguration, Migration und Schema-Validierung, den Logger, den Notifier, beide Anfrageschemata, den Ausnahme-Filter, die Validierungs-Pipe, den Interceptor, den Controller und die gemeinsamen Hilfsprogramme ab. pnpm test führt 266 Tests aus.

Breaking changes

Eine Standard-config.jsonc aus 4.1.2 startet unter 4.2.0 nicht, da CryptoCompare und CoinGecko nun einen API-Schlüssel erfordern und in der 4.1.2-Vorlage aktiviert sind. Betreiber müssen diese deaktivieren oder Zugangsdaten bereitstellen, die schlüssellosen Ersatzanbieter hinzufügen und die priorities aktualisieren. Drei datumsbasierte tickers-Indizes ersetzen drei ältere; Mongoose erstellt die neuen beim Verbindungsaufbau, löscht die alten aber nicht, daher sollten diese vorab manuell erstellt werden. Node.js 22.12 oder neuer ist erforderlich. Historische coin-Filter verwenden nun die dokumentierte BASE/QUOTE-Reihenfolge; da der Paarfilter in 4.1.x invertiert war, müssen Bereitstellungen mit clientseitigem Workaround diesen entfernen. Die Schemata für /get und /getHistory sind .strict(), sodass ein unbekannter Abfrageparameter nun 400 zurückgibt, anstatt ignoriert zu werden, und Validierungsfehler geben 400 anstelle von 500 zurück.