coingecko-pro 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +431 -0
- package/dist/index.cjs +2266 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +4308 -0
- package/dist/index.d.ts +4308 -0
- package/dist/index.js +2254 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 0xJesus
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<h1 align="center">coingecko-pro</h1>
|
|
3
|
+
<p align="center">The most comprehensive CoinGecko API SDK for JavaScript & TypeScript</p>
|
|
4
|
+
</p>
|
|
5
|
+
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="https://www.npmjs.com/package/coingecko-pro"><img src="https://img.shields.io/npm/v/coingecko-pro.svg" alt="npm version"></a>
|
|
8
|
+
<a href="https://www.npmjs.com/package/coingecko-pro"><img src="https://img.shields.io/npm/dm/coingecko-pro.svg" alt="npm downloads"></a>
|
|
9
|
+
<a href="https://github.com/0xJesus/coingecko-pro/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/coingecko-pro.svg" alt="license"></a>
|
|
10
|
+
<img src="https://img.shields.io/badge/TypeScript-first-blue.svg" alt="TypeScript">
|
|
11
|
+
<img src="https://img.shields.io/badge/dependencies-0-brightgreen.svg" alt="zero dependencies">
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Full coverage of the **CoinGecko Pro API** and **On-chain DEX data (GeckoTerminal)** in a single, typed SDK. One import, every endpoint.
|
|
17
|
+
|
|
18
|
+
## Features
|
|
19
|
+
|
|
20
|
+
- **86 endpoints** across 8 namespaces -- coins, exchanges, derivatives, NFTs, on-chain DEX, global, treasury, and meta
|
|
21
|
+
- **TypeScript-first** -- every request and response is fully typed, with JSDoc on every method
|
|
22
|
+
- **Zero runtime dependencies** -- uses the built-in `fetch` API (Node 18+, Bun, Deno, browsers)
|
|
23
|
+
- **In-memory TTL cache** -- deduplicates identical requests within a configurable window
|
|
24
|
+
- **Token-bucket rate limiter** -- automatically enforces CoinGecko rate limits (30/min free, 500/min Pro)
|
|
25
|
+
- **Exponential-backoff retry** -- retries on 429 and 503 with configurable attempts and delay
|
|
26
|
+
- **Request timeout** -- AbortController-based timeout with clean error reporting
|
|
27
|
+
- **Lifecycle hooks** -- `onRequest`, `onResponse`, `onError` for logging, metrics, and debugging
|
|
28
|
+
- **Dual format** -- ships ESM and CommonJS builds with full source maps and declaration files
|
|
29
|
+
- **Tree-shakeable** -- import only the endpoint classes you need for minimal bundle size
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install coingecko-pro
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pnpm add coingecko-pro
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
yarn add coingecko-pro
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Basic Usage
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { CoinGecko } from 'coingecko-pro';
|
|
51
|
+
|
|
52
|
+
// Pro tier (recommended)
|
|
53
|
+
const cg = new CoinGecko({ apiKey: 'CG-xxx' });
|
|
54
|
+
|
|
55
|
+
// Free tier (lower rate limits, some endpoints unavailable)
|
|
56
|
+
const cg = new CoinGecko();
|
|
57
|
+
|
|
58
|
+
// Check connectivity
|
|
59
|
+
const { gecko_says } = await cg.ping();
|
|
60
|
+
console.log(gecko_says); // "(V3) To the Moon!"
|
|
61
|
+
|
|
62
|
+
// Get Bitcoin market data
|
|
63
|
+
const btc = await cg.coins.getById('bitcoin');
|
|
64
|
+
console.log(btc.market_data.current_price.usd);
|
|
65
|
+
|
|
66
|
+
// Get top coins by market cap
|
|
67
|
+
const markets = await cg.coins.markets({ vs_currency: 'usd', per_page: 10 });
|
|
68
|
+
markets.forEach(coin => {
|
|
69
|
+
console.log(`${coin.name}: $${coin.current_price}`);
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Configuration
|
|
74
|
+
|
|
75
|
+
All options are optional. Sensible defaults are applied automatically.
|
|
76
|
+
|
|
77
|
+
| Option | Type | Default | Description |
|
|
78
|
+
|---|---|---|---|
|
|
79
|
+
| `apiKey` | `string` | -- | CoinGecko Pro API key. Switches base URL to `pro-api.coingecko.com` and sets the auth header. |
|
|
80
|
+
| `baseUrl` | `string` | auto | Override the base URL (useful for proxies or testing). |
|
|
81
|
+
| `cacheTtl` | `number` | `30000` | Default response cache TTL in milliseconds. Set to `0` to disable. |
|
|
82
|
+
| `maxRetries` | `number` | `3` | Maximum retry attempts for transient errors (429, 503). |
|
|
83
|
+
| `retryDelay` | `number` | `1000` | Base delay (ms) for the first retry. Uses exponential backoff: `retryDelay * 2^attempt`. |
|
|
84
|
+
| `rateLimit` | `number` | `500` (Pro) / `30` (Free) | Maximum requests per minute. |
|
|
85
|
+
| `timeout` | `number` | `15000` | Request timeout in milliseconds. |
|
|
86
|
+
| `onRequest` | `(url) => void` | -- | Hook called before every outgoing request. |
|
|
87
|
+
| `onResponse` | `(url, status, ms) => void` | -- | Hook called after every completed request. |
|
|
88
|
+
| `onError` | `(url, error) => void` | -- | Hook called when a request fails after all retries. |
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
const cg = new CoinGecko({
|
|
92
|
+
apiKey: process.env.CG_API_KEY,
|
|
93
|
+
cacheTtl: 60_000, // 1 minute cache
|
|
94
|
+
maxRetries: 5,
|
|
95
|
+
retryDelay: 2_000,
|
|
96
|
+
rateLimit: 500,
|
|
97
|
+
timeout: 30_000,
|
|
98
|
+
onRequest: (url) => console.log(`-> ${url}`),
|
|
99
|
+
onResponse: (url, status, ms) => console.log(`<- ${status} ${ms}ms`),
|
|
100
|
+
onError: (url, err) => console.error(`!! ${url}`, err.message),
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## API Reference
|
|
105
|
+
|
|
106
|
+
### Namespace Overview
|
|
107
|
+
|
|
108
|
+
| Namespace | Methods | Description |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| `cg.coins` | 23 | Prices, markets, charts, OHLC, supply, categories, contract lookups |
|
|
111
|
+
| `cg.exchanges` | 6 | Exchange listings, details, tickers, volume charts |
|
|
112
|
+
| `cg.derivatives` | 4 | Derivatives tickers and exchange data |
|
|
113
|
+
| `cg.nfts` | 7 | NFT collections, market data, charts, tickers |
|
|
114
|
+
| `cg.onchain` | 27 | On-chain DEX pools, tokens, trades, OHLCV, top traders/holders |
|
|
115
|
+
| `cg.global` | 8 | Global stats, search, trending, exchange rates, asset platforms |
|
|
116
|
+
| `cg.treasury` | 5 | Public treasury holdings, charts, transactions |
|
|
117
|
+
| `cg.ping()` | 1 | API connectivity check |
|
|
118
|
+
| `cg.apiUsage()` | 1 | API key usage stats (Pro only) |
|
|
119
|
+
|
|
120
|
+
### Coins
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// Simple price lookup
|
|
124
|
+
const prices = await cg.coins.price({
|
|
125
|
+
ids: 'bitcoin,ethereum',
|
|
126
|
+
vs_currencies: 'usd,eur',
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Token price by contract address
|
|
130
|
+
const tokenPrice = await cg.coins.tokenPrice('ethereum', {
|
|
131
|
+
contract_addresses: '0xdac17f958d2ee523a2206206994597c13d831ec7',
|
|
132
|
+
vs_currencies: 'usd',
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Market data with sorting and pagination
|
|
136
|
+
const markets = await cg.coins.markets({
|
|
137
|
+
vs_currency: 'usd',
|
|
138
|
+
order: 'market_cap_desc',
|
|
139
|
+
per_page: 100,
|
|
140
|
+
page: 1,
|
|
141
|
+
sparkline: true,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Full coin detail
|
|
145
|
+
const btc = await cg.coins.getById('bitcoin', {
|
|
146
|
+
localization: false,
|
|
147
|
+
tickers: false,
|
|
148
|
+
community_data: false,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Historical market chart
|
|
152
|
+
const chart = await cg.coins.marketChart('bitcoin', {
|
|
153
|
+
vs_currency: 'usd',
|
|
154
|
+
days: '30',
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// OHLC candlestick data
|
|
158
|
+
const ohlc = await cg.coins.ohlc('bitcoin', {
|
|
159
|
+
vs_currency: 'usd',
|
|
160
|
+
days: '14',
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Top gainers and losers
|
|
164
|
+
const movers = await cg.coins.topGainersLosers({ vs_currency: 'usd' });
|
|
165
|
+
|
|
166
|
+
// Categories
|
|
167
|
+
const categories = await cg.coins.categories({ order: 'market_cap_desc' });
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### On-chain DEX (GeckoTerminal)
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// Trending pools across all networks
|
|
174
|
+
const { data: trending } = await cg.onchain.trendingPools();
|
|
175
|
+
|
|
176
|
+
// Top pools on a specific DEX
|
|
177
|
+
const { data: uniPools } = await cg.onchain.topPoolsByDex('eth', 'uniswap_v3');
|
|
178
|
+
|
|
179
|
+
// Pool OHLCV candlestick data
|
|
180
|
+
const ohlcv = await cg.onchain.poolOhlcv(
|
|
181
|
+
'eth',
|
|
182
|
+
'0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640',
|
|
183
|
+
'hour',
|
|
184
|
+
{ aggregate: '4', limit: 200 },
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// Token info with security flags
|
|
188
|
+
const { data: tokenInfo } = await cg.onchain.tokenInfo(
|
|
189
|
+
'eth',
|
|
190
|
+
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
// Top traders (whale tracking) -- Pro only
|
|
194
|
+
const { data: whales } = await cg.onchain.topTraders(
|
|
195
|
+
'eth',
|
|
196
|
+
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
197
|
+
);
|
|
198
|
+
|
|
199
|
+
// Top holders -- Pro only
|
|
200
|
+
const { data: holders } = await cg.onchain.topHolders(
|
|
201
|
+
'eth',
|
|
202
|
+
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
// Search pools by name or address
|
|
206
|
+
const { data: results } = await cg.onchain.searchPools('PEPE', { network: 'eth' });
|
|
207
|
+
|
|
208
|
+
// Advanced pool filtering (megafilter) -- Pro only
|
|
209
|
+
const { data: filtered } = await cg.onchain.megafilter({
|
|
210
|
+
network: 'eth',
|
|
211
|
+
reserve_in_usd_gte: 100_000,
|
|
212
|
+
sort: 'h24_volume_usd',
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Treasury
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// Companies holding Bitcoin
|
|
220
|
+
const btcTreasury = await cg.treasury.companyHoldings('bitcoin');
|
|
221
|
+
console.log(btcTreasury.total_holdings, btcTreasury.total_value_usd);
|
|
222
|
+
|
|
223
|
+
// Entity details
|
|
224
|
+
const entity = await cg.treasury.entityHoldings('microstrategy');
|
|
225
|
+
|
|
226
|
+
// Holding chart over time
|
|
227
|
+
const chart = await cg.treasury.entityHoldingChart('microstrategy', 'bitcoin');
|
|
228
|
+
|
|
229
|
+
// Transaction history
|
|
230
|
+
const txs = await cg.treasury.entityTransactions('microstrategy');
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Global & Search
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
// Global crypto market data
|
|
237
|
+
const global = await cg.global.global();
|
|
238
|
+
console.log(global.data.total_market_cap.usd);
|
|
239
|
+
|
|
240
|
+
// DeFi market data
|
|
241
|
+
const defi = await cg.global.globalDefi();
|
|
242
|
+
|
|
243
|
+
// Search coins, exchanges, categories
|
|
244
|
+
const results = await cg.global.search('solana');
|
|
245
|
+
|
|
246
|
+
// Trending coins and NFTs
|
|
247
|
+
const trending = await cg.global.trending();
|
|
248
|
+
|
|
249
|
+
// BTC exchange rates
|
|
250
|
+
const rates = await cg.global.exchangeRates();
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Exchanges & Derivatives
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
// Top exchanges by trust score
|
|
257
|
+
const exchanges = await cg.exchanges.list({ per_page: 10 });
|
|
258
|
+
|
|
259
|
+
// Exchange tickers
|
|
260
|
+
const tickers = await cg.exchanges.tickers('binance', {
|
|
261
|
+
coin_ids: 'bitcoin',
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
// Derivatives tickers
|
|
265
|
+
const derivTickers = await cg.derivatives.tickers();
|
|
266
|
+
|
|
267
|
+
// Derivatives exchanges
|
|
268
|
+
const derivExchanges = await cg.derivatives.exchanges();
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### NFTs
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
// NFT collections list
|
|
275
|
+
const collections = await cg.nfts.list();
|
|
276
|
+
|
|
277
|
+
// Collection detail
|
|
278
|
+
const bayc = await cg.nfts.getById('bored-ape-yacht-club');
|
|
279
|
+
|
|
280
|
+
// NFT market chart -- Pro only
|
|
281
|
+
const nftChart = await cg.nfts.marketChart('bored-ape-yacht-club', { days: '30' });
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Pro vs Free API
|
|
285
|
+
|
|
286
|
+
CoinGecko offers both free and paid API tiers. This SDK works with both -- just pass your API key to unlock Pro features.
|
|
287
|
+
|
|
288
|
+
| Feature | Free | Pro (Analyst+) |
|
|
289
|
+
|---|---|---|
|
|
290
|
+
| Rate limit | 30 req/min | 500 req/min |
|
|
291
|
+
| Base URL | `api.coingecko.com` | `pro-api.coingecko.com` |
|
|
292
|
+
| Top gainers/losers | -- | Yes |
|
|
293
|
+
| OHLC range | -- | Yes |
|
|
294
|
+
| Supply charts | -- | Yes |
|
|
295
|
+
| NFT market charts | -- | Yes |
|
|
296
|
+
| On-chain megafilter | -- | Yes |
|
|
297
|
+
| On-chain top traders | -- | Yes |
|
|
298
|
+
| On-chain top holders | -- | Yes |
|
|
299
|
+
| Treasury data | -- | Yes |
|
|
300
|
+
| Global market cap chart | -- | Yes |
|
|
301
|
+
| API usage endpoint | -- | Yes |
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
// Free tier -- no API key needed
|
|
305
|
+
const cg = new CoinGecko();
|
|
306
|
+
|
|
307
|
+
// Pro tier -- pass your API key
|
|
308
|
+
const cg = new CoinGecko({ apiKey: 'CG-xxxxxxxxxxxxxxxxxxxx' });
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Get a Pro API key at [coingecko.com/api/pricing](https://www.coingecko.com/api/pricing).
|
|
312
|
+
|
|
313
|
+
## Error Handling
|
|
314
|
+
|
|
315
|
+
All API errors throw a `CoinGeckoError` with structured information:
|
|
316
|
+
|
|
317
|
+
```typescript
|
|
318
|
+
import { CoinGecko, CoinGeckoError } from 'coingecko-pro';
|
|
319
|
+
|
|
320
|
+
const cg = new CoinGecko({ apiKey: 'CG-xxx' });
|
|
321
|
+
|
|
322
|
+
try {
|
|
323
|
+
await cg.coins.getById('this-coin-does-not-exist');
|
|
324
|
+
} catch (err) {
|
|
325
|
+
if (err instanceof CoinGeckoError) {
|
|
326
|
+
console.error(err.message); // Human-readable error description
|
|
327
|
+
console.error(err.status); // HTTP status code (0 for network errors)
|
|
328
|
+
console.error(err.url); // The URL that was requested
|
|
329
|
+
console.error(err.data); // Raw response body, if available
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
| Status | Meaning | SDK Behavior |
|
|
335
|
+
|---|---|---|
|
|
336
|
+
| `0` | Network error / timeout | Retried up to `maxRetries` times |
|
|
337
|
+
| `429` | Rate limited | Retried with exponential backoff |
|
|
338
|
+
| `401` | Invalid API key | Thrown immediately (not retried) |
|
|
339
|
+
| `403` | Pro-only endpoint | Thrown immediately (not retried) |
|
|
340
|
+
| `404` | Resource not found | Thrown immediately (not retried) |
|
|
341
|
+
| `503` | Service unavailable | Retried with exponential backoff |
|
|
342
|
+
|
|
343
|
+
## Cache & Rate Limiting
|
|
344
|
+
|
|
345
|
+
### Built-in Cache
|
|
346
|
+
|
|
347
|
+
Every response is cached in memory with a configurable TTL. Identical requests within the cache window are served instantly without hitting the API.
|
|
348
|
+
|
|
349
|
+
```typescript
|
|
350
|
+
const cg = new CoinGecko({
|
|
351
|
+
apiKey: 'CG-xxx',
|
|
352
|
+
cacheTtl: 60_000, // Cache responses for 60 seconds
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// First call hits the API
|
|
356
|
+
const btc1 = await cg.coins.getById('bitcoin');
|
|
357
|
+
|
|
358
|
+
// Second call within 60s returns cached data instantly
|
|
359
|
+
const btc2 = await cg.coins.getById('bitcoin');
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
Disable caching globally by setting `cacheTtl: 0`.
|
|
363
|
+
|
|
364
|
+
### Rate Limiter
|
|
365
|
+
|
|
366
|
+
A token-bucket rate limiter runs in-process and ensures your application never exceeds the CoinGecko rate limit. When the bucket is empty, requests automatically wait until a token becomes available.
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
// Pro tier: 500 requests/minute (default when apiKey is set)
|
|
370
|
+
const cg = new CoinGecko({ apiKey: 'CG-xxx' });
|
|
371
|
+
|
|
372
|
+
// Custom rate limit
|
|
373
|
+
const cg = new CoinGecko({ apiKey: 'CG-xxx', rateLimit: 100 });
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
## Advanced Usage
|
|
377
|
+
|
|
378
|
+
### Standalone Endpoint Classes
|
|
379
|
+
|
|
380
|
+
For maximum tree-shaking or custom compositions, import endpoint classes directly:
|
|
381
|
+
|
|
382
|
+
```typescript
|
|
383
|
+
import { CoinGeckoClient } from 'coingecko-pro';
|
|
384
|
+
import { CoinsEndpoints } from 'coingecko-pro';
|
|
385
|
+
import { OnchainEndpoints } from 'coingecko-pro';
|
|
386
|
+
|
|
387
|
+
const client = new CoinGeckoClient({ apiKey: 'CG-xxx' });
|
|
388
|
+
const coins = new CoinsEndpoints(client);
|
|
389
|
+
const onchain = new OnchainEndpoints(client);
|
|
390
|
+
|
|
391
|
+
const btc = await coins.getById('bitcoin');
|
|
392
|
+
const pools = await onchain.trendingPools();
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
### Lifecycle Hooks
|
|
396
|
+
|
|
397
|
+
Use hooks for logging, metrics, or request tracing:
|
|
398
|
+
|
|
399
|
+
```typescript
|
|
400
|
+
const cg = new CoinGecko({
|
|
401
|
+
apiKey: 'CG-xxx',
|
|
402
|
+
onRequest: (url) => {
|
|
403
|
+
performance.mark(`cg-start-${url}`);
|
|
404
|
+
},
|
|
405
|
+
onResponse: (url, status, ms) => {
|
|
406
|
+
metrics.histogram('coingecko.latency', ms, { status: String(status) });
|
|
407
|
+
},
|
|
408
|
+
onError: (url, error) => {
|
|
409
|
+
logger.error('CoinGecko request failed', { url, error: error.message });
|
|
410
|
+
},
|
|
411
|
+
});
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
## Requirements
|
|
415
|
+
|
|
416
|
+
- **Node.js 18+**, **Bun**, **Deno**, or any environment with a global `fetch` implementation
|
|
417
|
+
- No polyfills needed -- zero runtime dependencies
|
|
418
|
+
|
|
419
|
+
## Contributing
|
|
420
|
+
|
|
421
|
+
Contributions are welcome! Please follow these steps:
|
|
422
|
+
|
|
423
|
+
1. Fork the repository
|
|
424
|
+
2. Create a feature branch: `git checkout -b feature/my-feature`
|
|
425
|
+
3. Make your changes with tests
|
|
426
|
+
4. Run checks: `npm run lint && npm test`
|
|
427
|
+
5. Submit a pull request
|
|
428
|
+
|
|
429
|
+
## License
|
|
430
|
+
|
|
431
|
+
[MIT](LICENSE) -- 0xJesus
|