Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules/
dist/
.env
__pycache__/
*.log
.DS_Store
*.test.js
*.test.ts
23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "coin-gekko-api",
"version": "1.0.0",
"description": "Coin Gekko API",
"main": "dist/index.js",
"scripts": {
"build": "tsc",
"test": "vitest",
"start": "node dist/index.js"
},
"keywords": ["crypto", "api", "gekko"],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "^16.11.6",
"typescript": "^4.4.4",
"vitest": "^0.25.3",
"axios-mock-adapter": "^1.20.0"
},
"dependencies": {
"axios": "^0.24.0"
}
}
79 changes: 79 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import axios from 'axios';

export interface CoinData {
id: string;
symbol: string;
name: string;
price: number;
marketCap: number;
}

export class CoinGekkoApi {
private baseUrl: string;

constructor(baseUrl: string = 'https://api.coingecko.com/api/v3') {
this.baseUrl = baseUrl;
}

/**
* Fetch coin data by ID
* @param coinId - The ID of the coin
* @returns Promise resolving to CoinData
*/
async getCoinById(coinId: string): Promise<CoinData> {
if (!coinId) {
throw new Error('Coin ID is required');
}

try {
const response = await axios.get(`${this.baseUrl}/coins/${coinId}`);
return {
id: response.data.id,
symbol: response.data.symbol,
name: response.data.name,
price: response.data.market_data.current_price.usd,
marketCap: response.data.market_data.market_cap.usd
};
} catch (error) {
if (axios.isAxiosError(error)) {
if (error.response?.status === 404) {
throw new Error(`Coin with ID ${coinId} not found`);
}
throw new Error(`API request failed: ${error.message}`);
}
throw error;
}
}

/**
* List top cryptocurrencies by market cap
* @param limit - Number of coins to retrieve (default 10)
* @returns Promise resolving to array of CoinData
*/
async getTopCoins(limit: number = 10): Promise<CoinData[]> {
if (limit < 1) {
throw new Error('Limit must be at least 1');
}

try {
const response = await axios.get(`${this.baseUrl}/coins/markets`, {
params: {
vs_currency: 'usd',
order: 'market_cap_desc',
per_page: limit,
page: 1
}
});

return response.data.map((coin: any) => ({
id: coin.id,
symbol: coin.symbol,
name: coin.name,
price: coin.current_price,
marketCap: coin.market_cap
}));
} catch (error) {
throw new Error(`Failed to fetch top coins: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
}
13 changes: 13 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}