glassnode-api 0.1.3 → 0.1.4

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/README.md CHANGED
@@ -43,12 +43,18 @@ async function getMetrics() {
43
43
 
44
44
  ## Examples
45
45
 
46
- Check the `examples` directory for usage examples. To run the examples:
46
+ Explore our [detailed examples](./examples/README.md) to learn how to use the Glassnode API client effectively. The examples demonstrate:
47
+
48
+ - Fetching and validating asset metadata
49
+ - Working with metric lists and metadata
50
+ - Calling metrics with parameters
51
+
52
+ To run the examples:
47
53
 
48
54
  1. Navigate to the examples directory
49
- 2. Create a `.env` file based on `.env.example` with your API key
55
+ 2. Create a `.env` file with your API key: `GLASSNODE_API_KEY=your_key_here`
50
56
  3. Install dependencies with `npm install`
51
- 4. Run an example with `npx ts-node metadata.ts`
57
+ 4. Run an example with `npx ts-node metadata.validation.ts`
52
58
 
53
59
  ## Development
54
60
 
@@ -0,0 +1 @@
1
+ import 'dotenv/config';
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const src_1 = require("../src");
4
+ const zod_1 = require("zod");
5
+ require("dotenv/config");
6
+ // Create an instance of the API client
7
+ const api = new src_1.GlassnodeAPI({
8
+ apiKey: process.env.GLASSNODE_API_KEY || '', // Get API key from .env file
9
+ });
10
+ async function fetchAssetMetadata() {
11
+ try {
12
+ // Get asset metadata
13
+ console.log('Fetching asset metadata...');
14
+ const assetMetadata = await api.getAssetMetadata();
15
+ // Show total number of assets
16
+ console.log(`Found ${assetMetadata.length} assets in total`);
17
+ // Custom validation: Check if USDC is present in the response
18
+ const USDCSchema = zod_1.z.object({
19
+ symbol: zod_1.z.literal('USDC'),
20
+ name: zod_1.z.literal('USDC'),
21
+ asset_type: zod_1.z.literal('TOKEN'),
22
+ });
23
+ // Create a refine function that looks for USDC
24
+ const usdc = assetMetadata.find((asset) => asset.symbol === 'USDC');
25
+ if (usdc) {
26
+ try {
27
+ USDCSchema.parse(usdc);
28
+ console.log('✅ USDC validation successful');
29
+ // Print 3 first blockchains for USDC
30
+ console.log('First 3 blockchains for USDC:');
31
+ usdc.blockchains.slice(0, 3).forEach((blockchain) => {
32
+ console.log(` - ${blockchain.blockchain} - ${blockchain.address}`);
33
+ });
34
+ }
35
+ catch (error) {
36
+ if (error instanceof zod_1.z.ZodError) {
37
+ console.error('❌ Schema validation failed:', error.errors);
38
+ }
39
+ else {
40
+ throw error;
41
+ }
42
+ }
43
+ }
44
+ else {
45
+ console.log('❌ USDC not found in response');
46
+ }
47
+ }
48
+ catch (error) {
49
+ console.error('Error fetching asset metadata:', error);
50
+ }
51
+ }
52
+ async function fetchMetricList() {
53
+ try {
54
+ console.log('\nFetching metric list...');
55
+ const metricList = await api.getMetricList();
56
+ // Display basic metrics information
57
+ console.log(`Found ${metricList.length} metrics in total`);
58
+ // Check for market metrics
59
+ const marketMetrics = metricList.filter((metric) => metric.startsWith('/market/'));
60
+ if (marketMetrics.length > 0) {
61
+ console.log(`✅ Found ${marketMetrics.length} market metrics`);
62
+ console.log(`First 3 market metrics:`);
63
+ marketMetrics.slice(0, 3).forEach((metric) => console.log(` - ${metric}`));
64
+ }
65
+ else {
66
+ console.log('❌ No market metrics found');
67
+ }
68
+ }
69
+ catch (error) {
70
+ console.error('Error fetching metric list:', error);
71
+ }
72
+ }
73
+ async function fetchExchangeBalanceMetadata() {
74
+ try {
75
+ console.log('\nFetching exchange balance metadata...');
76
+ const metricPath = '/distribution/balance_exchanges';
77
+ const metadata = await api.getMetricMetadata(metricPath);
78
+ console.log('✅ Exchange balance metadata:');
79
+ console.log(` Path: ${metadata.path}`);
80
+ console.log(` Tier: ${metadata.tier}`);
81
+ console.log(` Modified: ${metadata.modified?.toISOString()}`);
82
+ // Display available parameters
83
+ console.log('\nAvailable parameters:');
84
+ // Only print the firt 3 values per parameter
85
+ Object.entries(metadata.parameters).forEach(([key, values]) => {
86
+ console.log(` ${key}: ${values.slice(0, 3).join(', ')}`);
87
+ });
88
+ // Display documentation links
89
+ if (metadata.refs.docs) {
90
+ console.log(`\nDocumentation: ${metadata.refs.docs}`);
91
+ }
92
+ if (metadata.refs.studio) {
93
+ console.log(`Studio: ${metadata.refs.studio}`);
94
+ }
95
+ }
96
+ catch (error) {
97
+ console.error('Error fetching exchange balance metadata:', error);
98
+ }
99
+ }
100
+ async function fetchExchangeBalanceWithParams() {
101
+ try {
102
+ console.log('\nFetching exchange balance metadata with specific parameters...');
103
+ const metricPath = '/distribution/balance_exchanges';
104
+ const params = { a: 'BTC' };
105
+ const metadata = await api.getMetricMetadata(metricPath, params);
106
+ console.log('✅ Exchange balance metadata for BTC:');
107
+ console.log(` Path: ${metadata.path}`);
108
+ console.log(` Tier: ${metadata.tier}`);
109
+ // Display queried parameters
110
+ console.log('\nQueried parameters:');
111
+ Object.entries(metadata.queried).forEach(([key, value]) => {
112
+ console.log(` ${key}: ${value}`);
113
+ });
114
+ }
115
+ catch (error) {
116
+ console.error('Error fetching exchange balance metadata with parameters:', error);
117
+ }
118
+ }
119
+ // Execute the examples
120
+ async function runExamples() {
121
+ await fetchAssetMetadata();
122
+ await fetchMetricList();
123
+ await fetchExchangeBalanceMetadata();
124
+ await fetchExchangeBalanceWithParams();
125
+ }
126
+ runExamples();
@@ -0,0 +1 @@
1
+ import 'dotenv/config';
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const src_1 = require("../src");
4
+ require("dotenv/config");
5
+ // Create an instance of the API client
6
+ const api = new src_1.GlassnodeAPI({
7
+ apiKey: process.env.GLASSNODE_API_KEY || '', // Get API key from .env file
8
+ });
9
+ // Execute the examples
10
+ async function runExamples() {
11
+ //const assetMetadata = await api.getAssetMetadata();
12
+ const metricList = await api.getMetricList();
13
+ for (const metric of metricList.slice(0, 10)) {
14
+ const metricMetadata = await api.getMetricMetadata(metric);
15
+ const params = metricMetadata.parameters;
16
+ // create params object from params array
17
+ const paramsObject = {};
18
+ for (const param of Object.keys(params)) {
19
+ // Fix: params[param] is an array of strings, not an object with values property
20
+ if (Array.isArray(params[param]) && params[param].length > 0) {
21
+ paramsObject[param] = params[param][0];
22
+ }
23
+ }
24
+ const result = (await api.callMetric(metric, paramsObject));
25
+ console.log(result[0]);
26
+ }
27
+ }
28
+ runExamples();
@@ -32,6 +32,7 @@ class GlassnodeAPI {
32
32
  api_key: this.apiKey,
33
33
  });
