npm package: @makebelieve21213-packages/coinmarketcap-client
Description: CoinMarketCap API client for NestJS with TypeScript support
Author: Skryabin Aleksey
Latest version: 1.0.0

# @packages/coinmarketcap-client

CoinMarketCap API клиент для NestJS с поддержкой TypeScript и полной типобезопасностью.

## 📋 Содержание

- [Возможности](#-возможности)
- [Требования](#-требования)
- [Установка](#-установка)
- [Структура пакета](#-структура-пакета)
- [Быстрый старт](#-быстрый-старт)
- [API Reference](#-api-reference)
- [Примеры использования](#-примеры-использования)
- [Troubleshooting](#-troubleshooting)
- [Тестирование](#-тестирование)

## 🚀 Возможности

- ✅ **NestJS интеграция** - глобальный модуль с forRootAsync для простой интеграции
- ✅ **Type-safe API** - полная типобезопасность TypeScript с экспортируемыми типами
- ✅ **HTTP клиент** - использование нативного fetch API с поддержкой таймаутов
- ✅ **Конфигурация** - поддержка API ключа через ConfigModule (обязательно)
- ✅ **Трансформация данных** - автоматическое преобразование snake_case → camelCase
- ✅ **Обработка ошибок** - детальная обработка ошибок API с логированием
- ✅ **100% покрытие тестами** - надежность и качество кода

## 📋 Требования

- **Node.js**: >= 22.11.0
- **NestJS**: >= 11.0.0

## 📦 Установка

```bash
npm install @packages/coinmarketcap-client
```

### Зависимости

```json
{
  "@nestjs/common": "^11.0.0",
  "@nestjs/config": "^11.0.0",
  "@makebelieve21213-packages/logger": "^1.0.0",
  "reflect-metadata": "^0.1.13 || ^0.2.0"
}
```

## 📁 Структура пакета

```
src/
├── main/                    # NestJS модуль
├── types/                   # TypeScript типы
├── utils/                   # Утилиты
└── index.ts                 # Экспорты
```

## 🏗️ Архитектура

Пакет предоставляет NestJS глобальный модуль `CoinMarketCapModule` для работы с CoinMarketCap API через HTTP запросы.

**Основные компоненты:**
- `CoinMarketCapModule` - NestJS глобальный модуль
- `CoinMarketCapService` - сервис для работы с API
- `CoinMarketCapModuleOptions` - конфигурация клиента
- Типы: `CMCAsset`, `CMCCoinInfo`, `CMCGlobalMetrics`, `CMCDominance`

## 🔧 Быстрый старт

### Шаг 1: Настройка переменных окружения

```env
COINMARKETCAP_API_KEY=your-api-key-here
COINMARKETCAP_BASE_URL=https://pro-api.coinmarketcap.com/v1  # Опционально
COINMARKETCAP_TIMEOUT=30000  # Опционально
```

### Шаг 2: Создание конфигурации

Создайте файл `coinmarketcap.config.ts` в вашем сервисе:

```typescript
import { registerAs } from "@nestjs/config";
import type { CoinMarketCapModuleOptions } from "@packages/coinmarketcap-client";
import { EnvVariable } from "src/types/enums";

export type CoinMarketCapConfiguration = CoinMarketCapModuleOptions;

const coinmarketcapConfig = registerAs<CoinMarketCapConfiguration>(
  "coinmarketcap",
  (): CoinMarketCapConfiguration => {
    const apiKey = process.env[EnvVariable.COINMARKETCAP_API_KEY];
    
    if (!apiKey) {
      throw new Error("COINMARKETCAP_API_KEY is required");
    }
    
    return {
      apiKey,
      baseUrl: process.env[EnvVariable.COINMARKETCAP_BASE_URL] || "https://pro-api.coinmarketcap.com/v1",
      timeout: Number(process.env[EnvVariable.COINMARKETCAP_TIMEOUT]) || 30000,
    };
  },
);

export default coinmarketcapConfig;
```

### Шаг 3: Регистрация модуля

```typescript
// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { CoinMarketCapModule } from '@packages/coinmarketcap-client';
import coinmarketcapConfig from 'src/configs/coinmarketcap.config';
import type { CoinMarketCapConfiguration } from 'src/configs/coinmarketcap.config';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [coinmarketcapConfig],
    }),
    CoinMarketCapModule.forRootAsync<[CoinMarketCapConfiguration]>({
      useFactory: (config: CoinMarketCapConfiguration) => config,
      inject: [coinmarketcapConfig.KEY],
      imports: [ConfigModule],
    }),
  ],
})
export class AppModule {}
```

### Шаг 4: Использование сервиса

```typescript
// crypto-data.service.ts
import { Injectable } from '@nestjs/common';
import { CoinMarketCapService } from '@packages/coinmarketcap-client';
import type { CMCAsset } from '@packages/coinmarketcap-client';

@Injectable()
export class CryptoDataService {
  constructor(private readonly coinmarketcap: CoinMarketCapService) {}

  async getTopCryptoAssets(limit: number = 100): Promise<CMCAsset[]> {
    return await this.coinmarketcap.getTopAssets(limit);
  }
}
```

## 📚 API Reference

### CoinMarketCapModule

**forRootAsync(options):**

```typescript
CoinMarketCapModule.forRootAsync<[CoinMarketCapConfiguration]>({
  useFactory: (config: CoinMarketCapConfiguration) => config,
  inject: [coinmarketcapConfig.KEY],
  imports: [ConfigModule],
})
```

**Экспортирует:** `CoinMarketCapService` (глобально)

### CoinMarketCapService

**Конфигурация:**
- `apiKey: string` - API ключ (обязательно)
- `baseUrl?: string` - базовый URL (по умолчанию: https://pro-api.coinmarketcap.com/v1)
- `timeout?: number` - таймаут запросов в мс (по умолчанию: 30000)

**Методы:**

#### `getTopAssets(limit?)`

Получает список топ криптовалютных активов с ограничением по количеству. Автоматически преобразует данные из snake_case в camelCase.

```typescript
async getTopAssets(limit?: number): Promise<CMCAsset[]>
```

**Параметры:**
- `limit` - количество активов для получения (по умолчанию: 100)

**Возвращает:** Массив активов в формате camelCase

#### `getCoinInfo(symbol)`

Получает детальную информацию о криптовалюте по её символу.

```typescript
async getCoinInfo(symbol: string): Promise<CMCCoinInfo>
```

**Параметры:**
- `symbol` - символ криптовалюты (например, "BTC", "ETH")

**Возвращает:** Детальную информацию о монете

#### `getGlobalMetrics()`

Получает глобальные метрики криптовалютного рынка включая общую капитализацию и доминацию.

```typescript
async getGlobalMetrics(): Promise<CMCGlobalMetrics>
```

**Возвращает:** Глобальные метрики рынка

#### `getDominance()`

Получает данные о доминации BTC и ETH на рынке криптовалют.

```typescript
async getDominance(): Promise<CMCDominance>
```

**Возвращает:** Данные о доминации BTC/ETH

## 🧪 Примеры использования

### Получение топ криптовалют

```typescript
const topAssets = await this.coinmarketcap.getTopAssets(50);
topAssets.forEach(asset => {
  console.log(`${asset.name} (${asset.symbol}): $${asset.quote?.USD?.price}`);
});
```

### Получение информации о монете

```typescript
const btcInfo = await this.coinmarketcap.getCoinInfo('BTC');
console.log(`Name: ${btcInfo.name}`);
console.log(`Description: ${btcInfo.description}`);
console.log(`Website: ${btcInfo.website?.join(', ')}`);
```

### Получение глобальных метрик

```typescript
const metrics = await this.coinmarketcap.getGlobalMetrics();
console.log(`Total Market Cap: $${metrics.data.quote?.USD?.totalMarketCap}`);
console.log(`BTC Dominance: ${metrics.data.btcDominance}%`);
console.log(`ETH Dominance: ${metrics.data.ethDominance}%`);
```

### Получение доминации BTC/ETH

```typescript
const dominance = await this.coinmarketcap.getDominance();
console.log(`BTC Dominance: ${dominance.data.btcDominance}%`);
console.log(`ETH Dominance: ${dominance.data.ethDominance}%`);
```

## 🚨 Troubleshooting

### API key не найден

**Проблема:** `COINMARKETCAP_API_KEY is required` или `apiKey is required`

**Решение:**
1. Проверить, что переменная окружения `COINMARKETCAP_API_KEY` установлена в `.env` файле
2. Убедиться, что ConfigModule загружает локальный конфиг из `src/configs/coinmarketcap.config.ts`
3. Проверить, что `coinmarketcapConfig.KEY` используется в `inject` при инициализации модуля

### Request timeout

**Проблема:** Запрос к CoinMarketCap API превышает таймаут

**Решение:**
1. Увеличить `COINMARKETCAP_TIMEOUT` в переменных окружения
2. Проверить скорость интернет-соединения
3. Проверить доступность API CoinMarketCap

### Coin not found

**Проблема:** Монета не найдена по символу

**Решение:**
1. Проверить правильность написания символа (должен быть в верхнем регистре)
2. Убедиться, что символ существует в CoinMarketCap
3. Проверить, что API ключ имеет доступ к данному эндпоинту

## 🧪 Тестирование

Пакет имеет **100% покрытие тестами**.

```bash
pnpm test                # Все тесты
pnpm test:coverage       # С покрытием
pnpm test:watch          # Watch режим
```

## 🔧 Конфигурация

```typescript
interface CoinMarketCapModuleOptions {
  apiKey: string;          // API ключ (обязательно)
  baseUrl?: string;        // Базовый URL (опционально)
  timeout?: number;        // Таймаут в мс (опционально)
}
```

**Примечание:** Конфигурация должна создаваться в сервисе, который использует пакет.

## 📦 Зависимости

- `@nestjs/common` - NestJS core
- `@nestjs/config` - NestJS config
- `@makebelieve21213-packages/logger` - Логирование
- `reflect-metadata` - TypeScript decorators

## 📄 Лицензия

UNLICENSED (private package)

## 👥 Автор

Skryabin Aleksey