Currencyinfo 4.2.0では、2つの上位無料ティアの提供終了を受けてレートソース層をキーレスプロバイダー中心に再構築しました。また、ランタイムとコンテナの堅牢化に加え、ドキュメントサイトの公開と本格的なテストスイートの実装を行いました。
セキュリティ監査はcryptofoundryによって実施済みです。
4.1.2以前からのアップグレード
API利用側に変更は不要です。/get、/getHistory、および/statusのレスポンス形式に変更はありません。ただし、運用担当者は以下の2つの手順を必ず実行してください。
標準の4.1.2 config.jsoncは、4.2.0では起動しません。CryptoCompareとCoinGeckoの両方がAPIキーを必須とするようになり、かつ4.1.2のテンプレートでは両方が有効化されているため、設定を変更しないままではHTTPポートが開く前にバリデーションエラーが発生します。これらを無効化するか資格情報を入力し、キーレスの代替ソースを追加してカバレッジを回復させた上で、prioritiesを更新してください。
tickersインデックスが再構築されました。従来の3つのインデックスに代わり、日付順の新しいインデックスが3つ作成されます。Mongooseは接続時に新しいインデックスを作成しますが、古いインデックスを自動的に削除することはありません。そのため、直接アップグレードを行うと起動時に3つすべてが構築され、準備完了までに時間がかかる可能性があります。事前に帯域外でインデックスを構築しておくことを推奨します。
約2億3800万件のティッカードキュメントを保持する2つの本番環境で測定した結果、NVMe、12コア、64GB RAMの環境では、3つのインデックス構築に17分かかり(indexSizeは9.1GBから19.3GBに増加)、SATA、4コア、16GB RAMの環境では50分かかりました(indexSizeは8.7GBから18.9GBに増加)。
Node.js 22.12以降が必須となりました。4.1.2へのロールバックは安全に行えます。保存されているドキュメントレイアウトに変更はありません。
レートソース
2026年5月21日にCryptoCompareが無料ティアを終了し、CoinGeckoのキーレスプランが利用不可能になったことを受け、プロバイダーセットを見直しました。新たに4つのコネクタを追加し、すべてキーレス対応としています。
CoinPaprikaは、サイクルごとに1回のランク付けされたバルク呼び出しと、バルク範囲外のコインに対する制限付きの個別呼び出しを行います。bulk_limitとmax_individual_requestsによってリクエスト予算を制限し、範囲外のコインは毎サイクルクォータを消費する代わりに、起動時に警告を出して除外します。
CoinLoreは、単一のマルチIDリクエストで全コインセットを返します。CoinLoreの数値IDはリストごとに再割り当てされるため、シンボルが設定されたIDと一致しないレスポンスは、信頼せずランタイムで拒否されます。
Binanceは、アグリゲーターではなく取引所から直接公開スポット市場データを提供するため、上位データを部分的に共有する4つのアグリゲーターとは独立したソースとなります。Binanceには直接のUSDペアが存在しないため、設定可能なquote_asset(デフォルトはUSDT)に対してレートをリクエストし、USDとして提供します。デペグが発生した場合は、マッピングによって隠蔽されるのではなく、影響を受けたレートが独自のダイバージェンスグループに分割されます。HTTP 451ジオブロッキングが発生した場合は、毎サイクル失敗するのではなく、コネクタを無効化して一度だけ警告を出します。
ExchangeRate-APIは、166通貨にわたるキーレスの法定通貨レートを日次更新で提供します。
CryptoCompareは非推奨となりデフォルトで無効化されました。prioritiesから削除済みであり、次回のメジャーリリースで完全に削除される予定です。有効化する場合はAPIキーが必須となります。CoinGeckoもデフォルトで無効化されており、キーレスのパブリックプランではレート制限が予測不能(毎分5〜15回)であるため、無料のデモキーが必須となりました。
現在、資格情報なしでデフォルトで有効なソースが5つあり、同梱のconfig.default.jsoncでそのまま動作するようになっています。3つのキーレス暗号資産ソースと2つのキーレス法定通貨ソースにより、minSources: 2の条件を初期状態で満たせます。
キーレスアクセスは、再配布の許可を意味するものではありません。CoinPaprikaとExchangeRate-APIは、パブリックまたは商用インスタンスによる再配布を制限しています。これらのレートを外部へ提供する前に、各ソースの利用規約および再配布に関するドキュメントを確認してください。
レート計算とAPIの正確性
tickersインデックスは日付順({ base: 1, date: -1 }、{ quote: 1, date: -1 }、{ base: 1, quote: 1, date: -1 })になったため、/getHistoryのソートはインメモリでのブロッキングなしにインデックスから直接提供されます。2億3800万ドキュメントのコレクションで測定した結果、同一のペアおよび範囲クエリの処理時間は22.8秒から8ミリ秒に短縮されました。
過去のcoinフィルタは、ドキュメント化されているBASE/QUOTE順を使用するようになりました。4.1.xではペアフィルタが逆転していたため、coin=ADM/USDが何も一致しない状態でした。クライアント側で逆転の回避策を実装している環境では、それを削除する必要があります。
minSourcesは、リクエストされた期間に対して最新のソースに基づいて測定されるため、古いプロバイダーがソース数のゲートを満たすことはできなくなりました。有効な閾値はmin(minSources, coverage)となり、単一プロバイダーのペアを維持しつつ、起動時の警告で報告されます。
三角測量計算では、ゼロに丸められるクロスレートや有限ではない値は拒否されます。/getおよび/getHistoryのスキーマは.strict()になったため、未知のクエリパラメータは無視されず400エラーを返します。バリデーションエラーは500ではなく400を返すようになりました。
プロバイダーおよびクエリフィルタから受け入れるコインシンボルは、より広範なUnicode対応形式となったため、すべての保存済みペアがアドレス指定可能になりました(例:$CWIF)。一方で、base_coinsやmappingsの誤字脱字は起動時に失敗します。
/statusは、タイムスタンプ比較からの推論ではなく、実際の更新状態からupdatingを報告し、同時実行されるリフレッシュサイクルは重複せずスキップされます。
セキュリティ
Webhook URL、APIキー、パスフレーズは、ログ出力、ログファイル、および通知送信から削除(redact)されます。これにより、AxiosのエラーURLを通じてAPIキーがログに流出するという現実的な脆弱性が解消されました。
logsディレクトリは0o750、ログファイルは0o600で作成されます。これは、他のユーザーが所有するマウント済みボリュームが起動を妨げないようにするためのベストエフォートです。ログファイル名からコロンが削除され、一部のファイルシステムで開けなくなる問題が解消されました。
コンテナは特権を持たないnodeユーザーとして実行され、ランタイムイメージからnpm/pnpm/yarnが削除されました。apk upgradeによりビルド時にAlpineの更新が適用され、本番環境の依存関係にネイティブバインディングが含まれている場合はビルド時にエラーとなります。config.jsoncは意図的にイメージから除外されているため、レイヤーに資格情報が含まれることはありません。x-powered-byは無効化され、設定のバリデーションでは未知のキーや大文字小文字が一致しない値は拒否されます。
CIでTrivyスキャンが実行され、脆弱性ポリシーが文書化されています。multerとjs-yamlはoverridesで固定されており、pnpm auditおよびpnpm audit --prodでクリーンな結果が得られます。
プラットフォームと依存関係
Node.js >= 22.12.0が必須となり、pnpmはpackageManagerを通じて12.3.4に固定されています。NestJSは10から12へ、Mongooseは8から9へ、Zodは3から4へ、adamant-apiは2から3へ、chalkは4から6へアップグレードされました。ESLintはフラット設定を採用した10へ、TypeScriptは5から6へ、Jestは29から30へ、Prettierは3.9へそれぞれ更新されました。
pnpm-workspace.yamlには、pnpm run deps:setupが依存するインストールスクリプトの許可リストが含まれています。MongoDBの接続エラーは無視されずログに記録されるようになり、ブートストラップ失敗時はサニタイズされたメッセージとともに非ゼロで終了します。
配布
publish-docker.ymlは、リリースに基づいたマルチプラットフォーム公開をghcr.io/adamant-im/currencyinfoに対してlinux/amd64およびlinux/arm64向けに実行します。これにはOCIラベル、SBOM、およびビルド証明が含まれます。ジョブは、リリースタグがmasterの祖先でない限り続行を拒否し、latestタグは最新の非プレリリース版でのみ更新されます。
docker-ci.ymlは、プルリクエスト時に本番イメージをビルドし、同梱のconfig.default.jsoncに対してスモークテストを実行します。これにより、デフォルト設定で起動し、APIキーなしでレートを返すことが証明されます。また、OCIラベルの検証、イメージに設定やシークレットが含まれていないことの確認、およびコンテナが非rootで実行されることの確認が行われます。このジョブはプッシュを行いません。
docker-compose.prod.yamlは、ビルドではなく公開済みイメージをプルし、設定を読み取り専用でマウントし、mongo:8.0を固定します。開発用のComposeファイルは、MongoDBをすべてのインターフェースではなく127.0.0.1にバインドします。
docker pull ghcr.io/adamant-im/currencyinfo:4.2.0
ドキュメントとテスト
https://currencyinfo.docs.adamant.im にドキュメントサイトが公開されました。クイックスタート、インストール、アーキテクチャ、レート計算、履歴、通知、運用、セキュリティ、トラブルシューティング、アップグレードに加え、完全なRESTおよび設定リファレンス、さらに各レートソースごとのクォータ、識別子形式、障害モード、再配布条件を網羅しています。
LICENSE (GPL-3.0) が初めてファイルとして追加され、CONTRIBUTING.mdおよびAGENTS.mdも同梱されました。
テストスイートは3つのspecファイルから28に増加し、すべてのソースコネクタ、マージャーとその戦略、ソースマネージャー、設定読み込み、マイグレーションとスキーマバリデーション、ロガー、ノーティファイアー、両方のリクエストスキーマ、例外フィルタ、バリデーションパイプ、インターセプター、コントローラー、および共有ユーティリティをカバーしています。pnpm testで266のテストが実行されます。
破壊的変更
CryptoCompareとCoinGeckoの両方がAPIキーを必須とし、かつ4.1.2のテンプレートで両方が有効化されているため、標準の4.1.2 config.jsoncは4.2.0では起動しません。運用担当者はこれらを無効化するか資格情報を入力し、キーレスの代替ソースを追加してカバレッジを回復させ、prioritiesを更新する必要があります。日付順のtickersインデックスが3つ作成されるため、起動の遅延を防ぐために事前に帯域外で構築してください。Node.js 22.12以降が必須です。過去のcoinフィルタはBASE/QUOTE順となりました。4.1.xではペアフィルタが逆転していたため、クライアント側で回避策を実装している場合は削除してください。/getおよび/getHistoryのスキーマは.strict()となり、未知のクエリパラメータは無視されず400エラーを返し、バリデーションエラーも500ではなく400を返すようになりました。