Currencyinfo 4.2.0 reconstruye la capa de fuentes de tasas en torno a proveedores sin clave tras la desaparición de dos niveles gratuitos ascendentes, refuerza el tiempo de ejecución y el contenedor, e incluye un sitio de documentación y una suite de pruebas real.
Seguridad auditada por cryptofoundry.
Actualización desde la versión 4.1.2 o anterior
Los consumidores de la API no necesitan cambios: las estructuras de respuesta de /get, /getHistory y /status permanecen sin cambios. Son obligatorios dos pasos por parte del operador.
Un archivo config.jsonc estándar de la versión 4.1.2 no se iniciará en la 4.2.0. Tanto CryptoCompare como CoinGecko requieren ahora una clave de API, y ambos están habilitados en la plantilla de la 4.1.2, por lo que una configuración sin modificar fallará la validación antes de que se abra el puerto HTTP. Deshabilítelos o proporcione credenciales, añada los reemplazos sin clave para restaurar la cobertura y actualice las priorities.
Los índices de tickers han sido reconstruidos. Tres índices ordenados por fecha reemplazan a tres antiguos. Mongoose crea los nuevos al conectarse pero nunca elimina los antiguos, por lo que una actualización directa los construye todos al inicio y puede retrasar la disponibilidad. Constrúyalos primero fuera de banda.
Medido en dos despliegues de producción que contienen ~238 millones de documentos de ticker cada uno: en NVMe con 12 núcleos y 64 GB de RAM, la construcción de los tres índices tomó 17 minutos con un indexSize que creció de 9.1 a 19.3 GB; en SATA con 4 núcleos y 16 GB de RAM, la misma construcción tomó 50 minutos con un indexSize que creció de 8.7 a 18.9 GB.
Ahora se requiere Node.js 22.12 o superior. Es seguro volver a la versión 4.1.2: el diseño de los documentos almacenados no ha cambiado.
Fuentes de tasas
El conjunto de proveedores fue reelaborado después de que CryptoCompare retirara su nivel gratuito el 21 de mayo de 2026 y el plan sin clave de CoinGecko se volviera inutilizable. Hay cuatro conectores nuevos, y los cuatro son sin clave.
CoinPaprika realiza una llamada masiva clasificada por ciclo más un número limitado de llamadas por moneda para aquellas fuera del rango masivo. bulk_limit y max_individual_requests limitan el presupuesto de solicitudes, y las monedas fuera de rango se excluyen al inicio con una advertencia en lugar de agotar la cuota en cada ciclo.
CoinLore devuelve todo el conjunto de monedas en una única solicitud multi-ID. Los IDs numéricos de CoinLore se reasignan entre listados, por lo que una respuesta cuyo símbolo no coincida con el ID configurado se rechaza en tiempo de ejecución en lugar de ser aceptada.
Binance proporciona datos del mercado spot público desde un exchange en lugar de un agregador, lo que supone una independencia de fuente genuina respecto a los cuatro agregadores que comparten parcialmente datos ascendentes. Binance no tiene pares directos en USD, por lo que las tasas se solicitan contra un quote_asset configurable (USDT por defecto) y se sirven como USD; un desacoplamiento divide las tasas afectadas en su propio grupo de divergencia en lugar de quedar ocultas por un mapeo. El bloqueo geográfico HTTP 451 deshabilita el conector y alerta una vez en lugar de fallar en cada ciclo.
ExchangeRate-API proporciona tasas fiat sin clave para 166 monedas con actualizaciones diarias.
CryptoCompare está obsoleto y deshabilitado por defecto, eliminado de priorities y programado para su eliminación en la próxima versión mayor. Se requiere una clave de API cuando está habilitado. CoinGecko está deshabilitado por defecto y ahora requiere una clave Demo gratuita, ya que el plan público sin clave limita a 5–15 llamadas por minuto y las tasas de limitación son impredecibles.
Cinco fuentes están ahora habilitadas por defecto sin ninguna credencial, lo que hace que el archivo config.default.jsonc incluido sea una configuración funcional: tres fuentes cripto sin clave y dos fuentes fiat sin clave significan que minSources: 2 se satisface desde el primer momento.
El acceso sin clave no es lo mismo que el permiso para republicar. Tanto CoinPaprika como ExchangeRate-API restringen la redistribución por parte de una instancia pública o comercial. Lea los términos de la fuente y la documentación de redistribución antes de servir estas tasas a terceros.
Cálculo de tasas y exactitud de la API
Los índices de tickers están ordenados por fecha ({ base: 1, date: -1 }, { quote: 1, date: -1 }, { base: 1, quote: 1, date: -1 }), por lo que las ordenaciones de /getHistory son proporcionadas por el índice en lugar de bloquear ordenaciones en memoria. Medido en una colección de 238 millones de documentos, la misma consulta de par y rango pasó de 22.8 s a 8 ms.
Los filtros históricos de coin ahora utilizan el orden documentado BASE/QUOTE. En la versión 4.1.x el filtro de par estaba invertido, por lo que coin=ADM/USD no coincidía con nada. Los despliegues que utilicen una solución alternativa de inversión en el lado del cliente deben eliminarla.
minSources se mide frente a fuentes que están actualizadas para el tiempo de vida solicitado, por lo que un proveedor obsoleto ya no puede satisfacer el umbral de conteo de fuentes. El umbral efectivo es min(minSources, coverage), lo que mantiene un par de proveedor único servido mientras se reporta en la advertencia de inicio.
La triangulación rechaza tasas cruzadas que se redondean a cero o resultan no finitas. Los esquemas de /get y /getHistory son .strict(), por lo que un parámetro de consulta desconocido genera un 400 en lugar de ser ignorado silenciosamente. Los errores de validación ahora devuelven 400 en lugar de 500.
Los símbolos de monedas aceptados de los proveedores y de los filtros de consulta tienen una forma más amplia compatible con Unicode, por lo que cada par almacenado es direccionable — $CWIF es un ejemplo real — mientras que los errores tipográficos en base_coins y mappings siguen fallando al inicio.
/status reporta updating a partir del estado de actualización real en lugar de inferirlo de una comparación de marcas de tiempo, y los ciclos de actualización concurrentes se omiten en lugar de solaparse.
Seguridad
Las URLs de Webhook, las claves de API y las frases de contraseña se redactan de la salida de registros, archivos de registro y envío de notificaciones. Esto cierra una fuga real: una respuesta de error ascendente colocaba una clave de API en el registro a través de la URL de error de Axios.
El directorio logs se crea con permisos 0o750 y los archivos de registro con 0o600, como mejor esfuerzo para que un volumen montado propiedad de otro usuario nunca bloquee el inicio. Los nombres de los archivos de registro ya no contienen dos puntos, lo que los hacía imposibles de abrir en algunos sistemas de archivos.
El contenedor se ejecuta como el usuario no privilegiado node, npm/pnpm/yarn se eliminan de la imagen de tiempo de ejecución, apk upgrade aplica las actualizaciones pendientes de Alpine en el momento de la construcción, y un protector en tiempo de construcción falla la compilación si una dependencia de producción incluye un enlace nativo. config.jsonc está deliberadamente ausente de la imagen, por lo que ninguna capa puede contener una credencial. x-powered-by está deshabilitado, y la validación de configuración rechaza claves desconocidas y valores con discrepancias de mayúsculas y minúsculas.
El escaneo con Trivy se ejecuta en CI, y la política de vulnerabilidades está documentada. multer y js-yaml están fijados a través de overrides, por lo que tanto pnpm audit como pnpm audit --prod resultan limpios.
Plataforma y dependencias
Se requiere Node.js >= 22.12.0, con pnpm fijado en 12.3.4 mediante packageManager. NestJS se actualizó de 10 a 12, Mongoose de 8 a 9, Zod de 3 a 4, adamant-api de 2 a 3, y chalk de 4 a 6. ESLint se actualizó de 8 a 10 con configuración plana, TypeScript de 5 a 6, Jest de 29 a 30, y Prettier a 3.9.
pnpm-workspace.yaml contiene la lista de permitidos de scripts de instalación de la que depende pnpm run deps:setup. Los errores de conexión a MongoDB se registran en lugar de omitirse, y la ruta de fallo de arranque sale con un código distinto de cero y un mensaje saneado.
Distribución
publish-docker.yml realiza la publicación multiplataforma impulsada por la versión en ghcr.io/adamant-im/currencyinfo para linux/amd64 y linux/arm64, con etiquetas OCI, un SBOM y una atestación de procedencia de construcción. El trabajo se niega a continuar a menos que la etiqueta de versión sea un ancestro de master, y latest solo se mueve para la versión más reciente que no sea pre-lanzamiento.
docker-ci.yml construye la imagen de producción en las solicitudes de extracción y realiza pruebas de humo contra el config.default.jsonc incluido, demostrando que la configuración por defecto se inicia y devuelve tasas sin necesidad de una clave de API. Verifica las etiquetas OCI, confirma que la imagen no contiene configuración ni secretos, y confirma que el contenedor se ejecuta como no root. Nunca realiza push.
docker-compose.prod.yaml extrae la imagen publicada en lugar de construirla, monta la configuración como de solo lectura y fija mongo:8.0. El archivo Compose de desarrollo vincula MongoDB a 127.0.0.1 en lugar de a todas las interfaces.
docker pull ghcr.io/adamant-im/currencyinfo:4.2.0
Documentación y pruebas
Un sitio de documentación está disponible en https://currencyinfo.docs.adamant.im que cubre inicio rápido, instalación, arquitectura, cálculo de tasas, historial, notificaciones, operaciones, seguridad, solución de problemas, actualización, además de una referencia completa de REST y configuración y una página por fuente de tasa que documenta cuota, forma de identificador, modo de fallo y términos de redistribución.
LICENSE (GPL-3.0) se añadió como archivo por primera vez, junto con CONTRIBUTING.md y AGENTS.md.
La suite de pruebas creció de 3 archivos spec a 28, cubriendo cada conector de fuente, el fusionador y sus estrategias, el gestor de fuentes, carga de configuración, validación de migración y esquema, el registrador, el notificador, ambos esquemas de solicitud, el filtro de excepciones, la tubería de validación, el interceptor, el controlador y las utilidades compartidas. pnpm test ejecuta 266 pruebas.
Cambios importantes
Un archivo config.jsonc estándar de la versión 4.1.2 no se inicia en la 4.2.0 porque CryptoCompare y CoinGecko requieren ahora una clave de API y ambos están habilitados en la plantilla de la 4.1.2. Los operadores deben deshabilitarlos o proporcionar credenciales, añadir los reemplazos sin clave para restaurar la cobertura y actualizar las priorities. Tres índices de tickers ordenados por fecha reemplazan a tres antiguos; Mongoose crea los nuevos al conectarse pero nunca elimina los antiguos, por lo que deben construirse primero fuera de banda para evitar retrasos en la disponibilidad. Se requiere Node.js 22.12 o superior. Los filtros históricos de coin ahora utilizan el orden documentado BASE/QUOTE; en la versión 4.1.x el filtro de par estaba invertido, por lo que los despliegues que utilicen una solución alternativa de inversión en el lado del cliente deben eliminarla. Los esquemas de /get y /getHistory son .strict(), por lo que un parámetro de consulta desconocido ahora devuelve 400 en lugar de ser ignorado silenciosamente, y los errores de validación devuelven 400 en lugar de 500.