34
34
  const url = `${this.apiUrl}${endpoint}?${queryParams}`;
35
+ console.log(' API call:', url);
35
36
  try {
36
37
  const response = await fetch(url);
37
38
  if (!response.ok) {
@@ -85,7 +86,7 @@ class GlassnodeAPI {
85
86
  * @returns Promise resolving to the response data
86
87
  */
87
88
  async callMetric(metricPath, params = {}) {
88
- const response = await this.request('https://api.glassnode.com/v1/metrics/addresses' + metricPath, params);
89
+ const response = await this.request('/v1/metrics' + metricPath, { ...params, f: 'json' });
89
90
  return response;
90
91
  }
91
92
  }
@@ -252,7 +252,7 @@ export declare const MetricMetadataSchema: z.ZodObject<{
252
252
  /**
253
253
  * The last date that the metadata was updated
254
254
  */
255
- modified: z.ZodEffects<z.ZodNumber, Date, number>;
255
+ modified: z.ZodEffects<z.ZodOptional<z.ZodNumber>, Date | undefined, number | undefined>;
256
256
  /**
257
257
  * Next parameter for the metric
258
258
  */
@@ -281,24 +281,24 @@ export declare const MetricMetadataSchema: z.ZodObject<{
281
281
  }, "strip", z.ZodTypeAny, {
282
282
  path: string;
283
283
  tier: number;
284
- modified: Date;
285
284
  refs: {
286
285
  docs?: string | undefined;
287
286
  studio?: string | undefined;
288
287
  };
289
288
  queried: Record<string, any>;
290
289
  parameters: Record<string, string[]>;
290
+ modified?: Date | undefined;
291
291
  next_param?: string | undefined;
292
292
  }, {
293
293
  path: string;
294
294
  tier: number;
295
- modified: number;
296
295
  refs: {
297
296
  docs?: string | undefined;
298
297
  studio?: string | undefined;
299
298
  };
300
299
  queried: Record<string, any>;
301
300
  parameters: Record<string, string[]>;
301
+ modified?: number | undefined;
302
302
  next_param?: string | undefined;
303
303
  }>;
304
304
  /**
@@ -320,7 +320,7 @@ export declare const MetricMetadataResponseSchema: z.ZodObject<{
320
320
  /**
321
321
  * The last date that the metadata was updated
322
322
  */
323
- modified: z.ZodEffects<z.ZodNumber, Date, number>;
323
+ modified: z.ZodEffects<z.ZodOptional<z.ZodNumber>, Date | undefined, number | undefined>;
324
324
  /**
325
325
  * Next parameter for the metric
326
326
  */
@@ -349,24 +349,24 @@ export declare const MetricMetadataResponseSchema: z.ZodObject<{
349
349
  }, "strip", z.ZodTypeAny, {
350
350
  path: string;
351
351
  tier: number;
352
- modified: Date;
353
352
  refs: {
354
353
  docs?: string | undefined;
355
354
  studio?: string | undefined;
356
355
  };
357
356
  queried: Record<string, any>;
358
357
  parameters: Record<string, string[]>;
358
+ modified?: Date | undefined;
359
359
  next_param?: string | undefined;
360
360
  }, {
361
361
  path: string;
362
362
  tier: number;
363
- modified: number;
364
363
  refs: {
365
364
  docs?: string | undefined;
366
365
  studio?: string | undefined;
367
366
  };
368
367
  queried: Record<string, any>;
369
368
  parameters: Record<string, string[]>;
369
+ modified?: number | undefined;
370
370
  next_param?: string | undefined;
371
371
  }>;
372
372
  /**
@@ -90,7 +90,10 @@ exports.MetricMetadataSchema = zod_1.z.object({
90
90
  /**
91
91
  * The last date that the metadata was updated
92
92
  */
93
- modified: zod_1.z.number().transform((val) => new Date(val * 1000)),
93
+ modified: zod_1.z
94
+ .number()
95
+ .optional()
96
+ .transform((val) => (val ? new Date(val * 1000) : undefined)),
94
97
  /**
95
98
  * Next parameter for the metric
96
99
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glassnode-api",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "Node.js client for the Glassnode API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -9,7 +9,7 @@
9
9
  ],
10
10
  "repository": {
11
11
  "type": "git",
12
- "url": "https://github.com/planadecu/glassnode-api-node.git"
12
+ "url": "git+https://github.com/planadecu/glassnode-api-node.git"
13
13
  },
14
14
  "scripts": {
15
15
  "build": "tsc",
@@ -38,7 +38,7 @@
38
38
  "prettier": "^3.5.3",
39
39
  "ts-jest": "^29.3.2",
40
40
  "typescript": "^5.8.3",
41
- "typescript-eslint": "^8.32.0"
41
+ "typescript-eslint": "^8.32.1"
42
42
  },
43
43
  "lint-staged": {
44
44
  "*.{js,ts,mjs}": [
File without changes
File without changes
File without changes
File without changes