
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the projectβs GitHub releases.
trade360-nodejs-sdk
Advanced tools
Description:
The Trade360 Node.js SDK is a comprehensive TypeScript library designed to simplify integration with LSports Trade360 services. This SDK provides a unified interface for connecting to the Trade360 real-time message feed (via RabbitMQ), interacting with the Snapshot API for data recovery, and managing customer subscriptions and metadata through the Customers API.
Role in STM Ecosystem:
The SDK serves as the primary integration layer for Node.js/TypeScript applications in the Trade360 ecosystem, enabling developers to:
Technologies & Frameworks:
Core Dependencies:
Infrastructure:
The SDK processes data through three main pathways:
Feed Consumption: Connects to RabbitMQ message queues, consumes real-time updates (fixtures, livescores, markets, settlements), validates messages, and dispatches them to registered entity handlers. Supports automatic reconnection and distribution management.
Snapshot API: Provides HTTP-based data retrieval for recovery scenarios. Allows querying fixtures, markets, livescores, and settlements by various filters (sport, location, league, fixture IDs) with support for both in-play and pre-match contexts.
Customers API: Manages subscriptions (start/stop distribution, subscribe/unsubscribe to fixtures or leagues), retrieves metadata (sports, leagues, locations, markets, translations, venues, cities, states, participants), and handles manual suspensions.
Data flows from Trade360 services β SDK clients β application handlers β business logic, with comprehensive error handling, validation, and transformation at each layer.
The SDK is structured in a layered architecture with clear separation of concerns:
graph TB
App[Application Layer] --> Feed[Feed Module]
App --> Snapshot[Snapshot API Module]
App --> Customers[Customers API Module]
Feed --> MQFeed[RabbitMQ Feed Implementation]
MQFeed --> MessageConsumer[Message Consumer]
MessageConsumer --> Handlers[Entity Handlers]
Snapshot --> BaseHttpClient[Base HTTP Client]
Customers --> BaseHttpClient
BaseHttpClient --> AxiosService[Axios Service]
Feed --> Mapper[Mapper/Transformer]
Snapshot --> Mapper
Customers --> Mapper
Mapper --> Entities[Core Entities]
MessageConsumer --> Entities
BaseHttpClient --> Entities
Entities --> Errors[Error Handling]
BaseHttpClient --> Errors
MessageConsumer --> Errors
Main Directories:
/src/api - REST API clients (Customers, Snapshot, Base HTTP client)/src/feed - Message queue feed implementation (RabbitMQ integration)/src/entities - Core domain entities, enums, and message types/src/utilities - Helper utilities (retry, transformation, distribution)/src/logger - Logging interface and adapters/sample - Example implementations for each SDK feature/test - Unit and integration testsDesign Principles:
CustomersApiFactory, SnapshotApiFactory) create client instances with proper configurationILogger interfaceKey Design Decisions:
BaseError for domain-specific error contextsgraph TD
Client[Client Application] --> Factory[API Factory]
Factory --> HttpClient[HTTP Client]
HttpClient --> Validator[Request Validator]
Validator --> Service[HTTP Service/Axios]
Service --> API[Trade360 API]
API --> Service
Service --> Transformer[Response Transformer]
Transformer --> Entity[Domain Entity]
Entity --> Client
HttpClient --> ErrorHandler[Error Handler]
ErrorHandler --> CustomError[Custom Error]
CustomError --> Client
/src/api - API Clientsbase-http-client/ - Abstract base class for HTTP clients with request/response handling, error management, and authenticationcustomers-api/ - Clients for Customers API services:
services/metadata.service.ts - Metadata endpoints (sports, leagues, locations, markets, translations, venues, cities, states, participants)services/subscription.service.ts - Subscription management (subscribe/unsubscribe, manual suspensions, schedule retrieval)services/distribution.service.ts - Package distribution control (start/stop, status checks)snapshot-api/ - Snapshot API clients for in-play and pre-match contextscommon/ - Shared components (mappers, DTOs, request/response structures, validation schemas)/src/feed - Message Queue Feedfeed.ts - Main feed class managing lifecycle and distributionmq-feed/rabbitmq-feed.ts - RabbitMQ connection and channel management with automatic reconnectionmq-feed/message-consumer/ - Message consumption, validation, and entity handler dispatchvalidators/ - MQ settings validation using Zod schemas/src/entities - Domain Entitiescore-entities/ - Domain models:
fixture/ - Fixture entities with venue informationlivescore/ - Live score updates and clock statusmarket/ - Market types and bet statusesoutright-sport/ - Outright sport participants and fixturesoutright-league/ - Outright league tournamentscommon/ - Shared entities (subscription, ID/name records)enums/ - Enumeration types (status, types, classifications)message-types/ - Message type definitions for feed updateserrors/ - Custom error classes hierarchymessage-wrappers/ - Message headers and transport wrappers/src/utilities - Helper Utilitiesretry-util.ts - Retry logic with exponential backoffid-transformer-util.ts - ID transformation between external and internal formatstransformer-util.ts - Generic transformation utilitiesdistribution-util.ts - Distribution status management utilitiesasync-lock.ts - Async lock mechanism for concurrency controlid-safe-json-parser.ts - JSON parsing with large number ID safety/src/logger - Logginginterfaces/logger.interface.ts - Logger interface definitionadapters/ - Logger implementations (Console, Pino, Winston, Bunyan)enums/log-level.ts - Log level enumerationsReal-time Feed Consumption
Snapshot API Integration
Customers API Services
Comprehensive Error Handling
Type Safety & Validation
Flexible Logging
ID Transformation
Retry & Recovery
sequenceDiagram
participant RMQ as RabbitMQ
participant Feed as Feed Instance
participant Consumer as MessageConsumer
participant Validator as Message Validator
participant Transformer as Entity Transformer
participant Handler as Entity Handler
RMQ->>Feed: Connection established
Feed->>RMQ: Subscribe to queue
RMQ->>Consumer: Deliver message
Consumer->>Validator: Validate message structure
Validator->>Transformer: Transform to entity
Transformer->>Handler: Dispatch to registered handler
Handler->>Application: Process entity update
sequenceDiagram
participant Client as Client Application
participant Factory as API Factory
participant HttpClient as HTTP Client
participant Validator as Request Validator
participant Service as HTTP Service
participant API as Trade360 API
Client->>Factory: Create API client
Factory->>HttpClient: Initialize with config
Client->>HttpClient: Execute request method
HttpClient->>Validator: Validate request DTO
Validator->>HttpClient: Validation passed
HttpClient->>Service: Send HTTP request
Service->>API: POST/GET with auth
API->>Service: Return response
Service->>HttpClient: Raw response
HttpClient->>Transformer: Transform response
Transformer->>HttpClient: Domain entity
HttpClient->>Client: Return entity
sequenceDiagram
participant App as Application
participant Feed as Feed Instance
participant DistUtil as Distribution Util
participant API as Customers API
App->>Feed: Start feed (preConnectionAtStart=true)
Feed->>DistUtil: Check distribution status
DistUtil->>API: GET distribution status
API->>DistUtil: Status response
DistUtil->>Feed: Status result
alt Distribution is OFF
Feed->>DistUtil: Start distribution
DistUtil->>API: POST start distribution
API->>DistUtil: Success
DistUtil->>Feed: Distribution started
end
Feed->>RMQ: Connect and consume
@typescript-eslint/*) - Type checking and compilation@api, @feed, @entities, @logger, @utilities)Before using the SDK, ensure you have:
npm install trade360-sdk
If using TypeScript, install type definitions:
npm install --save-dev @types/node
git clone https://github.com/lsportsltd/trade360-nodejs-sdk.git
cd trade360-nodejs-sdk
npm install
npm run build
Create a configuration file (JSON or TypeScript) with your Trade360 credentials:
// Example: app-config.json
{
"trade360": {
"inPlayMQSettings": {
"hostname": "stm-inplay.lsports.eu",
"port": 5672,
"vhost": "StmInPlay",
"username": "your-username",
"password": "your-password",
"packageId": 430,
"prefetchCount": 100,
"networkRecoveryIntervalInMs": 5000,
"maxRetryAttempts": 3000,
"automaticRecoveryEnabled": true,
"autoAck": true,
"consumptionLatencyThreshold": 5,
"customersApiBaseUrl": "https://stm-api.lsports.eu/",
"PACKAGE_FORMAT_TYPE": "1",
"requestedHeartbeatSeconds": 30,
"dispatchConsumersAsync": true
},
"preMatchMQSettings": {
// Similar configuration for pre-match
},
"restApiBaseUrl": "https://stm-api.lsports.eu/",
"snapshotApiBaseUrl": "https://stm-snapshot.lsports.eu/"
}
}
npm run build
Explore the /sample directory for working examples:
feed-sample/ - Feed consumption examplessnapshot-api-sample/ - Snapshot API usagecustomer-api-sample/ - Customers API integrationThe SDK uses Azure DevOps pipelines for continuous integration and deployment (configured in ci.yml):
Stages:
main branch after successful build, publishes to npmjs.org registryConfiguration:
trade360_nodejs_sdkThe package is automatically published to NPM when:
main branchPackage Details:
https://registry.npmjs.org/dist/, README.md, CHANGELOG.mdVersion numbers follow Semantic Versioning (SemVer):
See CHANGELOG.md for detailed version history.
A Dockerfile is provided for containerized deployment. Build and run:
docker build -t trade360-nodejs-sdk .
docker run trade360-nodejs-sdk
Tests are organized in the /test directory mirroring the /src structure:
/test/api - API client tests/test/entities - Entity and enum tests/test/utilities - Utility function testsRun all tests:
npm test
Run tests with coverage:
npm run test:cov
Coverage reports are generated in the coverage/ directory:
coverage/lcov-report/index.htmlcoverage/lcov.infoConfigured in jest.config.js:
**/?(*.)+(spec|test).[tj]s?(x)The test suite includes:
Configure a logger adapter. Note that log level is typically configured through the adapter's constructor options, not via a setLogLevel() method:
import { ConsoleAdapter } from 'trade360-sdk';
const logger = new ConsoleAdapter();
// Log level is controlled by the adapter implementation
// For custom adapters, configure log level in the adapter constructor
For feed connections, monitor RabbitMQ connection status:
feed.start(true); // preConnectionAtStart enables distribution check
Use the validation utilities to check configuration:
import { MqConnectionSettingsValidator } from 'trade360-sdk';
try {
const validated = MqConnectionSettingsValidator.validate(mqSettings);
} catch (error) {
console.error('Configuration validation failed:', error);
}
Check error context for detailed information:
try {
await apiClient.getFixtures(request);
} catch (error) {
if (error instanceof HttpResponseError) {
console.error('HTTP Error:', error.message);
console.error('Context:', error.context);
} else if (error instanceof ValidationError) {
console.error('Validation Error:', error.context);
}
}
Enable message logging in feed handlers:
import { IEntityHandler, IMessageStructure } from 'trade360-sdk';
class MyHandler implements IEntityHandler<FixtureMetadataUpdate> {
async processAsync({ header, entity, transportHeaders }: IMessageStructure<FixtureMetadataUpdate>) {
// Important: Entities are wrapped in metadata update classes with events[] arrays, not direct access
if (entity?.events) {
entity.events.forEach((event) => {
logger.debug('Received fixture event:', JSON.stringify(event, null, 2));
// Process event (not entity directly)
});
}
}
}
feed.addEntityHandler(new MyHandler(), FixtureMetadataUpdate);
id-safe-json-parser to handle these cases.The SDK provides a flexible logging system:
Supported Loggers:
Log Levels:
Usage:
import { ConsoleAdapter, PinoAdapter } from 'trade360-sdk';
const logger = new PinoAdapter(); // or ConsoleAdapter(), WinstonAdapter(), BunyanAdapter()
feed.setLogger(logger);
Distribution Status:
Check if distribution is active:
import { DistributionUtil } from 'trade360-sdk';
const status = await DistributionUtil.checkStatus();
if (status?.isDistributionOn) {
console.log('Distribution is active');
}
Connection Monitoring:
Monitor RabbitMQ connection status through feed events and logger output.
Event Listeners:
Event listeners should be attached to feed.consumerMq, not feed directly:
const feed = new Feed(mqSettings, logger);
// Event listeners are on feed.consumerMq, not feed.on()
// Note: The underlying RabbitMQFeed manages connection events internally
// Connection events (error, close) are handled automatically by the SDK
The SDK logs key operations:
Configure application-level metrics collection to aggregate SDK logs.
Configure different settings for Development, QA, and Production environments:
Development:
{
"trade360": {
"restApiBaseUrl": "https://stm-api-dev.lsports.eu/",
"snapshotApiBaseUrl": "https://stm-snapshot-dev.lsports.eu/",
"inPlayMQSettings": {
"hostname": "dev-inplay.lsports.eu",
// ... other settings
}
}
}
Production:
{
"trade360": {
"restApiBaseUrl": "https://stm-api.lsports.eu/",
"snapshotApiBaseUrl": "https://stm-snapshot.lsports.eu/",
"inPlayMQSettings": {
"hostname": "stm-inplay.lsports.eu",
// ... other settings
}
}
}
MQ Settings:
hostname - RabbitMQ server hostnameport - RabbitMQ server port (default: 5672)vhost - Virtual host nameusername / password - Authentication credentialspackageId - Trade360 package identifierprefetchCount - Number of unacknowledged messages (default: 100)networkRecoveryIntervalInMs - Reconnection interval (default: 5000)maxRetryAttempts - Maximum retry attempts (default: 3000)automaticRecoveryEnabled - Enable automatic reconnection (default: true)autoAck - Auto-acknowledge messages (default: true)consumptionLatencyThreshold - Latency threshold in seconds (default: 5)requestedHeartbeatSeconds - Heartbeat interval (default: 30)dispatchConsumersAsync - Async message dispatch (default: true)PACKAGE_FORMAT_TYPE - Package format type ("1" for in-play, "2" for pre-match)customersApiBaseUrl - Required Customers API base URL (e.g., "https://stm-api.lsports.eu/"). This field is required for all MQ settings and is used by the SDK for distribution management operations.HTTP Client Settings:
restApiBaseUrl - Customers API base URLsnapshotApiBaseUrl - Snapshot API base URL (for snapshot client)timeout - Request timeout in millisecondsretryConfig - Retry configuration (optional)Code Standards:
npm run lint before committingnpm run lint:fix)Testing Requirements:
npm test before submitting PRDocumentation:
Pull Request Process:
mainVersion Management:
package.jsonCHANGELOG.mdgraph TD
Developer[Developer] --> SDK[Trade360 Node.js SDK]
SDK --> FeedModule[Feed Module]
SDK --> SnapshotModule[Snapshot API Module]
SDK --> CustomersModule[Customers API Module]
FeedModule --> RabbitMQ[(RabbitMQ<br/>Message Queue)]
SnapshotModule --> SnapshotAPI[Snapshot REST API]
CustomersModule --> CustomersAPI[Customers REST API]
RabbitMQ --> |Real-time Updates| FeedModule
FeedModule --> |Entity Updates| Developer
SnapshotAPI --> |Recovery Data| SnapshotModule
SnapshotModule --> |Entities| Developer
CustomersAPI --> |Metadata/Subscriptions| CustomersModule
CustomersModule --> |Entities| Developer
SDK --> Logger[Logger Adapter]
SDK --> Utils[Utilities]
Logger --> Console[Console Logs]
Logger --> File[File Logs]
Logger --> External[External Logging Service]
CHANGELOG.md for version historyThis SDK is licensed under the ISC License.
For issues, questions, or contributions, please:
/sample directoryFAQs
LSports Trade360 SDK for Node.js
The npm package trade360-nodejs-sdk receives a total of 424 weekly downloads. As such, trade360-nodejs-sdk popularity was classified as not popular.
We found that trade360-nodejs-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the projectβs GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.