Really-amin commited on
Commit
dfb6cf1
·
verified ·
1 Parent(s): df9fbb5

Sanitize embedded tokens; add /api/health alias

Browse files
Files changed (48) hide show
  1. CRYPTOBERT_COMPLETION_REPORT.txt +2 -2
  2. CRYPTOBERT_QUICK_REFERENCE.md +2 -2
  3. CRYPTOBERT_SETUP_COMPLETE.md +4 -4
  4. FINAL_FIXES_SUMMARY.md +6 -6
  5. HF_IMPLEMENTATION_COMPLETE.md +1 -1
  6. INTEGRATION_SUMMARY.md +4 -4
  7. QUICK_START_FA.md +3 -3
  8. SET_HF_TOKEN.md +7 -7
  9. START_HERE.md +2 -2
  10. all_apis_merged_2025.json +2 -2
  11. api-resources/crypto_resources_unified_2025-11-11.json +2 -2
  12. api/HF_IMPLEMENTATION_COMPLETE.md +1 -1
  13. api/QUICK_START.md +1 -1
  14. api/all_apis_merged_2025.json +2 -2
  15. api/crypto_resources_unified_2025-11-11.json +2 -2
  16. archive/all_apis_merged_2025.json +2 -2
  17. archive/docs/CRYPTOBERT_QUICK_REFERENCE.md +2 -2
  18. config.js +1 -1
  19. crypto_resources_unified_2025-11-11.json +2 -2
  20. docs/CRYPTOBERT_INTEGRATION.md +4 -4
  21. docs/archive/HF_IMPLEMENTATION_COMPLETE.md +1 -1
  22. final/.env +1 -1
  23. final/all_apis_merged_2025.json +2 -2
  24. final/api-resources/crypto_resources_unified_2025-11-11.json +2 -2
  25. final/backend/services/auto_discovery_service.py +1 -1
  26. final/backend/services/diagnostics_service.py +1 -1
  27. final/config.js +1 -1
  28. final/config.py +1 -1
  29. final/crypto_resources_unified_2025-11-11.json +2 -2
  30. final/hf_unified_server.py +1 -1
  31. final/provider_validator.py +1 -1
  32. final/providers_config_ultimate.json +1 -1
  33. final/setup_cryptobert.sh +1 -1
  34. final/static/js/huggingface-integration.js +1 -1
  35. final/static/providers_config_ultimate.json +1 -1
  36. final/test_cryptobert.py +1 -1
  37. hf-data-engine/all_apis_merged_2025.json +2 -2
  38. hf-data-engine/api-resources/crypto_resources_unified_2025-11-11.json +2 -2
  39. hf-data-engine/crypto_resources_unified_2025-11-11.json +2 -2
  40. hf-data-engine/docs/archive/HF_IMPLEMENTATION_COMPLETE.md +1 -1
  41. hf-data-engine/providers_config_ultimate.json +1 -1
  42. providers_config_ultimate.json +1 -1
  43. run_server.ps1 +1 -1
  44. set_env.ps1 +1 -1
  45. setup_cryptobert.sh +1 -1
  46. static/js/huggingface-integration.js +1 -1
  47. static/providers_config_ultimate.json +1 -1
  48. test_cryptobert.py +1 -1
CRYPTOBERT_COMPLETION_REPORT.txt CHANGED
@@ -18,7 +18,7 @@ Model Details:
18
  • Name: ElKulako/CryptoBERT
19
  • Status: CONDITIONALLY_AVAILABLE (requires authentication)
20
  • Authentication: HF_TOKEN configured
21
- • Token: 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
22
  • Task: fill-mask (Masked Language Model)
23
  • Use Case: Cryptocurrency-specific sentiment analysis
24
 
@@ -85,7 +85,7 @@ Created Files:
85
  ================================================================================
86
 
87
  Environment Variables:
88
- HF_TOKEN = "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"
89
 
90
  Models Configured (4 total):
91
  1. sentiment_twitter: cardiffnlp/twitter-roberta-base-sentiment-latest
 
18
  • Name: ElKulako/CryptoBERT
19
  • Status: CONDITIONALLY_AVAILABLE (requires authentication)
20
  • Authentication: HF_TOKEN configured
21
+ • Token: hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
22
  • Task: fill-mask (Masked Language Model)
23
  • Use Case: Cryptocurrency-specific sentiment analysis
24
 
 
85
  ================================================================================
86
 
87
  Environment Variables:
88
+ HF_TOKEN = "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
89
 
90
  Models Configured (4 total):
91
  1. sentiment_twitter: cardiffnlp/twitter-roberta-base-sentiment-latest
CRYPTOBERT_QUICK_REFERENCE.md CHANGED
@@ -21,7 +21,7 @@ python3 -c "import ai_models; ai_models.initialize_models(); print(ai_models.ana
21
  |------|-------|
22
  | **Model** | ElKulako/CryptoBERT |
23
  | **ID** | `hf_model_elkulako_cryptobert` |
24
- | **Token** | `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` |
25
  | **Status** | CONDITIONALLY_AVAILABLE |
26
 
27
  ---
@@ -53,7 +53,7 @@ print(f"Loaded: {info['loaded_models']['crypto_sentiment']}")
53
 
54
  ### Setup
55
  ```bash
56
- export HF_TOKEN="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"
57
  ./setup_cryptobert.sh
58
  ```
59
 
 
21
  |------|-------|
22
  | **Model** | ElKulako/CryptoBERT |
23
  | **ID** | `hf_model_elkulako_cryptobert` |
24
+ | **Token** | `hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` |
25
  | **Status** | CONDITIONALLY_AVAILABLE |
26
 
27
  ---
 
53
 
54
  ### Setup
55
  ```bash
56
+ export HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
57
  ./setup_cryptobert.sh
58
  ```
59
 
CRYPTOBERT_SETUP_COMPLETE.md CHANGED
@@ -9,7 +9,7 @@ The **ElKulako/CryptoBERT** model has been successfully integrated into your Cry
9
  - **Provider ID**: `hf_model_elkulako_cryptobert`
10
  - **Status**: CONDITIONALLY_AVAILABLE (requires authentication)
11
  - **Authentication**: HF_TOKEN configured
12
- - **Token**: `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`
13
 
14
  ## What Was Implemented
15
 
@@ -138,13 +138,13 @@ Expected output includes:
138
 
139
  ### Current Configuration
140
  ```bash
141
- HF_TOKEN="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"
142
  ```
143
 
144
  ### To Set Permanently
145
  ```bash
146
  # Add to ~/.bashrc or ~/.zshrc
147
- echo 'export HF_TOKEN="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"' >> ~/.bashrc
148
  source ~/.bashrc
149
  ```
150
 
@@ -216,7 +216,7 @@ print(f"Market sentiment: {result['label']}")
216
  ```python
217
  from transformers import pipeline
218
  import os
219
- os.environ['HF_TOKEN'] = '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'
220
  pipe = pipeline("fill-mask", model="ElKulako/CryptoBERT", use_auth_token=True)
221
  ```
222
 
 
9
  - **Provider ID**: `hf_model_elkulako_cryptobert`
10
  - **Status**: CONDITIONALLY_AVAILABLE (requires authentication)
11
  - **Authentication**: HF_TOKEN configured
12
+ - **Token**: `hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
13
 
14
  ## What Was Implemented
15
 
 
138
 
139
  ### Current Configuration
140
  ```bash
141
+ HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
142
  ```
143
 
144
  ### To Set Permanently
145
  ```bash
146
  # Add to ~/.bashrc or ~/.zshrc
147
+ echo 'export HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"' >> ~/.bashrc
148
  source ~/.bashrc
149
  ```
150
 
 
216
  ```python
217
  from transformers import pipeline
218
  import os
219
+ os.environ['HF_TOKEN'] = 'hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
220
  pipe = pipeline("fill-mask", model="ElKulako/CryptoBERT", use_auth_token=True)
221
  ```
222
 
FINAL_FIXES_SUMMARY.md CHANGED
@@ -6,7 +6,7 @@
6
 
7
  **توکن شما:**
8
  ```
9
- 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
10
  ```
11
 
12
  **فایل ایجاد شده:** `SET_HF_TOKEN.md`
@@ -16,13 +16,13 @@ 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
16
  #### روی Hugging Face Space (برای دیپلوی):
17
  ```
18
  Settings → Repository secrets
19
- - HF_TOKEN: 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
20
  - HF_MODE: public
21
  ```
22
 
23
  #### روی Windows (Local):
24
  ```powershell
25
- $env:HF_TOKEN="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"
26
  $env:HF_MODE="public"
27
  python api_server_extended.py
28
  ```
@@ -155,14 +155,14 @@ if (typeof Chart === 'undefined') {
155
  **روی Hugging Face Space:**
156
  ```
157
  1. Settings → Repository secrets
158
- 2. Add: HF_TOKEN = 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
159
  3. Add: HF_MODE = public
160
  4. Restart Space
161
  ```
162
 
163
  **روی Local (Windows):**
164
  ```powershell
165
- $env:HF_TOKEN="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"
166
  $env:HF_MODE="public"
167
  python api_server_extended.py
168
  ```
@@ -289,7 +289,7 @@ $env:HF_MODE
289
 
290
  **راه‌حل:**
291
  ```powershell
292
- $env:HF_TOKEN="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"
293
  $env:HF_MODE="public"
294
  ```
295
 
 
6
 
7
  **توکن شما:**
8
  ```
9
+ hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
10
  ```
11
 
12
  **فایل ایجاد شده:** `SET_HF_TOKEN.md`
 
16
  #### روی Hugging Face Space (برای دیپلوی):
17
  ```
18
  Settings → Repository secrets
19
+ - HF_TOKEN: hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
20
  - HF_MODE: public
21
  ```
22
 
23
  #### روی Windows (Local):
24
  ```powershell
25
+ $env:HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
26
  $env:HF_MODE="public"
27
  python api_server_extended.py
28
  ```
 
155
  **روی Hugging Face Space:**
156
  ```
157
  1. Settings → Repository secrets
158
+ 2. Add: HF_TOKEN = hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
159
  3. Add: HF_MODE = public
160
  4. Restart Space
161
  ```
162
 
163
  **روی Local (Windows):**
164
  ```powershell
165
+ $env:HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
166
  $env:HF_MODE="public"
167
  python api_server_extended.py
168
  ```
 
289
 
290
  **راه‌حل:**
291
  ```powershell
292
+ $env:HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
293
  $env:HF_MODE="public"
294
  ```
295
 
HF_IMPLEMENTATION_COMPLETE.md CHANGED
@@ -47,7 +47,7 @@
47
 
48
  #### 1. **Environment Configuration** (`.env`)
49
  ```env
50
- HUGGINGFACE_TOKEN=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
51
  ENABLE_SENTIMENT=true
52
  SENTIMENT_SOCIAL_MODEL=ElKulako/cryptobert
53
  SENTIMENT_NEWS_MODEL=kk08/CryptoBERT
 
47
 
48
  #### 1. **Environment Configuration** (`.env`)
49
  ```env
50
+ HUGGINGFACE_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
51
  ENABLE_SENTIMENT=true
52
  SENTIMENT_SOCIAL_MODEL=ElKulako/cryptobert
53
  SENTIMENT_NEWS_MODEL=kk08/CryptoBERT
INTEGRATION_SUMMARY.md CHANGED
@@ -14,7 +14,7 @@ The **ElKulako/CryptoBERT** model has been successfully integrated into your Cry
14
  | **Model ID** | `hf_model_elkulako_cryptobert` |
15
  | **Status** | CONDITIONALLY_AVAILABLE |
16
  | **Authentication** | Required (HF_TOKEN) |
17
- | **Token** | `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` |
18
  | **Task Type** | fill-mask (Masked Language Model) |
19
  | **Use Case** | Cryptocurrency-specific sentiment analysis |
20
  | **Integration Status** | ✓ Active and Operational |
@@ -34,7 +34,7 @@ HUGGINGFACE_MODELS = {
34
  "crypto_sentiment": "ElKulako/CryptoBERT", # NEW
35
  }
36
 
37
- HF_TOKEN = os.environ.get("HF_TOKEN", "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")
38
  HF_USE_AUTH_TOKEN = bool(HF_TOKEN)
39
  ```
40
 
@@ -227,13 +227,13 @@ python3 -c "import ai_models; info = ai_models.get_model_info(); print(info)"
227
 
228
  ### Current Setup
229
  ```bash
230
- HF_TOKEN="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"
231
  ```
232
 
233
  ### Permanent Setup
234
  ```bash
235
  # Add to ~/.bashrc or ~/.zshrc
236
- echo 'export HF_TOKEN="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"' >> ~/.bashrc
237
  source ~/.bashrc
238
  ```
239
 
 
14
  | **Model ID** | `hf_model_elkulako_cryptobert` |
15
  | **Status** | CONDITIONALLY_AVAILABLE |
16
  | **Authentication** | Required (HF_TOKEN) |
17
+ | **Token** | `hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` |
18
  | **Task Type** | fill-mask (Masked Language Model) |
19
  | **Use Case** | Cryptocurrency-specific sentiment analysis |
20
  | **Integration Status** | ✓ Active and Operational |
 
34
  "crypto_sentiment": "ElKulako/CryptoBERT", # NEW
35
  }
36
 
37
+ HF_TOKEN = os.environ.get("HF_TOKEN", "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
38
  HF_USE_AUTH_TOKEN = bool(HF_TOKEN)
39
  ```
40
 
 
227
 
228
  ### Current Setup
229
  ```bash
230
+ HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
231
  ```
232
 
233
  ### Permanent Setup
234
  ```bash
235
  # Add to ~/.bashrc or ~/.zshrc
236
+ echo 'export HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"' >> ~/.bashrc
237
  source ~/.bashrc
238
  ```
239
 
QUICK_START_FA.md CHANGED
@@ -7,14 +7,14 @@
7
  2. `Settings` → `Repository secrets`
8
  3. دو secret اضافه کنید:
9
  ```
10
- HF_TOKEN = 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
11
  HF_MODE = public
12
  ```
13
  4. Space را Restart کنید
14
 
15
  ### روی Windows Local:
16
  ```powershell
17
- $env:HF_TOKEN="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"
18
  $env:HF_MODE="public"
19
  ```
20
 
@@ -66,7 +66,7 @@ $env:HF_TOKEN
66
  $env:HF_MODE
67
 
68
  # تنظیم مجدد
69
- $env:HF_TOKEN="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"
70
  $env:HF_MODE="public"
71
  ```
72
 
 
7
  2. `Settings` → `Repository secrets`
8
  3. دو secret اضافه کنید:
9
  ```
10
+ HF_TOKEN = hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
11
  HF_MODE = public
12
  ```
13
  4. Space را Restart کنید
14
 
15
  ### روی Windows Local:
16
  ```powershell
17
+ $env:HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
18
  $env:HF_MODE="public"
19
  ```
20
 
 
66
  $env:HF_MODE
67
 
68
  # تنظیم مجدد
69
+ $env:HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
70
  $env:HF_MODE="public"
71
  ```
72
 
SET_HF_TOKEN.md CHANGED
@@ -2,7 +2,7 @@
2
 
3
  ## توکن شما:
4
  ```
5
- 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
6
  ```
7
 
8
  ## روش‌های تنظیم:
@@ -15,7 +15,7 @@ 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
15
 
16
  **Secret 1:**
17
  - Name: `HF_TOKEN`
18
- - Value: `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`
19
 
20
  **Secret 2:**
21
  - Name: `HF_MODE`
@@ -29,7 +29,7 @@ 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
29
 
30
  در PowerShell:
31
  ```powershell
32
- $env:HF_TOKEN="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"
33
  $env:HF_MODE="public"
34
  python api_server_extended.py
35
  ```
@@ -38,7 +38,7 @@ python api_server_extended.py
38
  1. Win + R → `sysdm.cpl` → Advanced → Environment Variables
39
  2. در User variables، New کنید:
40
  - Name: `HF_TOKEN`
41
- - Value: `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`
42
  3. یکی دیگر:
43
  - Name: `HF_MODE`
44
  - Value: `public`
@@ -49,14 +49,14 @@ python api_server_extended.py
49
 
50
  در terminal:
51
  ```bash
52
- export HF_TOKEN="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"
53
  export HF_MODE="public"
54
  python api_server_extended.py
55
  ```
56
 
57
  یا در `~/.bashrc` یا `~/.zshrc` اضافه کنید:
58
  ```bash
59
- export HF_TOKEN="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"
60
  export HF_MODE="public"
61
  ```
62
 
@@ -66,7 +66,7 @@ export HF_MODE="public"
66
 
67
  فایل `.env` در root پروژه ایجاد کنید:
68
  ```
69
- HF_TOKEN=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
70
  HF_MODE=public
71
  PORT=7860
72
  ```
 
2
 
3
  ## توکن شما:
4
  ```
5
+ hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
6
  ```
7
 
8
  ## روش‌های تنظیم:
 
15
 
16
  **Secret 1:**
17
  - Name: `HF_TOKEN`
18
+ - Value: `hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
19
 
20
  **Secret 2:**
21
  - Name: `HF_MODE`
 
29
 
30
  در PowerShell:
31
  ```powershell
32
+ $env:HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
33
  $env:HF_MODE="public"
34
  python api_server_extended.py
35
  ```
 
38
  1. Win + R → `sysdm.cpl` → Advanced → Environment Variables
39
  2. در User variables، New کنید:
40
  - Name: `HF_TOKEN`
41
+ - Value: `hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
42
  3. یکی دیگر:
43
  - Name: `HF_MODE`
44
  - Value: `public`
 
49
 
50
  در terminal:
51
  ```bash
52
+ export HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
53
  export HF_MODE="public"
54
  python api_server_extended.py
55
  ```
56
 
57
  یا در `~/.bashrc` یا `~/.zshrc` اضافه کنید:
58
  ```bash
59
+ export HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
60
  export HF_MODE="public"
61
  ```
62
 
 
66
 
67
  فایل `.env` در root پروژه ایجاد کنید:
68
  ```
69
+ HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
70
  HF_MODE=public
71
  PORT=7860
72
  ```
START_HERE.md CHANGED
@@ -67,7 +67,7 @@ Score: 5/6 (83.3%)
67
 
68
  ### گزینه 2: دستی
69
  ```powershell
70
- $env:HF_TOKEN="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"
71
  $env:HF_MODE="public"
72
  python api_server_extended.py
73
  ```
@@ -75,7 +75,7 @@ python api_server_extended.py
75
  ### گزینه 3: دائمی (در System Environment Variables)
76
  1. Win + R → `sysdm.cpl`
77
  2. Advanced → Environment Variables
78
- 3. New → Name: `HF_TOKEN`, Value: `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`
79
  4. New → Name: `HF_MODE`, Value: `public`
80
 
81
  ---
 
67
 
68
  ### گزینه 2: دستی
69
  ```powershell
70
+ $env:HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
71
  $env:HF_MODE="public"
72
  python api_server_extended.py
73
  ```
 
75
  ### گزینه 3: دائمی (در System Environment Variables)
76
  1. Win + R → `sysdm.cpl`
77
  2. Advanced → Environment Variables
78
+ 3. New → Name: `HF_TOKEN`, Value: `hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`
79
  4. New → Name: `HF_MODE`, Value: `public`
80
 
81
  ---
all_apis_merged_2025.json CHANGED
@@ -31,7 +31,7 @@
31
  "zip_text_snippets": [
32
  {
33
  "filename": "crypto_resources.ts",
34
- "text_preview": "// crypto_resources.ts — unified TS with 150+ Hugging Face sources (dynamic catalog) + Safe F&G aggregator\n// English-only comments. Keys intentionally embedded per user request.\n\nexport type Category =\n | 'market'\n | 'news'\n | 'sentiment'\n | 'onchain'\n | 'block_explorer'\n | 'whales'\n | 'generic'\n | 'hf';\n\nexport interface EndpointDef {\n path: string;\n method?: 'GET' | 'POST';\n sampleParams?: Record<string, string | number>;\n authLocation?: 'header' | 'query';\n authName?: string;\n authValue?: string;\n contentType?: string;\n}\n\nexport interface CryptoResource {\n id: string;\n category: Category;\n name: string;\n baseUrl: string;\n free: boolean;\n rateLimit?: string;\n endpoints?: Record<string, EndpointDef>;\n}\n\nexport interface MarketQuote {\n id: string;\n symbol: string;\n name: string;\n price: number;\n change24h?: number;\n marketCap?: number;\n source: string;\n raw: any;\n}\n\nexport interface NewsItem {\n title: string;\n link: string;\n publishedAt?: string;\n source: string;\n}\n\nexport interface OHLCVRow {\n timestamp: number | string;\n open: number; high: number; low: number; close: number; volume: number;\n [k: string]: any;\n}\n\nexport interface FNGPoint {\n value: number; // 0..100\n classification: string;\n at?: string;\n source: string;\n raw?: any;\n}\n\nconst EMBEDDED_KEYS = {\n CMC: '04cf4b5b-9868-465c-8ba0-9f2e78c92eb1',\n ETHERSCAN: 'SZHYFZK2RR8H9TIMJBVW54V4H81K2Z2KR2',\n ETHERSCAN_BACKUP: 'T6IR8VJHX2NE6ZJW2S3FDVN1TYG4PYYI45',\n BSCSCAN: 'K62RKHGXTDCG53RU4MCG6XABIMJKTN19IT',\n CRYPTOCOMPARE: 'e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f',\n\n // Optional free keys provided by user (kept in-code per request)\n MESSARI: '',\n SANTIMENT: '',\n COINMETRICS: '',\n HUGGINGFACE: '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',\n};\n\nconst sleep = (ms: number) => new Promise(r => setTimeout(r, ms));\n\nclass HttpError extends Error {\n constructor(public status: number, public url: string, public body?: string) {\n super(`HTTP ${status} for ${url}`);\n }\n}\n\nfunction buildURL(base: string, path = '', params?: Record<string, any>): string {\n const hasQ = path.includes('?');\n const url = base.replace(/\\/+$/, '') + '/' + path.replace(/^\\/+/, '');\n if (!params || Object.keys(params).length === 0) return url;\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n qs.set(k, String(v));\n }\n return url + (hasQ ? '&' : '?') + qs.toString();\n}\n\nasync function fetchRaw(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<Response> {\n const { headers = {}, timeoutMs = 12000, retries = 1, retryDelayMs = 600, body, method = 'GET' } = opts;\n let lastErr: any;\n for (let attempt = 0; attempt <= retries; attempt++) {\n const ac = new AbortController();\n const id = setTimeout(() => ac.abort(), timeoutMs);\n try {\n const res = await fetch(url, { headers, signal: ac.signal, method, body });\n clearTimeout(id);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n if (res.status === 429 && attempt < retries) {\n await sleep(retryDelayMs * (attempt + 1));\n continue;\n }\n throw new HttpError(res.status, url, text);\n }\n return res;\n } catch (e) {\n clearTimeout(id);\n lastErr = e;\n if (attempt < retries) { await sleep(retryDelayMs * (attempt + 1)); continue; }\n }\n }\n throw lastErr;\n}\n\nasync function fetchJSON<T = any>(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<T> {\n const res = await fetchRaw(url, opts);\n const ct = res.headers.get('content-type') || '';\n if (ct.includes('json')) return res.json() as Promise<T>;\n const text = await res.text();\n try { return JSON.parse(text) as T; } catch { return text as unknown as T; }\n}\n\nfunction ensureNonEmpty(obj: any, label: string) {\n if (obj == null) throw new Error(`${label}: empty response`);\n if (Array.isArray(obj) && obj.length === 0) throw new Error(`${label}: empty array`);\n if (typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === 0)\n throw new Error(`${label}: empty object`);\n}\n\nfunction normalizeSymbol(q: string) { return q.trim().toLowerCase(); }\n\nfunction parseCSV(text: string): any[] {\n const lines = text.split(/\\r?\\n/).filter(Boolean);\n if (lines.length < 2) return [];\n const header = lines[0].split(',').map((s) => s.trim());\n const out: any[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cols = lines[i].split(',').map((s) => s.trim());\n const row: any = {};\n header.forEach((h, idx) => { row[h] = cols[idx]; });\n out.push(row);\n }\n return out;\n}\n\nfunction parseRssSimple(xml: string, source: string, limit = 20): NewsItem[] {\n const items: NewsItem[] = [];\n const chunks = xml.split(/<item[\\s>]/i).slice(1);\n for (const raw of chunks) {\n const item = raw.split(/<\\/item>/i)[0] || '';\n const get = (tag: string) => {\n const m = item.match(new RegExp(`<${tag}[^>]*>([\\\\s\\\\S]*?)</${tag}>`, 'i'));\n return m ? m[1].replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() : undefined;\n };\n const title = get('title'); const link = get('link') || get('guid'); const pub = get('pubDate') || get('updated') || get('dc:date');\n if (title && link) items.push({ title, link, publishedAt: pub, source });\n if (items.length >= limit) break;\n }\n return items;\n}\n\n/* ===================== BASE RESOURCES ===================== */\n\nexport const resources: CryptoResource[] = [\n // Market\n { id: 'coinpaprika', category: 'market', name: 'CoinPaprika', baseUrl: 'https://api.coinpaprika.com/v1', free: true, endpoints: {\n search: { path: '/search', sampleParams: { q: 'bitcoin', c: 'currencies', limit: 1 } },\n tickerById: { path: '/tickers/{id}', sampleParams: { quotes: 'USD' } },\n }},\n { id: 'coincap', category: 'market', name: 'CoinCap', baseUrl: 'https://api.coincap.io/v2', free: true, endpoints: {\n assets: { path: '/assets', sampleParams: { search: 'bitcoin', limit: 1 } },\n assetById: { path: '/assets/{id}' },\n }},\n { id: 'coingecko', category: 'market', name: 'CoinGecko', baseUrl: 'https://api.coingecko.com/api/v3', free: true, endpoints: {\n simplePrice: { path: '/simple/price?ids={ids}&vs_currencies={fiats}' },\n }},\n { id: 'defillama', category: 'market', name: 'DefiLlama (Prices)', baseUrl: 'https://coins.llama.fi', free: true, endpoints: {\n pricesCurrent: { path: '/prices/current/{coins}' },\n }},\n { id: 'binance', category: 'market', name: 'Binance Public', baseUrl: 'https://api.binance.com', free: true, endpoints: {\n klines: { path: '/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}' },\n ticker: { path: '/api/v3/ticker/price?symbol={symbol}' },\n }},\n { id: 'cryptocompare', category: 'market', name: 'CryptoCompare', baseUrl: 'https://min-api.cryptocompare.com', free: true, endpoints: {\n histominute: { path: '/data/v2/histominute?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histohour: { path: '/data/v2/histohour?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histoday: { path: '/data/v2/histoday?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n }},\n { id: 'cmc', category: 'market', name: 'CoinMarketCap', baseUrl: 'https://pro-api.coinmarketcap.com/v1', free: false, endpoints: {\n quotes: { path: '/cryptocurrency/quotes/latest?symbol={symbol}', authLocation: 'header', authName: 'X-CMC_PRO_API_KEY', authValue: EMBEDDED_KEYS.CMC },\n }},\n\n // News\n { id: 'coinstats_news', category: 'news', name: 'CoinStats News', baseUrl: 'https://api.coinstats.app', free: true, endpoints: { feed: { path: '/public/v1/news' } }},\n { id: 'cryptopanic', category: 'news', name: 'CryptoPanic', baseUrl: 'https://cryptopanic.com', free: true, endpoints: { public: { path: '/api/v1/posts/?public=true' } }},\n { id: 'rss_cointelegraph', category: 'news', name: 'Cointelegraph RSS', baseUrl: 'https://cointelegraph.com', free: true, endpoints: { feed: { path: '/rss' } }},\n { id: 'rss_coindesk', category: 'news', name: 'CoinDesk RSS', baseUrl: 'https://www.coindesk.com', free: true, endpoints: { feed: { path: '/arc/outboundfeeds/rss/?outputType=xml' } }},\n { id: 'rss_decrypt', category: 'news', name: 'Decrypt RSS', baseUrl: 'https://decrypt.co', free: true, endpoints: { feed: { path: '/feed' } }},\n\n // Sentiment / F&G\n { id: 'altme_fng', category: 'sentiment', name: 'Alternative.me F&G', baseUrl: 'https://api.alternative.me', free: true, endpoints: {\n latest: { path: '/fng/', sampleParams: { limit: 1 } },\n history: { path: '/fng/', sampleParams: { limit: 30 } },\n }},\n { id: 'cfgi_v1', category: 'sentiment', name: 'CFGI API v1', baseUrl: 'https://api.cfgi.io', free: true, endpoints: {\n latest: { path: '/v1/fear-greed' },\n }},\n { id: 'cfgi_legacy', category: 'sentiment', name: 'CFGI Legacy', baseUrl: 'https://cfgi.io', free: true, endpoints: {\n latest: { path: '/api' },\n }},\n\n // On-chain / explorers\n { id: 'etherscan_primary', category: 'block_explorer', name: 'Etherscan', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN },\n }},\n { id: 'etherscan_backup', category: 'block_explorer', name: 'Etherscan Backup', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN_BACKUP },\n }},\n { id: 'blockscout_eth', category: 'block_explorer', name: 'Blockscout (ETH)', baseUrl: 'https://eth.blockscout.com', free: true, endpoints: {\n balanc",
35
  "note": "included as small text"
36
  }
37
  ],
@@ -57,7 +57,7 @@
57
  "e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f"
58
  ],
59
  "huggingface": [
60
- "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"
61
  ]
62
  },
63
  "notes": "This file was auto-generated. Keys/tokens are present as found in uploaded sources. Secure them as you wish."
 
31
  "zip_text_snippets": [
32
  {
33
  "filename": "crypto_resources.ts",
34
+ "text_preview": "// crypto_resources.ts — unified TS with 150+ Hugging Face sources (dynamic catalog) + Safe F&G aggregator\n// English-only comments. Keys intentionally embedded per user request.\n\nexport type Category =\n | 'market'\n | 'news'\n | 'sentiment'\n | 'onchain'\n | 'block_explorer'\n | 'whales'\n | 'generic'\n | 'hf';\n\nexport interface EndpointDef {\n path: string;\n method?: 'GET' | 'POST';\n sampleParams?: Record<string, string | number>;\n authLocation?: 'header' | 'query';\n authName?: string;\n authValue?: string;\n contentType?: string;\n}\n\nexport interface CryptoResource {\n id: string;\n category: Category;\n name: string;\n baseUrl: string;\n free: boolean;\n rateLimit?: string;\n endpoints?: Record<string, EndpointDef>;\n}\n\nexport interface MarketQuote {\n id: string;\n symbol: string;\n name: string;\n price: number;\n change24h?: number;\n marketCap?: number;\n source: string;\n raw: any;\n}\n\nexport interface NewsItem {\n title: string;\n link: string;\n publishedAt?: string;\n source: string;\n}\n\nexport interface OHLCVRow {\n timestamp: number | string;\n open: number; high: number; low: number; close: number; volume: number;\n [k: string]: any;\n}\n\nexport interface FNGPoint {\n value: number; // 0..100\n classification: string;\n at?: string;\n source: string;\n raw?: any;\n}\n\nconst EMBEDDED_KEYS = {\n CMC: '04cf4b5b-9868-465c-8ba0-9f2e78c92eb1',\n ETHERSCAN: 'SZHYFZK2RR8H9TIMJBVW54V4H81K2Z2KR2',\n ETHERSCAN_BACKUP: 'T6IR8VJHX2NE6ZJW2S3FDVN1TYG4PYYI45',\n BSCSCAN: 'K62RKHGXTDCG53RU4MCG6XABIMJKTN19IT',\n CRYPTOCOMPARE: 'e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f',\n\n // Optional free keys provided by user (kept in-code per request)\n MESSARI: '',\n SANTIMENT: '',\n COINMETRICS: '',\n HUGGINGFACE: 'hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',\n};\n\nconst sleep = (ms: number) => new Promise(r => setTimeout(r, ms));\n\nclass HttpError extends Error {\n constructor(public status: number, public url: string, public body?: string) {\n super(`HTTP ${status} for ${url}`);\n }\n}\n\nfunction buildURL(base: string, path = '', params?: Record<string, any>): string {\n const hasQ = path.includes('?');\n const url = base.replace(/\\/+$/, '') + '/' + path.replace(/^\\/+/, '');\n if (!params || Object.keys(params).length === 0) return url;\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n qs.set(k, String(v));\n }\n return url + (hasQ ? '&' : '?') + qs.toString();\n}\n\nasync function fetchRaw(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<Response> {\n const { headers = {}, timeoutMs = 12000, retries = 1, retryDelayMs = 600, body, method = 'GET' } = opts;\n let lastErr: any;\n for (let attempt = 0; attempt <= retries; attempt++) {\n const ac = new AbortController();\n const id = setTimeout(() => ac.abort(), timeoutMs);\n try {\n const res = await fetch(url, { headers, signal: ac.signal, method, body });\n clearTimeout(id);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n if (res.status === 429 && attempt < retries) {\n await sleep(retryDelayMs * (attempt + 1));\n continue;\n }\n throw new HttpError(res.status, url, text);\n }\n return res;\n } catch (e) {\n clearTimeout(id);\n lastErr = e;\n if (attempt < retries) { await sleep(retryDelayMs * (attempt + 1)); continue; }\n }\n }\n throw lastErr;\n}\n\nasync function fetchJSON<T = any>(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<T> {\n const res = await fetchRaw(url, opts);\n const ct = res.headers.get('content-type') || '';\n if (ct.includes('json')) return res.json() as Promise<T>;\n const text = await res.text();\n try { return JSON.parse(text) as T; } catch { return text as unknown as T; }\n}\n\nfunction ensureNonEmpty(obj: any, label: string) {\n if (obj == null) throw new Error(`${label}: empty response`);\n if (Array.isArray(obj) && obj.length === 0) throw new Error(`${label}: empty array`);\n if (typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === 0)\n throw new Error(`${label}: empty object`);\n}\n\nfunction normalizeSymbol(q: string) { return q.trim().toLowerCase(); }\n\nfunction parseCSV(text: string): any[] {\n const lines = text.split(/\\r?\\n/).filter(Boolean);\n if (lines.length < 2) return [];\n const header = lines[0].split(',').map((s) => s.trim());\n const out: any[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cols = lines[i].split(',').map((s) => s.trim());\n const row: any = {};\n header.forEach((h, idx) => { row[h] = cols[idx]; });\n out.push(row);\n }\n return out;\n}\n\nfunction parseRssSimple(xml: string, source: string, limit = 20): NewsItem[] {\n const items: NewsItem[] = [];\n const chunks = xml.split(/<item[\\s>]/i).slice(1);\n for (const raw of chunks) {\n const item = raw.split(/<\\/item>/i)[0] || '';\n const get = (tag: string) => {\n const m = item.match(new RegExp(`<${tag}[^>]*>([\\\\s\\\\S]*?)</${tag}>`, 'i'));\n return m ? m[1].replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() : undefined;\n };\n const title = get('title'); const link = get('link') || get('guid'); const pub = get('pubDate') || get('updated') || get('dc:date');\n if (title && link) items.push({ title, link, publishedAt: pub, source });\n if (items.length >= limit) break;\n }\n return items;\n}\n\n/* ===================== BASE RESOURCES ===================== */\n\nexport const resources: CryptoResource[] = [\n // Market\n { id: 'coinpaprika', category: 'market', name: 'CoinPaprika', baseUrl: 'https://api.coinpaprika.com/v1', free: true, endpoints: {\n search: { path: '/search', sampleParams: { q: 'bitcoin', c: 'currencies', limit: 1 } },\n tickerById: { path: '/tickers/{id}', sampleParams: { quotes: 'USD' } },\n }},\n { id: 'coincap', category: 'market', name: 'CoinCap', baseUrl: 'https://api.coincap.io/v2', free: true, endpoints: {\n assets: { path: '/assets', sampleParams: { search: 'bitcoin', limit: 1 } },\n assetById: { path: '/assets/{id}' },\n }},\n { id: 'coingecko', category: 'market', name: 'CoinGecko', baseUrl: 'https://api.coingecko.com/api/v3', free: true, endpoints: {\n simplePrice: { path: '/simple/price?ids={ids}&vs_currencies={fiats}' },\n }},\n { id: 'defillama', category: 'market', name: 'DefiLlama (Prices)', baseUrl: 'https://coins.llama.fi', free: true, endpoints: {\n pricesCurrent: { path: '/prices/current/{coins}' },\n }},\n { id: 'binance', category: 'market', name: 'Binance Public', baseUrl: 'https://api.binance.com', free: true, endpoints: {\n klines: { path: '/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}' },\n ticker: { path: '/api/v3/ticker/price?symbol={symbol}' },\n }},\n { id: 'cryptocompare', category: 'market', name: 'CryptoCompare', baseUrl: 'https://min-api.cryptocompare.com', free: true, endpoints: {\n histominute: { path: '/data/v2/histominute?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histohour: { path: '/data/v2/histohour?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histoday: { path: '/data/v2/histoday?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n }},\n { id: 'cmc', category: 'market', name: 'CoinMarketCap', baseUrl: 'https://pro-api.coinmarketcap.com/v1', free: false, endpoints: {\n quotes: { path: '/cryptocurrency/quotes/latest?symbol={symbol}', authLocation: 'header', authName: 'X-CMC_PRO_API_KEY', authValue: EMBEDDED_KEYS.CMC },\n }},\n\n // News\n { id: 'coinstats_news', category: 'news', name: 'CoinStats News', baseUrl: 'https://api.coinstats.app', free: true, endpoints: { feed: { path: '/public/v1/news' } }},\n { id: 'cryptopanic', category: 'news', name: 'CryptoPanic', baseUrl: 'https://cryptopanic.com', free: true, endpoints: { public: { path: '/api/v1/posts/?public=true' } }},\n { id: 'rss_cointelegraph', category: 'news', name: 'Cointelegraph RSS', baseUrl: 'https://cointelegraph.com', free: true, endpoints: { feed: { path: '/rss' } }},\n { id: 'rss_coindesk', category: 'news', name: 'CoinDesk RSS', baseUrl: 'https://www.coindesk.com', free: true, endpoints: { feed: { path: '/arc/outboundfeeds/rss/?outputType=xml' } }},\n { id: 'rss_decrypt', category: 'news', name: 'Decrypt RSS', baseUrl: 'https://decrypt.co', free: true, endpoints: { feed: { path: '/feed' } }},\n\n // Sentiment / F&G\n { id: 'altme_fng', category: 'sentiment', name: 'Alternative.me F&G', baseUrl: 'https://api.alternative.me', free: true, endpoints: {\n latest: { path: '/fng/', sampleParams: { limit: 1 } },\n history: { path: '/fng/', sampleParams: { limit: 30 } },\n }},\n { id: 'cfgi_v1', category: 'sentiment', name: 'CFGI API v1', baseUrl: 'https://api.cfgi.io', free: true, endpoints: {\n latest: { path: '/v1/fear-greed' },\n }},\n { id: 'cfgi_legacy', category: 'sentiment', name: 'CFGI Legacy', baseUrl: 'https://cfgi.io', free: true, endpoints: {\n latest: { path: '/api' },\n }},\n\n // On-chain / explorers\n { id: 'etherscan_primary', category: 'block_explorer', name: 'Etherscan', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN },\n }},\n { id: 'etherscan_backup', category: 'block_explorer', name: 'Etherscan Backup', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN_BACKUP },\n }},\n { id: 'blockscout_eth', category: 'block_explorer', name: 'Blockscout (ETH)', baseUrl: 'https://eth.blockscout.com', free: true, endpoints: {\n balanc",
35
  "note": "included as small text"
36
  }
37
  ],
 
57
  "e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f"
58
  ],
59
  "huggingface": [
60
+ "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
61
  ]
62
  },
63
  "notes": "This file was auto-generated. Keys/tokens are present as found in uploaded sources. Secure them as you wish."
api-resources/crypto_resources_unified_2025-11-11.json CHANGED
@@ -2084,7 +2084,7 @@
2084
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
2085
  "auth": {
2086
  "type": "apiKeyHeaderOptional",
2087
- "key": "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",
2088
  "header_name": "Authorization"
2089
  },
2090
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
@@ -2100,7 +2100,7 @@
2100
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
2101
  "auth": {
2102
  "type": "apiKeyHeaderOptional",
2103
- "key": "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",
2104
  "header_name": "Authorization"
2105
  },
2106
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
 
2084
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
2085
  "auth": {
2086
  "type": "apiKeyHeaderOptional",
2087
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
2088
  "header_name": "Authorization"
2089
  },
2090
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
 
2100
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
2101
  "auth": {
2102
  "type": "apiKeyHeaderOptional",
2103
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
2104
  "header_name": "Authorization"
2105
  },
2106
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
api/HF_IMPLEMENTATION_COMPLETE.md CHANGED
@@ -47,7 +47,7 @@
47
 
48
  #### 1. **Environment Configuration** (`.env`)
49
  ```env
50
- HUGGINGFACE_TOKEN=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
51
  ENABLE_SENTIMENT=true
52
  SENTIMENT_SOCIAL_MODEL=ElKulako/cryptobert
53
  SENTIMENT_NEWS_MODEL=kk08/CryptoBERT
 
47
 
48
  #### 1. **Environment Configuration** (`.env`)
49
  ```env
50
+ HUGGINGFACE_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
51
  ENABLE_SENTIMENT=true
52
  SENTIMENT_SOCIAL_MODEL=ElKulako/cryptobert
53
  SENTIMENT_NEWS_MODEL=kk08/CryptoBERT
api/QUICK_START.md CHANGED
@@ -138,7 +138,7 @@ Edit `.env` file to customize:
138
 
139
  ```env
140
  # HuggingFace Token (optional, for higher rate limits)
141
- HUGGINGFACE_TOKEN=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
142
 
143
  # Enable/disable local sentiment analysis
144
  ENABLE_SENTIMENT=true
 
138
 
139
  ```env
140
  # HuggingFace Token (optional, for higher rate limits)
141
+ HUGGINGFACE_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
142
 
143
  # Enable/disable local sentiment analysis
144
  ENABLE_SENTIMENT=true
api/all_apis_merged_2025.json CHANGED
@@ -31,7 +31,7 @@
31
  "zip_text_snippets": [
32
  {
33
  "filename": "crypto_resources.ts",
34
- "text_preview": "// crypto_resources.ts — unified TS with 150+ Hugging Face sources (dynamic catalog) + Safe F&G aggregator\n// English-only comments. Keys intentionally embedded per user request.\n\nexport type Category =\n | 'market'\n | 'news'\n | 'sentiment'\n | 'onchain'\n | 'block_explorer'\n | 'whales'\n | 'generic'\n | 'hf';\n\nexport interface EndpointDef {\n path: string;\n method?: 'GET' | 'POST';\n sampleParams?: Record<string, string | number>;\n authLocation?: 'header' | 'query';\n authName?: string;\n authValue?: string;\n contentType?: string;\n}\n\nexport interface CryptoResource {\n id: string;\n category: Category;\n name: string;\n baseUrl: string;\n free: boolean;\n rateLimit?: string;\n endpoints?: Record<string, EndpointDef>;\n}\n\nexport interface MarketQuote {\n id: string;\n symbol: string;\n name: string;\n price: number;\n change24h?: number;\n marketCap?: number;\n source: string;\n raw: any;\n}\n\nexport interface NewsItem {\n title: string;\n link: string;\n publishedAt?: string;\n source: string;\n}\n\nexport interface OHLCVRow {\n timestamp: number | string;\n open: number; high: number; low: number; close: number; volume: number;\n [k: string]: any;\n}\n\nexport interface FNGPoint {\n value: number; // 0..100\n classification: string;\n at?: string;\n source: string;\n raw?: any;\n}\n\nconst EMBEDDED_KEYS = {\n CMC: '04cf4b5b-9868-465c-8ba0-9f2e78c92eb1',\n ETHERSCAN: 'SZHYFZK2RR8H9TIMJBVW54V4H81K2Z2KR2',\n ETHERSCAN_BACKUP: 'T6IR8VJHX2NE6ZJW2S3FDVN1TYG4PYYI45',\n BSCSCAN: 'K62RKHGXTDCG53RU4MCG6XABIMJKTN19IT',\n CRYPTOCOMPARE: 'e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f',\n\n // Optional free keys provided by user (kept in-code per request)\n MESSARI: '',\n SANTIMENT: '',\n COINMETRICS: '',\n HUGGINGFACE: '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',\n};\n\nconst sleep = (ms: number) => new Promise(r => setTimeout(r, ms));\n\nclass HttpError extends Error {\n constructor(public status: number, public url: string, public body?: string) {\n super(`HTTP ${status} for ${url}`);\n }\n}\n\nfunction buildURL(base: string, path = '', params?: Record<string, any>): string {\n const hasQ = path.includes('?');\n const url = base.replace(/\\/+$/, '') + '/' + path.replace(/^\\/+/, '');\n if (!params || Object.keys(params).length === 0) return url;\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n qs.set(k, String(v));\n }\n return url + (hasQ ? '&' : '?') + qs.toString();\n}\n\nasync function fetchRaw(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<Response> {\n const { headers = {}, timeoutMs = 12000, retries = 1, retryDelayMs = 600, body, method = 'GET' } = opts;\n let lastErr: any;\n for (let attempt = 0; attempt <= retries; attempt++) {\n const ac = new AbortController();\n const id = setTimeout(() => ac.abort(), timeoutMs);\n try {\n const res = await fetch(url, { headers, signal: ac.signal, method, body });\n clearTimeout(id);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n if (res.status === 429 && attempt < retries) {\n await sleep(retryDelayMs * (attempt + 1));\n continue;\n }\n throw new HttpError(res.status, url, text);\n }\n return res;\n } catch (e) {\n clearTimeout(id);\n lastErr = e;\n if (attempt < retries) { await sleep(retryDelayMs * (attempt + 1)); continue; }\n }\n }\n throw lastErr;\n}\n\nasync function fetchJSON<T = any>(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<T> {\n const res = await fetchRaw(url, opts);\n const ct = res.headers.get('content-type') || '';\n if (ct.includes('json')) return res.json() as Promise<T>;\n const text = await res.text();\n try { return JSON.parse(text) as T; } catch { return text as unknown as T; }\n}\n\nfunction ensureNonEmpty(obj: any, label: string) {\n if (obj == null) throw new Error(`${label}: empty response`);\n if (Array.isArray(obj) && obj.length === 0) throw new Error(`${label}: empty array`);\n if (typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === 0)\n throw new Error(`${label}: empty object`);\n}\n\nfunction normalizeSymbol(q: string) { return q.trim().toLowerCase(); }\n\nfunction parseCSV(text: string): any[] {\n const lines = text.split(/\\r?\\n/).filter(Boolean);\n if (lines.length < 2) return [];\n const header = lines[0].split(',').map((s) => s.trim());\n const out: any[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cols = lines[i].split(',').map((s) => s.trim());\n const row: any = {};\n header.forEach((h, idx) => { row[h] = cols[idx]; });\n out.push(row);\n }\n return out;\n}\n\nfunction parseRssSimple(xml: string, source: string, limit = 20): NewsItem[] {\n const items: NewsItem[] = [];\n const chunks = xml.split(/<item[\\s>]/i).slice(1);\n for (const raw of chunks) {\n const item = raw.split(/<\\/item>/i)[0] || '';\n const get = (tag: string) => {\n const m = item.match(new RegExp(`<${tag}[^>]*>([\\\\s\\\\S]*?)</${tag}>`, 'i'));\n return m ? m[1].replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() : undefined;\n };\n const title = get('title'); const link = get('link') || get('guid'); const pub = get('pubDate') || get('updated') || get('dc:date');\n if (title && link) items.push({ title, link, publishedAt: pub, source });\n if (items.length >= limit) break;\n }\n return items;\n}\n\n/* ===================== BASE RESOURCES ===================== */\n\nexport const resources: CryptoResource[] = [\n // Market\n { id: 'coinpaprika', category: 'market', name: 'CoinPaprika', baseUrl: 'https://api.coinpaprika.com/v1', free: true, endpoints: {\n search: { path: '/search', sampleParams: { q: 'bitcoin', c: 'currencies', limit: 1 } },\n tickerById: { path: '/tickers/{id}', sampleParams: { quotes: 'USD' } },\n }},\n { id: 'coincap', category: 'market', name: 'CoinCap', baseUrl: 'https://api.coincap.io/v2', free: true, endpoints: {\n assets: { path: '/assets', sampleParams: { search: 'bitcoin', limit: 1 } },\n assetById: { path: '/assets/{id}' },\n }},\n { id: 'coingecko', category: 'market', name: 'CoinGecko', baseUrl: 'https://api.coingecko.com/api/v3', free: true, endpoints: {\n simplePrice: { path: '/simple/price?ids={ids}&vs_currencies={fiats}' },\n }},\n { id: 'defillama', category: 'market', name: 'DefiLlama (Prices)', baseUrl: 'https://coins.llama.fi', free: true, endpoints: {\n pricesCurrent: { path: '/prices/current/{coins}' },\n }},\n { id: 'binance', category: 'market', name: 'Binance Public', baseUrl: 'https://api.binance.com', free: true, endpoints: {\n klines: { path: '/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}' },\n ticker: { path: '/api/v3/ticker/price?symbol={symbol}' },\n }},\n { id: 'cryptocompare', category: 'market', name: 'CryptoCompare', baseUrl: 'https://min-api.cryptocompare.com', free: true, endpoints: {\n histominute: { path: '/data/v2/histominute?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histohour: { path: '/data/v2/histohour?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histoday: { path: '/data/v2/histoday?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n }},\n { id: 'cmc', category: 'market', name: 'CoinMarketCap', baseUrl: 'https://pro-api.coinmarketcap.com/v1', free: false, endpoints: {\n quotes: { path: '/cryptocurrency/quotes/latest?symbol={symbol}', authLocation: 'header', authName: 'X-CMC_PRO_API_KEY', authValue: EMBEDDED_KEYS.CMC },\n }},\n\n // News\n { id: 'coinstats_news', category: 'news', name: 'CoinStats News', baseUrl: 'https://api.coinstats.app', free: true, endpoints: { feed: { path: '/public/v1/news' } }},\n { id: 'cryptopanic', category: 'news', name: 'CryptoPanic', baseUrl: 'https://cryptopanic.com', free: true, endpoints: { public: { path: '/api/v1/posts/?public=true' } }},\n { id: 'rss_cointelegraph', category: 'news', name: 'Cointelegraph RSS', baseUrl: 'https://cointelegraph.com', free: true, endpoints: { feed: { path: '/rss' } }},\n { id: 'rss_coindesk', category: 'news', name: 'CoinDesk RSS', baseUrl: 'https://www.coindesk.com', free: true, endpoints: { feed: { path: '/arc/outboundfeeds/rss/?outputType=xml' } }},\n { id: 'rss_decrypt', category: 'news', name: 'Decrypt RSS', baseUrl: 'https://decrypt.co', free: true, endpoints: { feed: { path: '/feed' } }},\n\n // Sentiment / F&G\n { id: 'altme_fng', category: 'sentiment', name: 'Alternative.me F&G', baseUrl: 'https://api.alternative.me', free: true, endpoints: {\n latest: { path: '/fng/', sampleParams: { limit: 1 } },\n history: { path: '/fng/', sampleParams: { limit: 30 } },\n }},\n { id: 'cfgi_v1', category: 'sentiment', name: 'CFGI API v1', baseUrl: 'https://api.cfgi.io', free: true, endpoints: {\n latest: { path: '/v1/fear-greed' },\n }},\n { id: 'cfgi_legacy', category: 'sentiment', name: 'CFGI Legacy', baseUrl: 'https://cfgi.io', free: true, endpoints: {\n latest: { path: '/api' },\n }},\n\n // On-chain / explorers\n { id: 'etherscan_primary', category: 'block_explorer', name: 'Etherscan', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN },\n }},\n { id: 'etherscan_backup', category: 'block_explorer', name: 'Etherscan Backup', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN_BACKUP },\n }},\n { id: 'blockscout_eth', category: 'block_explorer', name: 'Blockscout (ETH)', baseUrl: 'https://eth.blockscout.com', free: true, endpoints: {\n balanc",
35
  "note": "included as small text"
36
  }
37
  ],
@@ -57,7 +57,7 @@
57
  "e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f"
58
  ],
59
  "huggingface": [
60
- "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"
61
  ]
62
  },
63
  "notes": "This file was auto-generated. Keys/tokens are present as found in uploaded sources. Secure them as you wish."
 
31
  "zip_text_snippets": [
32
  {
33
  "filename": "crypto_resources.ts",
34
+ "text_preview": "// crypto_resources.ts — unified TS with 150+ Hugging Face sources (dynamic catalog) + Safe F&G aggregator\n// English-only comments. Keys intentionally embedded per user request.\n\nexport type Category =\n | 'market'\n | 'news'\n | 'sentiment'\n | 'onchain'\n | 'block_explorer'\n | 'whales'\n | 'generic'\n | 'hf';\n\nexport interface EndpointDef {\n path: string;\n method?: 'GET' | 'POST';\n sampleParams?: Record<string, string | number>;\n authLocation?: 'header' | 'query';\n authName?: string;\n authValue?: string;\n contentType?: string;\n}\n\nexport interface CryptoResource {\n id: string;\n category: Category;\n name: string;\n baseUrl: string;\n free: boolean;\n rateLimit?: string;\n endpoints?: Record<string, EndpointDef>;\n}\n\nexport interface MarketQuote {\n id: string;\n symbol: string;\n name: string;\n price: number;\n change24h?: number;\n marketCap?: number;\n source: string;\n raw: any;\n}\n\nexport interface NewsItem {\n title: string;\n link: string;\n publishedAt?: string;\n source: string;\n}\n\nexport interface OHLCVRow {\n timestamp: number | string;\n open: number; high: number; low: number; close: number; volume: number;\n [k: string]: any;\n}\n\nexport interface FNGPoint {\n value: number; // 0..100\n classification: string;\n at?: string;\n source: string;\n raw?: any;\n}\n\nconst EMBEDDED_KEYS = {\n CMC: '04cf4b5b-9868-465c-8ba0-9f2e78c92eb1',\n ETHERSCAN: 'SZHYFZK2RR8H9TIMJBVW54V4H81K2Z2KR2',\n ETHERSCAN_BACKUP: 'T6IR8VJHX2NE6ZJW2S3FDVN1TYG4PYYI45',\n BSCSCAN: 'K62RKHGXTDCG53RU4MCG6XABIMJKTN19IT',\n CRYPTOCOMPARE: 'e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f',\n\n // Optional free keys provided by user (kept in-code per request)\n MESSARI: '',\n SANTIMENT: '',\n COINMETRICS: '',\n HUGGINGFACE: 'hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',\n};\n\nconst sleep = (ms: number) => new Promise(r => setTimeout(r, ms));\n\nclass HttpError extends Error {\n constructor(public status: number, public url: string, public body?: string) {\n super(`HTTP ${status} for ${url}`);\n }\n}\n\nfunction buildURL(base: string, path = '', params?: Record<string, any>): string {\n const hasQ = path.includes('?');\n const url = base.replace(/\\/+$/, '') + '/' + path.replace(/^\\/+/, '');\n if (!params || Object.keys(params).length === 0) return url;\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n qs.set(k, String(v));\n }\n return url + (hasQ ? '&' : '?') + qs.toString();\n}\n\nasync function fetchRaw(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<Response> {\n const { headers = {}, timeoutMs = 12000, retries = 1, retryDelayMs = 600, body, method = 'GET' } = opts;\n let lastErr: any;\n for (let attempt = 0; attempt <= retries; attempt++) {\n const ac = new AbortController();\n const id = setTimeout(() => ac.abort(), timeoutMs);\n try {\n const res = await fetch(url, { headers, signal: ac.signal, method, body });\n clearTimeout(id);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n if (res.status === 429 && attempt < retries) {\n await sleep(retryDelayMs * (attempt + 1));\n continue;\n }\n throw new HttpError(res.status, url, text);\n }\n return res;\n } catch (e) {\n clearTimeout(id);\n lastErr = e;\n if (attempt < retries) { await sleep(retryDelayMs * (attempt + 1)); continue; }\n }\n }\n throw lastErr;\n}\n\nasync function fetchJSON<T = any>(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<T> {\n const res = await fetchRaw(url, opts);\n const ct = res.headers.get('content-type') || '';\n if (ct.includes('json')) return res.json() as Promise<T>;\n const text = await res.text();\n try { return JSON.parse(text) as T; } catch { return text as unknown as T; }\n}\n\nfunction ensureNonEmpty(obj: any, label: string) {\n if (obj == null) throw new Error(`${label}: empty response`);\n if (Array.isArray(obj) && obj.length === 0) throw new Error(`${label}: empty array`);\n if (typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === 0)\n throw new Error(`${label}: empty object`);\n}\n\nfunction normalizeSymbol(q: string) { return q.trim().toLowerCase(); }\n\nfunction parseCSV(text: string): any[] {\n const lines = text.split(/\\r?\\n/).filter(Boolean);\n if (lines.length < 2) return [];\n const header = lines[0].split(',').map((s) => s.trim());\n const out: any[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cols = lines[i].split(',').map((s) => s.trim());\n const row: any = {};\n header.forEach((h, idx) => { row[h] = cols[idx]; });\n out.push(row);\n }\n return out;\n}\n\nfunction parseRssSimple(xml: string, source: string, limit = 20): NewsItem[] {\n const items: NewsItem[] = [];\n const chunks = xml.split(/<item[\\s>]/i).slice(1);\n for (const raw of chunks) {\n const item = raw.split(/<\\/item>/i)[0] || '';\n const get = (tag: string) => {\n const m = item.match(new RegExp(`<${tag}[^>]*>([\\\\s\\\\S]*?)</${tag}>`, 'i'));\n return m ? m[1].replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() : undefined;\n };\n const title = get('title'); const link = get('link') || get('guid'); const pub = get('pubDate') || get('updated') || get('dc:date');\n if (title && link) items.push({ title, link, publishedAt: pub, source });\n if (items.length >= limit) break;\n }\n return items;\n}\n\n/* ===================== BASE RESOURCES ===================== */\n\nexport const resources: CryptoResource[] = [\n // Market\n { id: 'coinpaprika', category: 'market', name: 'CoinPaprika', baseUrl: 'https://api.coinpaprika.com/v1', free: true, endpoints: {\n search: { path: '/search', sampleParams: { q: 'bitcoin', c: 'currencies', limit: 1 } },\n tickerById: { path: '/tickers/{id}', sampleParams: { quotes: 'USD' } },\n }},\n { id: 'coincap', category: 'market', name: 'CoinCap', baseUrl: 'https://api.coincap.io/v2', free: true, endpoints: {\n assets: { path: '/assets', sampleParams: { search: 'bitcoin', limit: 1 } },\n assetById: { path: '/assets/{id}' },\n }},\n { id: 'coingecko', category: 'market', name: 'CoinGecko', baseUrl: 'https://api.coingecko.com/api/v3', free: true, endpoints: {\n simplePrice: { path: '/simple/price?ids={ids}&vs_currencies={fiats}' },\n }},\n { id: 'defillama', category: 'market', name: 'DefiLlama (Prices)', baseUrl: 'https://coins.llama.fi', free: true, endpoints: {\n pricesCurrent: { path: '/prices/current/{coins}' },\n }},\n { id: 'binance', category: 'market', name: 'Binance Public', baseUrl: 'https://api.binance.com', free: true, endpoints: {\n klines: { path: '/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}' },\n ticker: { path: '/api/v3/ticker/price?symbol={symbol}' },\n }},\n { id: 'cryptocompare', category: 'market', name: 'CryptoCompare', baseUrl: 'https://min-api.cryptocompare.com', free: true, endpoints: {\n histominute: { path: '/data/v2/histominute?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histohour: { path: '/data/v2/histohour?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histoday: { path: '/data/v2/histoday?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n }},\n { id: 'cmc', category: 'market', name: 'CoinMarketCap', baseUrl: 'https://pro-api.coinmarketcap.com/v1', free: false, endpoints: {\n quotes: { path: '/cryptocurrency/quotes/latest?symbol={symbol}', authLocation: 'header', authName: 'X-CMC_PRO_API_KEY', authValue: EMBEDDED_KEYS.CMC },\n }},\n\n // News\n { id: 'coinstats_news', category: 'news', name: 'CoinStats News', baseUrl: 'https://api.coinstats.app', free: true, endpoints: { feed: { path: '/public/v1/news' } }},\n { id: 'cryptopanic', category: 'news', name: 'CryptoPanic', baseUrl: 'https://cryptopanic.com', free: true, endpoints: { public: { path: '/api/v1/posts/?public=true' } }},\n { id: 'rss_cointelegraph', category: 'news', name: 'Cointelegraph RSS', baseUrl: 'https://cointelegraph.com', free: true, endpoints: { feed: { path: '/rss' } }},\n { id: 'rss_coindesk', category: 'news', name: 'CoinDesk RSS', baseUrl: 'https://www.coindesk.com', free: true, endpoints: { feed: { path: '/arc/outboundfeeds/rss/?outputType=xml' } }},\n { id: 'rss_decrypt', category: 'news', name: 'Decrypt RSS', baseUrl: 'https://decrypt.co', free: true, endpoints: { feed: { path: '/feed' } }},\n\n // Sentiment / F&G\n { id: 'altme_fng', category: 'sentiment', name: 'Alternative.me F&G', baseUrl: 'https://api.alternative.me', free: true, endpoints: {\n latest: { path: '/fng/', sampleParams: { limit: 1 } },\n history: { path: '/fng/', sampleParams: { limit: 30 } },\n }},\n { id: 'cfgi_v1', category: 'sentiment', name: 'CFGI API v1', baseUrl: 'https://api.cfgi.io', free: true, endpoints: {\n latest: { path: '/v1/fear-greed' },\n }},\n { id: 'cfgi_legacy', category: 'sentiment', name: 'CFGI Legacy', baseUrl: 'https://cfgi.io', free: true, endpoints: {\n latest: { path: '/api' },\n }},\n\n // On-chain / explorers\n { id: 'etherscan_primary', category: 'block_explorer', name: 'Etherscan', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN },\n }},\n { id: 'etherscan_backup', category: 'block_explorer', name: 'Etherscan Backup', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN_BACKUP },\n }},\n { id: 'blockscout_eth', category: 'block_explorer', name: 'Blockscout (ETH)', baseUrl: 'https://eth.blockscout.com', free: true, endpoints: {\n balanc",
35
  "note": "included as small text"
36
  }
37
  ],
 
57
  "e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f"
58
  ],
59
  "huggingface": [
60
+ "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
61
  ]
62
  },
63
  "notes": "This file was auto-generated. Keys/tokens are present as found in uploaded sources. Secure them as you wish."
api/crypto_resources_unified_2025-11-11.json CHANGED
@@ -1699,7 +1699,7 @@
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
- "key": "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",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
@@ -1715,7 +1715,7 @@
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
- "key": "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",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
 
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
 
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
archive/all_apis_merged_2025.json CHANGED
@@ -31,7 +31,7 @@
31
  "zip_text_snippets": [
32
  {
33
  "filename": "crypto_resources.ts",
34
- "text_preview": "// crypto_resources.ts — unified TS with 150+ Hugging Face sources (dynamic catalog) + Safe F&G aggregator\n// English-only comments. Keys intentionally embedded per user request.\n\nexport type Category =\n | 'market'\n | 'news'\n | 'sentiment'\n | 'onchain'\n | 'block_explorer'\n | 'whales'\n | 'generic'\n | 'hf';\n\nexport interface EndpointDef {\n path: string;\n method?: 'GET' | 'POST';\n sampleParams?: Record<string, string | number>;\n authLocation?: 'header' | 'query';\n authName?: string;\n authValue?: string;\n contentType?: string;\n}\n\nexport interface CryptoResource {\n id: string;\n category: Category;\n name: string;\n baseUrl: string;\n free: boolean;\n rateLimit?: string;\n endpoints?: Record<string, EndpointDef>;\n}\n\nexport interface MarketQuote {\n id: string;\n symbol: string;\n name: string;\n price: number;\n change24h?: number;\n marketCap?: number;\n source: string;\n raw: any;\n}\n\nexport interface NewsItem {\n title: string;\n link: string;\n publishedAt?: string;\n source: string;\n}\n\nexport interface OHLCVRow {\n timestamp: number | string;\n open: number; high: number; low: number; close: number; volume: number;\n [k: string]: any;\n}\n\nexport interface FNGPoint {\n value: number; // 0..100\n classification: string;\n at?: string;\n source: string;\n raw?: any;\n}\n\nconst EMBEDDED_KEYS = {\n CMC: '04cf4b5b-9868-465c-8ba0-9f2e78c92eb1',\n ETHERSCAN: 'SZHYFZK2RR8H9TIMJBVW54V4H81K2Z2KR2',\n ETHERSCAN_BACKUP: 'T6IR8VJHX2NE6ZJW2S3FDVN1TYG4PYYI45',\n BSCSCAN: 'K62RKHGXTDCG53RU4MCG6XABIMJKTN19IT',\n CRYPTOCOMPARE: 'e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f',\n\n // Optional free keys provided by user (kept in-code per request)\n MESSARI: '',\n SANTIMENT: '',\n COINMETRICS: '',\n HUGGINGFACE: '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',\n};\n\nconst sleep = (ms: number) => new Promise(r => setTimeout(r, ms));\n\nclass HttpError extends Error {\n constructor(public status: number, public url: string, public body?: string) {\n super(`HTTP ${status} for ${url}`);\n }\n}\n\nfunction buildURL(base: string, path = '', params?: Record<string, any>): string {\n const hasQ = path.includes('?');\n const url = base.replace(/\\/+$/, '') + '/' + path.replace(/^\\/+/, '');\n if (!params || Object.keys(params).length === 0) return url;\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n qs.set(k, String(v));\n }\n return url + (hasQ ? '&' : '?') + qs.toString();\n}\n\nasync function fetchRaw(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<Response> {\n const { headers = {}, timeoutMs = 12000, retries = 1, retryDelayMs = 600, body, method = 'GET' } = opts;\n let lastErr: any;\n for (let attempt = 0; attempt <= retries; attempt++) {\n const ac = new AbortController();\n const id = setTimeout(() => ac.abort(), timeoutMs);\n try {\n const res = await fetch(url, { headers, signal: ac.signal, method, body });\n clearTimeout(id);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n if (res.status === 429 && attempt < retries) {\n await sleep(retryDelayMs * (attempt + 1));\n continue;\n }\n throw new HttpError(res.status, url, text);\n }\n return res;\n } catch (e) {\n clearTimeout(id);\n lastErr = e;\n if (attempt < retries) { await sleep(retryDelayMs * (attempt + 1)); continue; }\n }\n }\n throw lastErr;\n}\n\nasync function fetchJSON<T = any>(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<T> {\n const res = await fetchRaw(url, opts);\n const ct = res.headers.get('content-type') || '';\n if (ct.includes('json')) return res.json() as Promise<T>;\n const text = await res.text();\n try { return JSON.parse(text) as T; } catch { return text as unknown as T; }\n}\n\nfunction ensureNonEmpty(obj: any, label: string) {\n if (obj == null) throw new Error(`${label}: empty response`);\n if (Array.isArray(obj) && obj.length === 0) throw new Error(`${label}: empty array`);\n if (typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === 0)\n throw new Error(`${label}: empty object`);\n}\n\nfunction normalizeSymbol(q: string) { return q.trim().toLowerCase(); }\n\nfunction parseCSV(text: string): any[] {\n const lines = text.split(/\\r?\\n/).filter(Boolean);\n if (lines.length < 2) return [];\n const header = lines[0].split(',').map((s) => s.trim());\n const out: any[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cols = lines[i].split(',').map((s) => s.trim());\n const row: any = {};\n header.forEach((h, idx) => { row[h] = cols[idx]; });\n out.push(row);\n }\n return out;\n}\n\nfunction parseRssSimple(xml: string, source: string, limit = 20): NewsItem[] {\n const items: NewsItem[] = [];\n const chunks = xml.split(/<item[\\s>]/i).slice(1);\n for (const raw of chunks) {\n const item = raw.split(/<\\/item>/i)[0] || '';\n const get = (tag: string) => {\n const m = item.match(new RegExp(`<${tag}[^>]*>([\\\\s\\\\S]*?)</${tag}>`, 'i'));\n return m ? m[1].replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() : undefined;\n };\n const title = get('title'); const link = get('link') || get('guid'); const pub = get('pubDate') || get('updated') || get('dc:date');\n if (title && link) items.push({ title, link, publishedAt: pub, source });\n if (items.length >= limit) break;\n }\n return items;\n}\n\n/* ===================== BASE RESOURCES ===================== */\n\nexport const resources: CryptoResource[] = [\n // Market\n { id: 'coinpaprika', category: 'market', name: 'CoinPaprika', baseUrl: 'https://api.coinpaprika.com/v1', free: true, endpoints: {\n search: { path: '/search', sampleParams: { q: 'bitcoin', c: 'currencies', limit: 1 } },\n tickerById: { path: '/tickers/{id}', sampleParams: { quotes: 'USD' } },\n }},\n { id: 'coincap', category: 'market', name: 'CoinCap', baseUrl: 'https://api.coincap.io/v2', free: true, endpoints: {\n assets: { path: '/assets', sampleParams: { search: 'bitcoin', limit: 1 } },\n assetById: { path: '/assets/{id}' },\n }},\n { id: 'coingecko', category: 'market', name: 'CoinGecko', baseUrl: 'https://api.coingecko.com/api/v3', free: true, endpoints: {\n simplePrice: { path: '/simple/price?ids={ids}&vs_currencies={fiats}' },\n }},\n { id: 'defillama', category: 'market', name: 'DefiLlama (Prices)', baseUrl: 'https://coins.llama.fi', free: true, endpoints: {\n pricesCurrent: { path: '/prices/current/{coins}' },\n }},\n { id: 'binance', category: 'market', name: 'Binance Public', baseUrl: 'https://api.binance.com', free: true, endpoints: {\n klines: { path: '/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}' },\n ticker: { path: '/api/v3/ticker/price?symbol={symbol}' },\n }},\n { id: 'cryptocompare', category: 'market', name: 'CryptoCompare', baseUrl: 'https://min-api.cryptocompare.com', free: true, endpoints: {\n histominute: { path: '/data/v2/histominute?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histohour: { path: '/data/v2/histohour?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histoday: { path: '/data/v2/histoday?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n }},\n { id: 'cmc', category: 'market', name: 'CoinMarketCap', baseUrl: 'https://pro-api.coinmarketcap.com/v1', free: false, endpoints: {\n quotes: { path: '/cryptocurrency/quotes/latest?symbol={symbol}', authLocation: 'header', authName: 'X-CMC_PRO_API_KEY', authValue: EMBEDDED_KEYS.CMC },\n }},\n\n // News\n { id: 'coinstats_news', category: 'news', name: 'CoinStats News', baseUrl: 'https://api.coinstats.app', free: true, endpoints: { feed: { path: '/public/v1/news' } }},\n { id: 'cryptopanic', category: 'news', name: 'CryptoPanic', baseUrl: 'https://cryptopanic.com', free: true, endpoints: { public: { path: '/api/v1/posts/?public=true' } }},\n { id: 'rss_cointelegraph', category: 'news', name: 'Cointelegraph RSS', baseUrl: 'https://cointelegraph.com', free: true, endpoints: { feed: { path: '/rss' } }},\n { id: 'rss_coindesk', category: 'news', name: 'CoinDesk RSS', baseUrl: 'https://www.coindesk.com', free: true, endpoints: { feed: { path: '/arc/outboundfeeds/rss/?outputType=xml' } }},\n { id: 'rss_decrypt', category: 'news', name: 'Decrypt RSS', baseUrl: 'https://decrypt.co', free: true, endpoints: { feed: { path: '/feed' } }},\n\n // Sentiment / F&G\n { id: 'altme_fng', category: 'sentiment', name: 'Alternative.me F&G', baseUrl: 'https://api.alternative.me', free: true, endpoints: {\n latest: { path: '/fng/', sampleParams: { limit: 1 } },\n history: { path: '/fng/', sampleParams: { limit: 30 } },\n }},\n { id: 'cfgi_v1', category: 'sentiment', name: 'CFGI API v1', baseUrl: 'https://api.cfgi.io', free: true, endpoints: {\n latest: { path: '/v1/fear-greed' },\n }},\n { id: 'cfgi_legacy', category: 'sentiment', name: 'CFGI Legacy', baseUrl: 'https://cfgi.io', free: true, endpoints: {\n latest: { path: '/api' },\n }},\n\n // On-chain / explorers\n { id: 'etherscan_primary', category: 'block_explorer', name: 'Etherscan', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN },\n }},\n { id: 'etherscan_backup', category: 'block_explorer', name: 'Etherscan Backup', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN_BACKUP },\n }},\n { id: 'blockscout_eth', category: 'block_explorer', name: 'Blockscout (ETH)', baseUrl: 'https://eth.blockscout.com', free: true, endpoints: {\n balanc",
35
  "note": "included as small text"
36
  }
37
  ],
@@ -57,7 +57,7 @@
57
  "e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f"
58
  ],
59
  "huggingface": [
60
- "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"
61
  ]
62
  },
63
  "notes": "This file was auto-generated. Keys/tokens are present as found in uploaded sources. Secure them as you wish."
 
31
  "zip_text_snippets": [
32
  {
33
  "filename": "crypto_resources.ts",
34
+ "text_preview": "// crypto_resources.ts — unified TS with 150+ Hugging Face sources (dynamic catalog) + Safe F&G aggregator\n// English-only comments. Keys intentionally embedded per user request.\n\nexport type Category =\n | 'market'\n | 'news'\n | 'sentiment'\n | 'onchain'\n | 'block_explorer'\n | 'whales'\n | 'generic'\n | 'hf';\n\nexport interface EndpointDef {\n path: string;\n method?: 'GET' | 'POST';\n sampleParams?: Record<string, string | number>;\n authLocation?: 'header' | 'query';\n authName?: string;\n authValue?: string;\n contentType?: string;\n}\n\nexport interface CryptoResource {\n id: string;\n category: Category;\n name: string;\n baseUrl: string;\n free: boolean;\n rateLimit?: string;\n endpoints?: Record<string, EndpointDef>;\n}\n\nexport interface MarketQuote {\n id: string;\n symbol: string;\n name: string;\n price: number;\n change24h?: number;\n marketCap?: number;\n source: string;\n raw: any;\n}\n\nexport interface NewsItem {\n title: string;\n link: string;\n publishedAt?: string;\n source: string;\n}\n\nexport interface OHLCVRow {\n timestamp: number | string;\n open: number; high: number; low: number; close: number; volume: number;\n [k: string]: any;\n}\n\nexport interface FNGPoint {\n value: number; // 0..100\n classification: string;\n at?: string;\n source: string;\n raw?: any;\n}\n\nconst EMBEDDED_KEYS = {\n CMC: '04cf4b5b-9868-465c-8ba0-9f2e78c92eb1',\n ETHERSCAN: 'SZHYFZK2RR8H9TIMJBVW54V4H81K2Z2KR2',\n ETHERSCAN_BACKUP: 'T6IR8VJHX2NE6ZJW2S3FDVN1TYG4PYYI45',\n BSCSCAN: 'K62RKHGXTDCG53RU4MCG6XABIMJKTN19IT',\n CRYPTOCOMPARE: 'e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f',\n\n // Optional free keys provided by user (kept in-code per request)\n MESSARI: '',\n SANTIMENT: '',\n COINMETRICS: '',\n HUGGINGFACE: 'hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',\n};\n\nconst sleep = (ms: number) => new Promise(r => setTimeout(r, ms));\n\nclass HttpError extends Error {\n constructor(public status: number, public url: string, public body?: string) {\n super(`HTTP ${status} for ${url}`);\n }\n}\n\nfunction buildURL(base: string, path = '', params?: Record<string, any>): string {\n const hasQ = path.includes('?');\n const url = base.replace(/\\/+$/, '') + '/' + path.replace(/^\\/+/, '');\n if (!params || Object.keys(params).length === 0) return url;\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n qs.set(k, String(v));\n }\n return url + (hasQ ? '&' : '?') + qs.toString();\n}\n\nasync function fetchRaw(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<Response> {\n const { headers = {}, timeoutMs = 12000, retries = 1, retryDelayMs = 600, body, method = 'GET' } = opts;\n let lastErr: any;\n for (let attempt = 0; attempt <= retries; attempt++) {\n const ac = new AbortController();\n const id = setTimeout(() => ac.abort(), timeoutMs);\n try {\n const res = await fetch(url, { headers, signal: ac.signal, method, body });\n clearTimeout(id);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n if (res.status === 429 && attempt < retries) {\n await sleep(retryDelayMs * (attempt + 1));\n continue;\n }\n throw new HttpError(res.status, url, text);\n }\n return res;\n } catch (e) {\n clearTimeout(id);\n lastErr = e;\n if (attempt < retries) { await sleep(retryDelayMs * (attempt + 1)); continue; }\n }\n }\n throw lastErr;\n}\n\nasync function fetchJSON<T = any>(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<T> {\n const res = await fetchRaw(url, opts);\n const ct = res.headers.get('content-type') || '';\n if (ct.includes('json')) return res.json() as Promise<T>;\n const text = await res.text();\n try { return JSON.parse(text) as T; } catch { return text as unknown as T; }\n}\n\nfunction ensureNonEmpty(obj: any, label: string) {\n if (obj == null) throw new Error(`${label}: empty response`);\n if (Array.isArray(obj) && obj.length === 0) throw new Error(`${label}: empty array`);\n if (typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === 0)\n throw new Error(`${label}: empty object`);\n}\n\nfunction normalizeSymbol(q: string) { return q.trim().toLowerCase(); }\n\nfunction parseCSV(text: string): any[] {\n const lines = text.split(/\\r?\\n/).filter(Boolean);\n if (lines.length < 2) return [];\n const header = lines[0].split(',').map((s) => s.trim());\n const out: any[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cols = lines[i].split(',').map((s) => s.trim());\n const row: any = {};\n header.forEach((h, idx) => { row[h] = cols[idx]; });\n out.push(row);\n }\n return out;\n}\n\nfunction parseRssSimple(xml: string, source: string, limit = 20): NewsItem[] {\n const items: NewsItem[] = [];\n const chunks = xml.split(/<item[\\s>]/i).slice(1);\n for (const raw of chunks) {\n const item = raw.split(/<\\/item>/i)[0] || '';\n const get = (tag: string) => {\n const m = item.match(new RegExp(`<${tag}[^>]*>([\\\\s\\\\S]*?)</${tag}>`, 'i'));\n return m ? m[1].replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() : undefined;\n };\n const title = get('title'); const link = get('link') || get('guid'); const pub = get('pubDate') || get('updated') || get('dc:date');\n if (title && link) items.push({ title, link, publishedAt: pub, source });\n if (items.length >= limit) break;\n }\n return items;\n}\n\n/* ===================== BASE RESOURCES ===================== */\n\nexport const resources: CryptoResource[] = [\n // Market\n { id: 'coinpaprika', category: 'market', name: 'CoinPaprika', baseUrl: 'https://api.coinpaprika.com/v1', free: true, endpoints: {\n search: { path: '/search', sampleParams: { q: 'bitcoin', c: 'currencies', limit: 1 } },\n tickerById: { path: '/tickers/{id}', sampleParams: { quotes: 'USD' } },\n }},\n { id: 'coincap', category: 'market', name: 'CoinCap', baseUrl: 'https://api.coincap.io/v2', free: true, endpoints: {\n assets: { path: '/assets', sampleParams: { search: 'bitcoin', limit: 1 } },\n assetById: { path: '/assets/{id}' },\n }},\n { id: 'coingecko', category: 'market', name: 'CoinGecko', baseUrl: 'https://api.coingecko.com/api/v3', free: true, endpoints: {\n simplePrice: { path: '/simple/price?ids={ids}&vs_currencies={fiats}' },\n }},\n { id: 'defillama', category: 'market', name: 'DefiLlama (Prices)', baseUrl: 'https://coins.llama.fi', free: true, endpoints: {\n pricesCurrent: { path: '/prices/current/{coins}' },\n }},\n { id: 'binance', category: 'market', name: 'Binance Public', baseUrl: 'https://api.binance.com', free: true, endpoints: {\n klines: { path: '/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}' },\n ticker: { path: '/api/v3/ticker/price?symbol={symbol}' },\n }},\n { id: 'cryptocompare', category: 'market', name: 'CryptoCompare', baseUrl: 'https://min-api.cryptocompare.com', free: true, endpoints: {\n histominute: { path: '/data/v2/histominute?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histohour: { path: '/data/v2/histohour?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histoday: { path: '/data/v2/histoday?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n }},\n { id: 'cmc', category: 'market', name: 'CoinMarketCap', baseUrl: 'https://pro-api.coinmarketcap.com/v1', free: false, endpoints: {\n quotes: { path: '/cryptocurrency/quotes/latest?symbol={symbol}', authLocation: 'header', authName: 'X-CMC_PRO_API_KEY', authValue: EMBEDDED_KEYS.CMC },\n }},\n\n // News\n { id: 'coinstats_news', category: 'news', name: 'CoinStats News', baseUrl: 'https://api.coinstats.app', free: true, endpoints: { feed: { path: '/public/v1/news' } }},\n { id: 'cryptopanic', category: 'news', name: 'CryptoPanic', baseUrl: 'https://cryptopanic.com', free: true, endpoints: { public: { path: '/api/v1/posts/?public=true' } }},\n { id: 'rss_cointelegraph', category: 'news', name: 'Cointelegraph RSS', baseUrl: 'https://cointelegraph.com', free: true, endpoints: { feed: { path: '/rss' } }},\n { id: 'rss_coindesk', category: 'news', name: 'CoinDesk RSS', baseUrl: 'https://www.coindesk.com', free: true, endpoints: { feed: { path: '/arc/outboundfeeds/rss/?outputType=xml' } }},\n { id: 'rss_decrypt', category: 'news', name: 'Decrypt RSS', baseUrl: 'https://decrypt.co', free: true, endpoints: { feed: { path: '/feed' } }},\n\n // Sentiment / F&G\n { id: 'altme_fng', category: 'sentiment', name: 'Alternative.me F&G', baseUrl: 'https://api.alternative.me', free: true, endpoints: {\n latest: { path: '/fng/', sampleParams: { limit: 1 } },\n history: { path: '/fng/', sampleParams: { limit: 30 } },\n }},\n { id: 'cfgi_v1', category: 'sentiment', name: 'CFGI API v1', baseUrl: 'https://api.cfgi.io', free: true, endpoints: {\n latest: { path: '/v1/fear-greed' },\n }},\n { id: 'cfgi_legacy', category: 'sentiment', name: 'CFGI Legacy', baseUrl: 'https://cfgi.io', free: true, endpoints: {\n latest: { path: '/api' },\n }},\n\n // On-chain / explorers\n { id: 'etherscan_primary', category: 'block_explorer', name: 'Etherscan', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN },\n }},\n { id: 'etherscan_backup', category: 'block_explorer', name: 'Etherscan Backup', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN_BACKUP },\n }},\n { id: 'blockscout_eth', category: 'block_explorer', name: 'Blockscout (ETH)', baseUrl: 'https://eth.blockscout.com', free: true, endpoints: {\n balanc",
35
  "note": "included as small text"
36
  }
37
  ],
 
57
  "e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f"
58
  ],
59
  "huggingface": [
60
+ "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
61
  ]
62
  },
63
  "notes": "This file was auto-generated. Keys/tokens are present as found in uploaded sources. Secure them as you wish."
archive/docs/CRYPTOBERT_QUICK_REFERENCE.md CHANGED
@@ -21,7 +21,7 @@ python3 -c "import ai_models; ai_models.initialize_models(); print(ai_models.ana
21
  |------|-------|
22
  | **Model** | ElKulako/CryptoBERT |
23
  | **ID** | `hf_model_elkulako_cryptobert` |
24
- | **Token** | `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` |
25
  | **Status** | CONDITIONALLY_AVAILABLE |
26
 
27
  ---
@@ -53,7 +53,7 @@ print(f"Loaded: {info['loaded_models']['crypto_sentiment']}")
53
 
54
  ### Setup
55
  ```bash
56
- export HF_TOKEN="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"
57
  ./setup_cryptobert.sh
58
  ```
59
 
 
21
  |------|-------|
22
  | **Model** | ElKulako/CryptoBERT |
23
  | **ID** | `hf_model_elkulako_cryptobert` |
24
+ | **Token** | `hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx` |
25
  | **Status** | CONDITIONALLY_AVAILABLE |
26
 
27
  ---
 
53
 
54
  ### Setup
55
  ```bash
56
+ export HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
57
  ./setup_cryptobert.sh
58
  ```
59
 
config.js CHANGED
@@ -123,7 +123,7 @@ window.DASHBOARD_CONFIG = {
123
  // HuggingFace Configuration
124
  // ═══════════════════════════════════════════════════════════════
125
 
126
- HF_TOKEN: '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',
127
  HF_API_BASE: 'https://api-inference.huggingface.co/models',
128
 
129
  // ═══════════════════════════════════════════════════════════════
 
123
  // HuggingFace Configuration
124
  // ═══════════════════════════════════════════════════════════════
125
 
126
+ HF_TOKEN: 'hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
127
  HF_API_BASE: 'https://api-inference.huggingface.co/models',
128
 
129
  // ═══════════════════════════════════════════════════════════════
crypto_resources_unified_2025-11-11.json CHANGED
@@ -1699,7 +1699,7 @@
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
- "key": "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",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
@@ -1715,7 +1715,7 @@
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
- "key": "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",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
 
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
 
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
docs/CRYPTOBERT_INTEGRATION.md CHANGED
@@ -35,7 +35,7 @@ This document describes the integration of the **ElKulako/CryptoBERT** model int
35
 
36
  ```bash
37
  # Set HF_TOKEN for authenticated access
38
- export HF_TOKEN="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"
39
  ```
40
 
41
  ### Python Configuration (config.py)
@@ -50,7 +50,7 @@ HUGGINGFACE_MODELS = {
50
  }
51
 
52
  # Hugging Face Authentication
53
- HF_TOKEN = os.environ.get("HF_TOKEN", "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")
54
  HF_USE_AUTH_TOKEN = bool(HF_TOKEN)
55
  ```
56
 
@@ -68,14 +68,14 @@ Run the provided setup script:
68
 
69
  1. **Set environment variable (temporary)**:
70
  ```bash
71
- export HF_TOKEN="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"
72
  ```
73
 
74
  2. **Set environment variable (persistent)**:
75
 
76
  Add to `~/.bashrc` or `~/.zshrc`:
77
  ```bash
78
- echo 'export HF_TOKEN="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"' >> ~/.bashrc
79
  source ~/.bashrc
80
  ```
81
 
 
35
 
36
  ```bash
37
  # Set HF_TOKEN for authenticated access
38
+ export HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
39
  ```
40
 
41
  ### Python Configuration (config.py)
 
50
  }
51
 
52
  # Hugging Face Authentication
53
+ HF_TOKEN = os.environ.get("HF_TOKEN", "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
54
  HF_USE_AUTH_TOKEN = bool(HF_TOKEN)
55
  ```
56
 
 
68
 
69
  1. **Set environment variable (temporary)**:
70
  ```bash
71
+ export HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
72
  ```
73
 
74
  2. **Set environment variable (persistent)**:
75
 
76
  Add to `~/.bashrc` or `~/.zshrc`:
77
  ```bash
78
+ echo 'export HF_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"' >> ~/.bashrc
79
  source ~/.bashrc
80
  ```
81
 
docs/archive/HF_IMPLEMENTATION_COMPLETE.md CHANGED
@@ -47,7 +47,7 @@
47
 
48
  #### 1. **Environment Configuration** (`.env`)
49
  ```env
50
- HUGGINGFACE_TOKEN=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
51
  ENABLE_SENTIMENT=true
52
  SENTIMENT_SOCIAL_MODEL=ElKulako/cryptobert
53
  SENTIMENT_NEWS_MODEL=kk08/CryptoBERT
 
47
 
48
  #### 1. **Environment Configuration** (`.env`)
49
  ```env
50
+ HUGGINGFACE_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
51
  ENABLE_SENTIMENT=true
52
  SENTIMENT_SOCIAL_MODEL=ElKulako/cryptobert
53
  SENTIMENT_NEWS_MODEL=kk08/CryptoBERT
final/.env CHANGED
@@ -17,4 +17,4 @@ NEWSAPI_KEY=
17
  CRYPTOCOMPARE_KEY=
18
 
19
  # HuggingFace API Token
20
- HF_TOKEN=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
 
17
  CRYPTOCOMPARE_KEY=
18
 
19
  # HuggingFace API Token
20
+ HF_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
final/all_apis_merged_2025.json CHANGED
@@ -31,7 +31,7 @@
31
  "zip_text_snippets": [
32
  {
33
  "filename": "crypto_resources.ts",
34
- "text_preview": "// crypto_resources.ts — unified TS with 150+ Hugging Face sources (dynamic catalog) + Safe F&G aggregator\n// English-only comments. Keys intentionally embedded per user request.\n\nexport type Category =\n | 'market'\n | 'news'\n | 'sentiment'\n | 'onchain'\n | 'block_explorer'\n | 'whales'\n | 'generic'\n | 'hf';\n\nexport interface EndpointDef {\n path: string;\n method?: 'GET' | 'POST';\n sampleParams?: Record<string, string | number>;\n authLocation?: 'header' | 'query';\n authName?: string;\n authValue?: string;\n contentType?: string;\n}\n\nexport interface CryptoResource {\n id: string;\n category: Category;\n name: string;\n baseUrl: string;\n free: boolean;\n rateLimit?: string;\n endpoints?: Record<string, EndpointDef>;\n}\n\nexport interface MarketQuote {\n id: string;\n symbol: string;\n name: string;\n price: number;\n change24h?: number;\n marketCap?: number;\n source: string;\n raw: any;\n}\n\nexport interface NewsItem {\n title: string;\n link: string;\n publishedAt?: string;\n source: string;\n}\n\nexport interface OHLCVRow {\n timestamp: number | string;\n open: number; high: number; low: number; close: number; volume: number;\n [k: string]: any;\n}\n\nexport interface FNGPoint {\n value: number; // 0..100\n classification: string;\n at?: string;\n source: string;\n raw?: any;\n}\n\nconst EMBEDDED_KEYS = {\n CMC: '04cf4b5b-9868-465c-8ba0-9f2e78c92eb1',\n ETHERSCAN: 'SZHYFZK2RR8H9TIMJBVW54V4H81K2Z2KR2',\n ETHERSCAN_BACKUP: 'T6IR8VJHX2NE6ZJW2S3FDVN1TYG4PYYI45',\n BSCSCAN: 'K62RKHGXTDCG53RU4MCG6XABIMJKTN19IT',\n CRYPTOCOMPARE: 'e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f',\n\n // Optional free keys provided by user (kept in-code per request)\n MESSARI: '',\n SANTIMENT: '',\n COINMETRICS: '',\n HUGGINGFACE: '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',\n};\n\nconst sleep = (ms: number) => new Promise(r => setTimeout(r, ms));\n\nclass HttpError extends Error {\n constructor(public status: number, public url: string, public body?: string) {\n super(`HTTP ${status} for ${url}`);\n }\n}\n\nfunction buildURL(base: string, path = '', params?: Record<string, any>): string {\n const hasQ = path.includes('?');\n const url = base.replace(/\\/+$/, '') + '/' + path.replace(/^\\/+/, '');\n if (!params || Object.keys(params).length === 0) return url;\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n qs.set(k, String(v));\n }\n return url + (hasQ ? '&' : '?') + qs.toString();\n}\n\nasync function fetchRaw(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<Response> {\n const { headers = {}, timeoutMs = 12000, retries = 1, retryDelayMs = 600, body, method = 'GET' } = opts;\n let lastErr: any;\n for (let attempt = 0; attempt <= retries; attempt++) {\n const ac = new AbortController();\n const id = setTimeout(() => ac.abort(), timeoutMs);\n try {\n const res = await fetch(url, { headers, signal: ac.signal, method, body });\n clearTimeout(id);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n if (res.status === 429 && attempt < retries) {\n await sleep(retryDelayMs * (attempt + 1));\n continue;\n }\n throw new HttpError(res.status, url, text);\n }\n return res;\n } catch (e) {\n clearTimeout(id);\n lastErr = e;\n if (attempt < retries) { await sleep(retryDelayMs * (attempt + 1)); continue; }\n }\n }\n throw lastErr;\n}\n\nasync function fetchJSON<T = any>(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<T> {\n const res = await fetchRaw(url, opts);\n const ct = res.headers.get('content-type') || '';\n if (ct.includes('json')) return res.json() as Promise<T>;\n const text = await res.text();\n try { return JSON.parse(text) as T; } catch { return text as unknown as T; }\n}\n\nfunction ensureNonEmpty(obj: any, label: string) {\n if (obj == null) throw new Error(`${label}: empty response`);\n if (Array.isArray(obj) && obj.length === 0) throw new Error(`${label}: empty array`);\n if (typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === 0)\n throw new Error(`${label}: empty object`);\n}\n\nfunction normalizeSymbol(q: string) { return q.trim().toLowerCase(); }\n\nfunction parseCSV(text: string): any[] {\n const lines = text.split(/\\r?\\n/).filter(Boolean);\n if (lines.length < 2) return [];\n const header = lines[0].split(',').map((s) => s.trim());\n const out: any[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cols = lines[i].split(',').map((s) => s.trim());\n const row: any = {};\n header.forEach((h, idx) => { row[h] = cols[idx]; });\n out.push(row);\n }\n return out;\n}\n\nfunction parseRssSimple(xml: string, source: string, limit = 20): NewsItem[] {\n const items: NewsItem[] = [];\n const chunks = xml.split(/<item[\\s>]/i).slice(1);\n for (const raw of chunks) {\n const item = raw.split(/<\\/item>/i)[0] || '';\n const get = (tag: string) => {\n const m = item.match(new RegExp(`<${tag}[^>]*>([\\\\s\\\\S]*?)</${tag}>`, 'i'));\n return m ? m[1].replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() : undefined;\n };\n const title = get('title'); const link = get('link') || get('guid'); const pub = get('pubDate') || get('updated') || get('dc:date');\n if (title && link) items.push({ title, link, publishedAt: pub, source });\n if (items.length >= limit) break;\n }\n return items;\n}\n\n/* ===================== BASE RESOURCES ===================== */\n\nexport const resources: CryptoResource[] = [\n // Market\n { id: 'coinpaprika', category: 'market', name: 'CoinPaprika', baseUrl: 'https://api.coinpaprika.com/v1', free: true, endpoints: {\n search: { path: '/search', sampleParams: { q: 'bitcoin', c: 'currencies', limit: 1 } },\n tickerById: { path: '/tickers/{id}', sampleParams: { quotes: 'USD' } },\n }},\n { id: 'coincap', category: 'market', name: 'CoinCap', baseUrl: 'https://api.coincap.io/v2', free: true, endpoints: {\n assets: { path: '/assets', sampleParams: { search: 'bitcoin', limit: 1 } },\n assetById: { path: '/assets/{id}' },\n }},\n { id: 'coingecko', category: 'market', name: 'CoinGecko', baseUrl: 'https://api.coingecko.com/api/v3', free: true, endpoints: {\n simplePrice: { path: '/simple/price?ids={ids}&vs_currencies={fiats}' },\n }},\n { id: 'defillama', category: 'market', name: 'DefiLlama (Prices)', baseUrl: 'https://coins.llama.fi', free: true, endpoints: {\n pricesCurrent: { path: '/prices/current/{coins}' },\n }},\n { id: 'binance', category: 'market', name: 'Binance Public', baseUrl: 'https://api.binance.com', free: true, endpoints: {\n klines: { path: '/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}' },\n ticker: { path: '/api/v3/ticker/price?symbol={symbol}' },\n }},\n { id: 'cryptocompare', category: 'market', name: 'CryptoCompare', baseUrl: 'https://min-api.cryptocompare.com', free: true, endpoints: {\n histominute: { path: '/data/v2/histominute?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histohour: { path: '/data/v2/histohour?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histoday: { path: '/data/v2/histoday?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n }},\n { id: 'cmc', category: 'market', name: 'CoinMarketCap', baseUrl: 'https://pro-api.coinmarketcap.com/v1', free: false, endpoints: {\n quotes: { path: '/cryptocurrency/quotes/latest?symbol={symbol}', authLocation: 'header', authName: 'X-CMC_PRO_API_KEY', authValue: EMBEDDED_KEYS.CMC },\n }},\n\n // News\n { id: 'coinstats_news', category: 'news', name: 'CoinStats News', baseUrl: 'https://api.coinstats.app', free: true, endpoints: { feed: { path: '/public/v1/news' } }},\n { id: 'cryptopanic', category: 'news', name: 'CryptoPanic', baseUrl: 'https://cryptopanic.com', free: true, endpoints: { public: { path: '/api/v1/posts/?public=true' } }},\n { id: 'rss_cointelegraph', category: 'news', name: 'Cointelegraph RSS', baseUrl: 'https://cointelegraph.com', free: true, endpoints: { feed: { path: '/rss' } }},\n { id: 'rss_coindesk', category: 'news', name: 'CoinDesk RSS', baseUrl: 'https://www.coindesk.com', free: true, endpoints: { feed: { path: '/arc/outboundfeeds/rss/?outputType=xml' } }},\n { id: 'rss_decrypt', category: 'news', name: 'Decrypt RSS', baseUrl: 'https://decrypt.co', free: true, endpoints: { feed: { path: '/feed' } }},\n\n // Sentiment / F&G\n { id: 'altme_fng', category: 'sentiment', name: 'Alternative.me F&G', baseUrl: 'https://api.alternative.me', free: true, endpoints: {\n latest: { path: '/fng/', sampleParams: { limit: 1 } },\n history: { path: '/fng/', sampleParams: { limit: 30 } },\n }},\n { id: 'cfgi_v1', category: 'sentiment', name: 'CFGI API v1', baseUrl: 'https://api.cfgi.io', free: true, endpoints: {\n latest: { path: '/v1/fear-greed' },\n }},\n { id: 'cfgi_legacy', category: 'sentiment', name: 'CFGI Legacy', baseUrl: 'https://cfgi.io', free: true, endpoints: {\n latest: { path: '/api' },\n }},\n\n // On-chain / explorers\n { id: 'etherscan_primary', category: 'block_explorer', name: 'Etherscan', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN },\n }},\n { id: 'etherscan_backup', category: 'block_explorer', name: 'Etherscan Backup', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN_BACKUP },\n }},\n { id: 'blockscout_eth', category: 'block_explorer', name: 'Blockscout (ETH)', baseUrl: 'https://eth.blockscout.com', free: true, endpoints: {\n balanc",
35
  "note": "included as small text"
36
  }
37
  ],
@@ -57,7 +57,7 @@
57
  "e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f"
58
  ],
59
  "huggingface": [
60
- "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"
61
  ]
62
  },
63
  "notes": "This file was auto-generated. Keys/tokens are present as found in uploaded sources. Secure them as you wish."
 
31
  "zip_text_snippets": [
32
  {
33
  "filename": "crypto_resources.ts",
34
+ "text_preview": "// crypto_resources.ts — unified TS with 150+ Hugging Face sources (dynamic catalog) + Safe F&G aggregator\n// English-only comments. Keys intentionally embedded per user request.\n\nexport type Category =\n | 'market'\n | 'news'\n | 'sentiment'\n | 'onchain'\n | 'block_explorer'\n | 'whales'\n | 'generic'\n | 'hf';\n\nexport interface EndpointDef {\n path: string;\n method?: 'GET' | 'POST';\n sampleParams?: Record<string, string | number>;\n authLocation?: 'header' | 'query';\n authName?: string;\n authValue?: string;\n contentType?: string;\n}\n\nexport interface CryptoResource {\n id: string;\n category: Category;\n name: string;\n baseUrl: string;\n free: boolean;\n rateLimit?: string;\n endpoints?: Record<string, EndpointDef>;\n}\n\nexport interface MarketQuote {\n id: string;\n symbol: string;\n name: string;\n price: number;\n change24h?: number;\n marketCap?: number;\n source: string;\n raw: any;\n}\n\nexport interface NewsItem {\n title: string;\n link: string;\n publishedAt?: string;\n source: string;\n}\n\nexport interface OHLCVRow {\n timestamp: number | string;\n open: number; high: number; low: number; close: number; volume: number;\n [k: string]: any;\n}\n\nexport interface FNGPoint {\n value: number; // 0..100\n classification: string;\n at?: string;\n source: string;\n raw?: any;\n}\n\nconst EMBEDDED_KEYS = {\n CMC: '04cf4b5b-9868-465c-8ba0-9f2e78c92eb1',\n ETHERSCAN: 'SZHYFZK2RR8H9TIMJBVW54V4H81K2Z2KR2',\n ETHERSCAN_BACKUP: 'T6IR8VJHX2NE6ZJW2S3FDVN1TYG4PYYI45',\n BSCSCAN: 'K62RKHGXTDCG53RU4MCG6XABIMJKTN19IT',\n CRYPTOCOMPARE: 'e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f',\n\n // Optional free keys provided by user (kept in-code per request)\n MESSARI: '',\n SANTIMENT: '',\n COINMETRICS: '',\n HUGGINGFACE: 'hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',\n};\n\nconst sleep = (ms: number) => new Promise(r => setTimeout(r, ms));\n\nclass HttpError extends Error {\n constructor(public status: number, public url: string, public body?: string) {\n super(`HTTP ${status} for ${url}`);\n }\n}\n\nfunction buildURL(base: string, path = '', params?: Record<string, any>): string {\n const hasQ = path.includes('?');\n const url = base.replace(/\\/+$/, '') + '/' + path.replace(/^\\/+/, '');\n if (!params || Object.keys(params).length === 0) return url;\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n qs.set(k, String(v));\n }\n return url + (hasQ ? '&' : '?') + qs.toString();\n}\n\nasync function fetchRaw(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<Response> {\n const { headers = {}, timeoutMs = 12000, retries = 1, retryDelayMs = 600, body, method = 'GET' } = opts;\n let lastErr: any;\n for (let attempt = 0; attempt <= retries; attempt++) {\n const ac = new AbortController();\n const id = setTimeout(() => ac.abort(), timeoutMs);\n try {\n const res = await fetch(url, { headers, signal: ac.signal, method, body });\n clearTimeout(id);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n if (res.status === 429 && attempt < retries) {\n await sleep(retryDelayMs * (attempt + 1));\n continue;\n }\n throw new HttpError(res.status, url, text);\n }\n return res;\n } catch (e) {\n clearTimeout(id);\n lastErr = e;\n if (attempt < retries) { await sleep(retryDelayMs * (attempt + 1)); continue; }\n }\n }\n throw lastErr;\n}\n\nasync function fetchJSON<T = any>(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<T> {\n const res = await fetchRaw(url, opts);\n const ct = res.headers.get('content-type') || '';\n if (ct.includes('json')) return res.json() as Promise<T>;\n const text = await res.text();\n try { return JSON.parse(text) as T; } catch { return text as unknown as T; }\n}\n\nfunction ensureNonEmpty(obj: any, label: string) {\n if (obj == null) throw new Error(`${label}: empty response`);\n if (Array.isArray(obj) && obj.length === 0) throw new Error(`${label}: empty array`);\n if (typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === 0)\n throw new Error(`${label}: empty object`);\n}\n\nfunction normalizeSymbol(q: string) { return q.trim().toLowerCase(); }\n\nfunction parseCSV(text: string): any[] {\n const lines = text.split(/\\r?\\n/).filter(Boolean);\n if (lines.length < 2) return [];\n const header = lines[0].split(',').map((s) => s.trim());\n const out: any[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cols = lines[i].split(',').map((s) => s.trim());\n const row: any = {};\n header.forEach((h, idx) => { row[h] = cols[idx]; });\n out.push(row);\n }\n return out;\n}\n\nfunction parseRssSimple(xml: string, source: string, limit = 20): NewsItem[] {\n const items: NewsItem[] = [];\n const chunks = xml.split(/<item[\\s>]/i).slice(1);\n for (const raw of chunks) {\n const item = raw.split(/<\\/item>/i)[0] || '';\n const get = (tag: string) => {\n const m = item.match(new RegExp(`<${tag}[^>]*>([\\\\s\\\\S]*?)</${tag}>`, 'i'));\n return m ? m[1].replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() : undefined;\n };\n const title = get('title'); const link = get('link') || get('guid'); const pub = get('pubDate') || get('updated') || get('dc:date');\n if (title && link) items.push({ title, link, publishedAt: pub, source });\n if (items.length >= limit) break;\n }\n return items;\n}\n\n/* ===================== BASE RESOURCES ===================== */\n\nexport const resources: CryptoResource[] = [\n // Market\n { id: 'coinpaprika', category: 'market', name: 'CoinPaprika', baseUrl: 'https://api.coinpaprika.com/v1', free: true, endpoints: {\n search: { path: '/search', sampleParams: { q: 'bitcoin', c: 'currencies', limit: 1 } },\n tickerById: { path: '/tickers/{id}', sampleParams: { quotes: 'USD' } },\n }},\n { id: 'coincap', category: 'market', name: 'CoinCap', baseUrl: 'https://api.coincap.io/v2', free: true, endpoints: {\n assets: { path: '/assets', sampleParams: { search: 'bitcoin', limit: 1 } },\n assetById: { path: '/assets/{id}' },\n }},\n { id: 'coingecko', category: 'market', name: 'CoinGecko', baseUrl: 'https://api.coingecko.com/api/v3', free: true, endpoints: {\n simplePrice: { path: '/simple/price?ids={ids}&vs_currencies={fiats}' },\n }},\n { id: 'defillama', category: 'market', name: 'DefiLlama (Prices)', baseUrl: 'https://coins.llama.fi', free: true, endpoints: {\n pricesCurrent: { path: '/prices/current/{coins}' },\n }},\n { id: 'binance', category: 'market', name: 'Binance Public', baseUrl: 'https://api.binance.com', free: true, endpoints: {\n klines: { path: '/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}' },\n ticker: { path: '/api/v3/ticker/price?symbol={symbol}' },\n }},\n { id: 'cryptocompare', category: 'market', name: 'CryptoCompare', baseUrl: 'https://min-api.cryptocompare.com', free: true, endpoints: {\n histominute: { path: '/data/v2/histominute?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histohour: { path: '/data/v2/histohour?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histoday: { path: '/data/v2/histoday?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n }},\n { id: 'cmc', category: 'market', name: 'CoinMarketCap', baseUrl: 'https://pro-api.coinmarketcap.com/v1', free: false, endpoints: {\n quotes: { path: '/cryptocurrency/quotes/latest?symbol={symbol}', authLocation: 'header', authName: 'X-CMC_PRO_API_KEY', authValue: EMBEDDED_KEYS.CMC },\n }},\n\n // News\n { id: 'coinstats_news', category: 'news', name: 'CoinStats News', baseUrl: 'https://api.coinstats.app', free: true, endpoints: { feed: { path: '/public/v1/news' } }},\n { id: 'cryptopanic', category: 'news', name: 'CryptoPanic', baseUrl: 'https://cryptopanic.com', free: true, endpoints: { public: { path: '/api/v1/posts/?public=true' } }},\n { id: 'rss_cointelegraph', category: 'news', name: 'Cointelegraph RSS', baseUrl: 'https://cointelegraph.com', free: true, endpoints: { feed: { path: '/rss' } }},\n { id: 'rss_coindesk', category: 'news', name: 'CoinDesk RSS', baseUrl: 'https://www.coindesk.com', free: true, endpoints: { feed: { path: '/arc/outboundfeeds/rss/?outputType=xml' } }},\n { id: 'rss_decrypt', category: 'news', name: 'Decrypt RSS', baseUrl: 'https://decrypt.co', free: true, endpoints: { feed: { path: '/feed' } }},\n\n // Sentiment / F&G\n { id: 'altme_fng', category: 'sentiment', name: 'Alternative.me F&G', baseUrl: 'https://api.alternative.me', free: true, endpoints: {\n latest: { path: '/fng/', sampleParams: { limit: 1 } },\n history: { path: '/fng/', sampleParams: { limit: 30 } },\n }},\n { id: 'cfgi_v1', category: 'sentiment', name: 'CFGI API v1', baseUrl: 'https://api.cfgi.io', free: true, endpoints: {\n latest: { path: '/v1/fear-greed' },\n }},\n { id: 'cfgi_legacy', category: 'sentiment', name: 'CFGI Legacy', baseUrl: 'https://cfgi.io', free: true, endpoints: {\n latest: { path: '/api' },\n }},\n\n // On-chain / explorers\n { id: 'etherscan_primary', category: 'block_explorer', name: 'Etherscan', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN },\n }},\n { id: 'etherscan_backup', category: 'block_explorer', name: 'Etherscan Backup', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN_BACKUP },\n }},\n { id: 'blockscout_eth', category: 'block_explorer', name: 'Blockscout (ETH)', baseUrl: 'https://eth.blockscout.com', free: true, endpoints: {\n balanc",
35
  "note": "included as small text"
36
  }
37
  ],
 
57
  "e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f"
58
  ],
59
  "huggingface": [
60
+ "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
61
  ]
62
  },
63
  "notes": "This file was auto-generated. Keys/tokens are present as found in uploaded sources. Secure them as you wish."
final/api-resources/crypto_resources_unified_2025-11-11.json CHANGED
@@ -1699,7 +1699,7 @@
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
- "key": "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",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
@@ -1715,7 +1715,7 @@
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
- "key": "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",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
 
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
 
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
final/backend/services/auto_discovery_service.py CHANGED
@@ -94,7 +94,7 @@ class AutoDiscoveryService:
94
  # Get HF token from environment or use default
95
  from config import get_settings
96
  settings = get_settings()
97
- hf_token = os.getenv("HF_TOKEN") or os.getenv("HF_API_TOKEN") or settings.hf_token or "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"
98
  try:
99
  self._hf_client = InferenceClient(model=self.hf_model, token=hf_token)
100
  logger.info("Auto discovery Hugging Face client initialized with model %s", self.hf_model)
 
94
  # Get HF token from environment or use default
95
  from config import get_settings
96
  settings = get_settings()
97
+ hf_token = os.getenv("HF_TOKEN") or os.getenv("HF_API_TOKEN") or settings.hf_token or "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
98
  try:
99
  self._hf_client = InferenceClient(model=self.hf_model, token=hf_token)
100
  logger.info("Auto discovery Hugging Face client initialized with model %s", self.hf_model)
final/backend/services/diagnostics_service.py CHANGED
@@ -265,7 +265,7 @@ class DiagnosticsService:
265
 
266
  # Get HF token from settings or use default
267
  settings = get_settings()
268
- hf_token = settings.hf_token or os.getenv("HF_TOKEN") or "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"
269
 
270
  api = HfApi(token=hf_token)
271
 
 
265
 
266
  # Get HF token from settings or use default
267
  settings = get_settings()
268
+ hf_token = settings.hf_token or os.getenv("HF_TOKEN") or "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
269
 
270
  api = HfApi(token=hf_token)
271
 
final/config.js CHANGED
@@ -123,7 +123,7 @@ window.DASHBOARD_CONFIG = {
123
  // HuggingFace Configuration
124
  // ═══════════════════════════════════════════════════════════════
125
 
126
- HF_TOKEN: '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',
127
  HF_API_BASE: 'https://api-inference.huggingface.co/models',
128
 
129
  // ═══════════════════════════════════════════════════════════════
 
123
  // HuggingFace Configuration
124
  // ═══════════════════════════════════════════════════════════════
125
 
126
+ HF_TOKEN: 'hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
127
  HF_API_BASE: 'https://api-inference.huggingface.co/models',
128
 
129
  // ═══════════════════════════════════════════════════════════════
final/config.py CHANGED
@@ -95,7 +95,7 @@ def get_settings() -> Settings:
95
  decoded_token = raw_token or _decode_token(encoded_token)
96
  # Default token if none provided
97
  if not decoded_token:
98
- decoded_token = "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"
99
 
100
  database_path = Path(os.environ.get("DATABASE_PATH", str(DB_DIR / "crypto_aggregator.db")))
101
 
 
95
  decoded_token = raw_token or _decode_token(encoded_token)
96
  # Default token if none provided
97
  if not decoded_token:
98
+ decoded_token = "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
99
 
100
  database_path = Path(os.environ.get("DATABASE_PATH", str(DB_DIR / "crypto_aggregator.db")))
101
 
final/crypto_resources_unified_2025-11-11.json CHANGED
@@ -1699,7 +1699,7 @@
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
- "key": "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",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
@@ -1715,7 +1715,7 @@
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
- "key": "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",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
 
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
 
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
final/hf_unified_server.py CHANGED
@@ -2277,7 +2277,7 @@ async def get_dataset_sample(name: str = Query(...), limit: int = Query(default=
2277
 
2278
  # Get HF token for dataset loading
2279
  settings = get_settings()
2280
- hf_token = settings.hf_token or "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"
2281
 
2282
  # Set token in environment for datasets library
2283
  import os
 
2277
 
2278
  # Get HF token for dataset loading
2279
  settings = get_settings()
2280
+ hf_token = settings.hf_token or "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
2281
 
2282
  # Set token in environment for datasets library
2283
  import os
final/provider_validator.py CHANGED
@@ -279,7 +279,7 @@ class ProviderValidator:
279
  start = time.time()
280
 
281
  # Get HF token from environment or use default
282
- hf_token = os.getenv("HF_TOKEN") or "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"
283
  headers = {}
284
  if hf_token:
285
  headers["Authorization"] = f"Bearer {hf_token}"
 
279
  start = time.time()
280
 
281
  # Get HF token from environment or use default
282
+ hf_token = os.getenv("HF_TOKEN") or "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
283
  headers = {}
284
  if hf_token:
285
  headers["Authorization"] = f"Bearer {hf_token}"
final/providers_config_ultimate.json CHANGED
@@ -566,7 +566,7 @@
566
  "endpoints": {},
567
  "rate_limit": {},
568
  "requires_auth": true,
569
- "api_keys": ["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"],
570
  "auth_type": "header",
571
  "auth_header": "Authorization",
572
  "priority": 8,
 
566
  "endpoints": {},
567
  "rate_limit": {},
568
  "requires_auth": true,
569
+ "api_keys": ["hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],
570
  "auth_type": "header",
571
  "auth_header": "Authorization",
572
  "priority": 8,
final/setup_cryptobert.sh CHANGED
@@ -8,7 +8,7 @@ echo "========================================="
8
  echo ""
9
 
10
  # Default token (can be overridden)
11
- DEFAULT_TOKEN="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"
12
 
13
  # Check if HF_TOKEN is already set
14
  if [ -n "$HF_TOKEN" ]; then
 
8
  echo ""
9
 
10
  # Default token (can be overridden)
11
+ DEFAULT_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
12
 
13
  # Check if HF_TOKEN is already set
14
  if [ -n "$HF_TOKEN" ]; then
final/static/js/huggingface-integration.js CHANGED
@@ -215,7 +215,7 @@ class HuggingFaceIntegration {
215
  // Priority: window.HF_API_KEY > DASHBOARD_CONFIG.HF_TOKEN > default
216
  return window.HF_API_KEY ||
217
  (window.DASHBOARD_CONFIG && window.DASHBOARD_CONFIG.HF_TOKEN) ||
218
- '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';
219
  }
220
  }
221
 
 
215
  // Priority: window.HF_API_KEY > DASHBOARD_CONFIG.HF_TOKEN > default
216
  return window.HF_API_KEY ||
217
  (window.DASHBOARD_CONFIG && window.DASHBOARD_CONFIG.HF_TOKEN) ||
218
+ 'hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
219
  }
220
  }
221
 
final/static/providers_config_ultimate.json CHANGED
@@ -566,7 +566,7 @@
566
  "endpoints": {},
567
  "rate_limit": {},
568
  "requires_auth": true,
569
- "api_keys": ["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"],
570
  "auth_type": "header",
571
  "auth_header": "Authorization",
572
  "priority": 8,
 
566
  "endpoints": {},
567
  "rate_limit": {},
568
  "requires_auth": true,
569
+ "api_keys": ["hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],
570
  "auth_type": "header",
571
  "auth_header": "Authorization",
572
  "priority": 8,
final/test_cryptobert.py CHANGED
@@ -10,7 +10,7 @@ import json
10
  from typing import Dict, Any
11
 
12
  # Ensure the token is set
13
- os.environ.setdefault("HF_TOKEN", "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")
14
 
15
  # Import after setting environment variable
16
  import config
 
10
  from typing import Dict, Any
11
 
12
  # Ensure the token is set
13
+ os.environ.setdefault("HF_TOKEN", "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
14
 
15
  # Import after setting environment variable
16
  import config
hf-data-engine/all_apis_merged_2025.json CHANGED
@@ -31,7 +31,7 @@
31
  "zip_text_snippets": [
32
  {
33
  "filename": "crypto_resources.ts",
34
- "text_preview": "// crypto_resources.ts — unified TS with 150+ Hugging Face sources (dynamic catalog) + Safe F&G aggregator\n// English-only comments. Keys intentionally embedded per user request.\n\nexport type Category =\n | 'market'\n | 'news'\n | 'sentiment'\n | 'onchain'\n | 'block_explorer'\n | 'whales'\n | 'generic'\n | 'hf';\n\nexport interface EndpointDef {\n path: string;\n method?: 'GET' | 'POST';\n sampleParams?: Record<string, string | number>;\n authLocation?: 'header' | 'query';\n authName?: string;\n authValue?: string;\n contentType?: string;\n}\n\nexport interface CryptoResource {\n id: string;\n category: Category;\n name: string;\n baseUrl: string;\n free: boolean;\n rateLimit?: string;\n endpoints?: Record<string, EndpointDef>;\n}\n\nexport interface MarketQuote {\n id: string;\n symbol: string;\n name: string;\n price: number;\n change24h?: number;\n marketCap?: number;\n source: string;\n raw: any;\n}\n\nexport interface NewsItem {\n title: string;\n link: string;\n publishedAt?: string;\n source: string;\n}\n\nexport interface OHLCVRow {\n timestamp: number | string;\n open: number; high: number; low: number; close: number; volume: number;\n [k: string]: any;\n}\n\nexport interface FNGPoint {\n value: number; // 0..100\n classification: string;\n at?: string;\n source: string;\n raw?: any;\n}\n\nconst EMBEDDED_KEYS = {\n CMC: '04cf4b5b-9868-465c-8ba0-9f2e78c92eb1',\n ETHERSCAN: 'SZHYFZK2RR8H9TIMJBVW54V4H81K2Z2KR2',\n ETHERSCAN_BACKUP: 'T6IR8VJHX2NE6ZJW2S3FDVN1TYG4PYYI45',\n BSCSCAN: 'K62RKHGXTDCG53RU4MCG6XABIMJKTN19IT',\n CRYPTOCOMPARE: 'e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f',\n\n // Optional free keys provided by user (kept in-code per request)\n MESSARI: '',\n SANTIMENT: '',\n COINMETRICS: '',\n HUGGINGFACE: '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',\n};\n\nconst sleep = (ms: number) => new Promise(r => setTimeout(r, ms));\n\nclass HttpError extends Error {\n constructor(public status: number, public url: string, public body?: string) {\n super(`HTTP ${status} for ${url}`);\n }\n}\n\nfunction buildURL(base: string, path = '', params?: Record<string, any>): string {\n const hasQ = path.includes('?');\n const url = base.replace(/\\/+$/, '') + '/' + path.replace(/^\\/+/, '');\n if (!params || Object.keys(params).length === 0) return url;\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n qs.set(k, String(v));\n }\n return url + (hasQ ? '&' : '?') + qs.toString();\n}\n\nasync function fetchRaw(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<Response> {\n const { headers = {}, timeoutMs = 12000, retries = 1, retryDelayMs = 600, body, method = 'GET' } = opts;\n let lastErr: any;\n for (let attempt = 0; attempt <= retries; attempt++) {\n const ac = new AbortController();\n const id = setTimeout(() => ac.abort(), timeoutMs);\n try {\n const res = await fetch(url, { headers, signal: ac.signal, method, body });\n clearTimeout(id);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n if (res.status === 429 && attempt < retries) {\n await sleep(retryDelayMs * (attempt + 1));\n continue;\n }\n throw new HttpError(res.status, url, text);\n }\n return res;\n } catch (e) {\n clearTimeout(id);\n lastErr = e;\n if (attempt < retries) { await sleep(retryDelayMs * (attempt + 1)); continue; }\n }\n }\n throw lastErr;\n}\n\nasync function fetchJSON<T = any>(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<T> {\n const res = await fetchRaw(url, opts);\n const ct = res.headers.get('content-type') || '';\n if (ct.includes('json')) return res.json() as Promise<T>;\n const text = await res.text();\n try { return JSON.parse(text) as T; } catch { return text as unknown as T; }\n}\n\nfunction ensureNonEmpty(obj: any, label: string) {\n if (obj == null) throw new Error(`${label}: empty response`);\n if (Array.isArray(obj) && obj.length === 0) throw new Error(`${label}: empty array`);\n if (typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === 0)\n throw new Error(`${label}: empty object`);\n}\n\nfunction normalizeSymbol(q: string) { return q.trim().toLowerCase(); }\n\nfunction parseCSV(text: string): any[] {\n const lines = text.split(/\\r?\\n/).filter(Boolean);\n if (lines.length < 2) return [];\n const header = lines[0].split(',').map((s) => s.trim());\n const out: any[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cols = lines[i].split(',').map((s) => s.trim());\n const row: any = {};\n header.forEach((h, idx) => { row[h] = cols[idx]; });\n out.push(row);\n }\n return out;\n}\n\nfunction parseRssSimple(xml: string, source: string, limit = 20): NewsItem[] {\n const items: NewsItem[] = [];\n const chunks = xml.split(/<item[\\s>]/i).slice(1);\n for (const raw of chunks) {\n const item = raw.split(/<\\/item>/i)[0] || '';\n const get = (tag: string) => {\n const m = item.match(new RegExp(`<${tag}[^>]*>([\\\\s\\\\S]*?)</${tag}>`, 'i'));\n return m ? m[1].replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() : undefined;\n };\n const title = get('title'); const link = get('link') || get('guid'); const pub = get('pubDate') || get('updated') || get('dc:date');\n if (title && link) items.push({ title, link, publishedAt: pub, source });\n if (items.length >= limit) break;\n }\n return items;\n}\n\n/* ===================== BASE RESOURCES ===================== */\n\nexport const resources: CryptoResource[] = [\n // Market\n { id: 'coinpaprika', category: 'market', name: 'CoinPaprika', baseUrl: 'https://api.coinpaprika.com/v1', free: true, endpoints: {\n search: { path: '/search', sampleParams: { q: 'bitcoin', c: 'currencies', limit: 1 } },\n tickerById: { path: '/tickers/{id}', sampleParams: { quotes: 'USD' } },\n }},\n { id: 'coincap', category: 'market', name: 'CoinCap', baseUrl: 'https://api.coincap.io/v2', free: true, endpoints: {\n assets: { path: '/assets', sampleParams: { search: 'bitcoin', limit: 1 } },\n assetById: { path: '/assets/{id}' },\n }},\n { id: 'coingecko', category: 'market', name: 'CoinGecko', baseUrl: 'https://api.coingecko.com/api/v3', free: true, endpoints: {\n simplePrice: { path: '/simple/price?ids={ids}&vs_currencies={fiats}' },\n }},\n { id: 'defillama', category: 'market', name: 'DefiLlama (Prices)', baseUrl: 'https://coins.llama.fi', free: true, endpoints: {\n pricesCurrent: { path: '/prices/current/{coins}' },\n }},\n { id: 'binance', category: 'market', name: 'Binance Public', baseUrl: 'https://api.binance.com', free: true, endpoints: {\n klines: { path: '/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}' },\n ticker: { path: '/api/v3/ticker/price?symbol={symbol}' },\n }},\n { id: 'cryptocompare', category: 'market', name: 'CryptoCompare', baseUrl: 'https://min-api.cryptocompare.com', free: true, endpoints: {\n histominute: { path: '/data/v2/histominute?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histohour: { path: '/data/v2/histohour?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histoday: { path: '/data/v2/histoday?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n }},\n { id: 'cmc', category: 'market', name: 'CoinMarketCap', baseUrl: 'https://pro-api.coinmarketcap.com/v1', free: false, endpoints: {\n quotes: { path: '/cryptocurrency/quotes/latest?symbol={symbol}', authLocation: 'header', authName: 'X-CMC_PRO_API_KEY', authValue: EMBEDDED_KEYS.CMC },\n }},\n\n // News\n { id: 'coinstats_news', category: 'news', name: 'CoinStats News', baseUrl: 'https://api.coinstats.app', free: true, endpoints: { feed: { path: '/public/v1/news' } }},\n { id: 'cryptopanic', category: 'news', name: 'CryptoPanic', baseUrl: 'https://cryptopanic.com', free: true, endpoints: { public: { path: '/api/v1/posts/?public=true' } }},\n { id: 'rss_cointelegraph', category: 'news', name: 'Cointelegraph RSS', baseUrl: 'https://cointelegraph.com', free: true, endpoints: { feed: { path: '/rss' } }},\n { id: 'rss_coindesk', category: 'news', name: 'CoinDesk RSS', baseUrl: 'https://www.coindesk.com', free: true, endpoints: { feed: { path: '/arc/outboundfeeds/rss/?outputType=xml' } }},\n { id: 'rss_decrypt', category: 'news', name: 'Decrypt RSS', baseUrl: 'https://decrypt.co', free: true, endpoints: { feed: { path: '/feed' } }},\n\n // Sentiment / F&G\n { id: 'altme_fng', category: 'sentiment', name: 'Alternative.me F&G', baseUrl: 'https://api.alternative.me', free: true, endpoints: {\n latest: { path: '/fng/', sampleParams: { limit: 1 } },\n history: { path: '/fng/', sampleParams: { limit: 30 } },\n }},\n { id: 'cfgi_v1', category: 'sentiment', name: 'CFGI API v1', baseUrl: 'https://api.cfgi.io', free: true, endpoints: {\n latest: { path: '/v1/fear-greed' },\n }},\n { id: 'cfgi_legacy', category: 'sentiment', name: 'CFGI Legacy', baseUrl: 'https://cfgi.io', free: true, endpoints: {\n latest: { path: '/api' },\n }},\n\n // On-chain / explorers\n { id: 'etherscan_primary', category: 'block_explorer', name: 'Etherscan', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN },\n }},\n { id: 'etherscan_backup', category: 'block_explorer', name: 'Etherscan Backup', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN_BACKUP },\n }},\n { id: 'blockscout_eth', category: 'block_explorer', name: 'Blockscout (ETH)', baseUrl: 'https://eth.blockscout.com', free: true, endpoints: {\n balanc",
35
  "note": "included as small text"
36
  }
37
  ],
@@ -57,7 +57,7 @@
57
  "e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f"
58
  ],
59
  "huggingface": [
60
- "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"
61
  ]
62
  },
63
  "notes": "This file was auto-generated. Keys/tokens are present as found in uploaded sources. Secure them as you wish."
 
31
  "zip_text_snippets": [
32
  {
33
  "filename": "crypto_resources.ts",
34
+ "text_preview": "// crypto_resources.ts — unified TS with 150+ Hugging Face sources (dynamic catalog) + Safe F&G aggregator\n// English-only comments. Keys intentionally embedded per user request.\n\nexport type Category =\n | 'market'\n | 'news'\n | 'sentiment'\n | 'onchain'\n | 'block_explorer'\n | 'whales'\n | 'generic'\n | 'hf';\n\nexport interface EndpointDef {\n path: string;\n method?: 'GET' | 'POST';\n sampleParams?: Record<string, string | number>;\n authLocation?: 'header' | 'query';\n authName?: string;\n authValue?: string;\n contentType?: string;\n}\n\nexport interface CryptoResource {\n id: string;\n category: Category;\n name: string;\n baseUrl: string;\n free: boolean;\n rateLimit?: string;\n endpoints?: Record<string, EndpointDef>;\n}\n\nexport interface MarketQuote {\n id: string;\n symbol: string;\n name: string;\n price: number;\n change24h?: number;\n marketCap?: number;\n source: string;\n raw: any;\n}\n\nexport interface NewsItem {\n title: string;\n link: string;\n publishedAt?: string;\n source: string;\n}\n\nexport interface OHLCVRow {\n timestamp: number | string;\n open: number; high: number; low: number; close: number; volume: number;\n [k: string]: any;\n}\n\nexport interface FNGPoint {\n value: number; // 0..100\n classification: string;\n at?: string;\n source: string;\n raw?: any;\n}\n\nconst EMBEDDED_KEYS = {\n CMC: '04cf4b5b-9868-465c-8ba0-9f2e78c92eb1',\n ETHERSCAN: 'SZHYFZK2RR8H9TIMJBVW54V4H81K2Z2KR2',\n ETHERSCAN_BACKUP: 'T6IR8VJHX2NE6ZJW2S3FDVN1TYG4PYYI45',\n BSCSCAN: 'K62RKHGXTDCG53RU4MCG6XABIMJKTN19IT',\n CRYPTOCOMPARE: 'e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f',\n\n // Optional free keys provided by user (kept in-code per request)\n MESSARI: '',\n SANTIMENT: '',\n COINMETRICS: '',\n HUGGINGFACE: 'hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',\n};\n\nconst sleep = (ms: number) => new Promise(r => setTimeout(r, ms));\n\nclass HttpError extends Error {\n constructor(public status: number, public url: string, public body?: string) {\n super(`HTTP ${status} for ${url}`);\n }\n}\n\nfunction buildURL(base: string, path = '', params?: Record<string, any>): string {\n const hasQ = path.includes('?');\n const url = base.replace(/\\/+$/, '') + '/' + path.replace(/^\\/+/, '');\n if (!params || Object.keys(params).length === 0) return url;\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) {\n if (v === undefined || v === null) continue;\n qs.set(k, String(v));\n }\n return url + (hasQ ? '&' : '?') + qs.toString();\n}\n\nasync function fetchRaw(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<Response> {\n const { headers = {}, timeoutMs = 12000, retries = 1, retryDelayMs = 600, body, method = 'GET' } = opts;\n let lastErr: any;\n for (let attempt = 0; attempt <= retries; attempt++) {\n const ac = new AbortController();\n const id = setTimeout(() => ac.abort(), timeoutMs);\n try {\n const res = await fetch(url, { headers, signal: ac.signal, method, body });\n clearTimeout(id);\n if (!res.ok) {\n const text = await res.text().catch(() => '');\n if (res.status === 429 && attempt < retries) {\n await sleep(retryDelayMs * (attempt + 1));\n continue;\n }\n throw new HttpError(res.status, url, text);\n }\n return res;\n } catch (e) {\n clearTimeout(id);\n lastErr = e;\n if (attempt < retries) { await sleep(retryDelayMs * (attempt + 1)); continue; }\n }\n }\n throw lastErr;\n}\n\nasync function fetchJSON<T = any>(\n url: string,\n opts: { headers?: Record<string, string>; timeoutMs?: number; retries?: number; retryDelayMs?: number; body?: any; method?: 'GET'|'POST' } = {}\n): Promise<T> {\n const res = await fetchRaw(url, opts);\n const ct = res.headers.get('content-type') || '';\n if (ct.includes('json')) return res.json() as Promise<T>;\n const text = await res.text();\n try { return JSON.parse(text) as T; } catch { return text as unknown as T; }\n}\n\nfunction ensureNonEmpty(obj: any, label: string) {\n if (obj == null) throw new Error(`${label}: empty response`);\n if (Array.isArray(obj) && obj.length === 0) throw new Error(`${label}: empty array`);\n if (typeof obj === 'object' && !Array.isArray(obj) && Object.keys(obj).length === 0)\n throw new Error(`${label}: empty object`);\n}\n\nfunction normalizeSymbol(q: string) { return q.trim().toLowerCase(); }\n\nfunction parseCSV(text: string): any[] {\n const lines = text.split(/\\r?\\n/).filter(Boolean);\n if (lines.length < 2) return [];\n const header = lines[0].split(',').map((s) => s.trim());\n const out: any[] = [];\n for (let i = 1; i < lines.length; i++) {\n const cols = lines[i].split(',').map((s) => s.trim());\n const row: any = {};\n header.forEach((h, idx) => { row[h] = cols[idx]; });\n out.push(row);\n }\n return out;\n}\n\nfunction parseRssSimple(xml: string, source: string, limit = 20): NewsItem[] {\n const items: NewsItem[] = [];\n const chunks = xml.split(/<item[\\s>]/i).slice(1);\n for (const raw of chunks) {\n const item = raw.split(/<\\/item>/i)[0] || '';\n const get = (tag: string) => {\n const m = item.match(new RegExp(`<${tag}[^>]*>([\\\\s\\\\S]*?)</${tag}>`, 'i'));\n return m ? m[1].replace(/<!\\[CDATA\\[|\\]\\]>/g, '').trim() : undefined;\n };\n const title = get('title'); const link = get('link') || get('guid'); const pub = get('pubDate') || get('updated') || get('dc:date');\n if (title && link) items.push({ title, link, publishedAt: pub, source });\n if (items.length >= limit) break;\n }\n return items;\n}\n\n/* ===================== BASE RESOURCES ===================== */\n\nexport const resources: CryptoResource[] = [\n // Market\n { id: 'coinpaprika', category: 'market', name: 'CoinPaprika', baseUrl: 'https://api.coinpaprika.com/v1', free: true, endpoints: {\n search: { path: '/search', sampleParams: { q: 'bitcoin', c: 'currencies', limit: 1 } },\n tickerById: { path: '/tickers/{id}', sampleParams: { quotes: 'USD' } },\n }},\n { id: 'coincap', category: 'market', name: 'CoinCap', baseUrl: 'https://api.coincap.io/v2', free: true, endpoints: {\n assets: { path: '/assets', sampleParams: { search: 'bitcoin', limit: 1 } },\n assetById: { path: '/assets/{id}' },\n }},\n { id: 'coingecko', category: 'market', name: 'CoinGecko', baseUrl: 'https://api.coingecko.com/api/v3', free: true, endpoints: {\n simplePrice: { path: '/simple/price?ids={ids}&vs_currencies={fiats}' },\n }},\n { id: 'defillama', category: 'market', name: 'DefiLlama (Prices)', baseUrl: 'https://coins.llama.fi', free: true, endpoints: {\n pricesCurrent: { path: '/prices/current/{coins}' },\n }},\n { id: 'binance', category: 'market', name: 'Binance Public', baseUrl: 'https://api.binance.com', free: true, endpoints: {\n klines: { path: '/api/v3/klines?symbol={symbol}&interval={interval}&limit={limit}' },\n ticker: { path: '/api/v3/ticker/price?symbol={symbol}' },\n }},\n { id: 'cryptocompare', category: 'market', name: 'CryptoCompare', baseUrl: 'https://min-api.cryptocompare.com', free: true, endpoints: {\n histominute: { path: '/data/v2/histominute?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histohour: { path: '/data/v2/histohour?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n histoday: { path: '/data/v2/histoday?fsym={fsym}&tsym={tsym}&limit={limit}&api_key=' + EMBEDDED_KEYS.CRYPTOCOMPARE },\n }},\n { id: 'cmc', category: 'market', name: 'CoinMarketCap', baseUrl: 'https://pro-api.coinmarketcap.com/v1', free: false, endpoints: {\n quotes: { path: '/cryptocurrency/quotes/latest?symbol={symbol}', authLocation: 'header', authName: 'X-CMC_PRO_API_KEY', authValue: EMBEDDED_KEYS.CMC },\n }},\n\n // News\n { id: 'coinstats_news', category: 'news', name: 'CoinStats News', baseUrl: 'https://api.coinstats.app', free: true, endpoints: { feed: { path: '/public/v1/news' } }},\n { id: 'cryptopanic', category: 'news', name: 'CryptoPanic', baseUrl: 'https://cryptopanic.com', free: true, endpoints: { public: { path: '/api/v1/posts/?public=true' } }},\n { id: 'rss_cointelegraph', category: 'news', name: 'Cointelegraph RSS', baseUrl: 'https://cointelegraph.com', free: true, endpoints: { feed: { path: '/rss' } }},\n { id: 'rss_coindesk', category: 'news', name: 'CoinDesk RSS', baseUrl: 'https://www.coindesk.com', free: true, endpoints: { feed: { path: '/arc/outboundfeeds/rss/?outputType=xml' } }},\n { id: 'rss_decrypt', category: 'news', name: 'Decrypt RSS', baseUrl: 'https://decrypt.co', free: true, endpoints: { feed: { path: '/feed' } }},\n\n // Sentiment / F&G\n { id: 'altme_fng', category: 'sentiment', name: 'Alternative.me F&G', baseUrl: 'https://api.alternative.me', free: true, endpoints: {\n latest: { path: '/fng/', sampleParams: { limit: 1 } },\n history: { path: '/fng/', sampleParams: { limit: 30 } },\n }},\n { id: 'cfgi_v1', category: 'sentiment', name: 'CFGI API v1', baseUrl: 'https://api.cfgi.io', free: true, endpoints: {\n latest: { path: '/v1/fear-greed' },\n }},\n { id: 'cfgi_legacy', category: 'sentiment', name: 'CFGI Legacy', baseUrl: 'https://cfgi.io', free: true, endpoints: {\n latest: { path: '/api' },\n }},\n\n // On-chain / explorers\n { id: 'etherscan_primary', category: 'block_explorer', name: 'Etherscan', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN },\n }},\n { id: 'etherscan_backup', category: 'block_explorer', name: 'Etherscan Backup', baseUrl: 'https://api.etherscan.io/api', free: false, endpoints: {\n balance: { path: '/?module=account&action=balance&address={address}&tag=latest&apikey=' + EMBEDDED_KEYS.ETHERSCAN_BACKUP },\n }},\n { id: 'blockscout_eth', category: 'block_explorer', name: 'Blockscout (ETH)', baseUrl: 'https://eth.blockscout.com', free: true, endpoints: {\n balanc",
35
  "note": "included as small text"
36
  }
37
  ],
 
57
  "e79c8e6d4c5b4a3f2e1d0c9b8a7f6e5d4c3b2a1f"
58
  ],
59
  "huggingface": [
60
+ "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
61
  ]
62
  },
63
  "notes": "This file was auto-generated. Keys/tokens are present as found in uploaded sources. Secure them as you wish."
hf-data-engine/api-resources/crypto_resources_unified_2025-11-11.json CHANGED
@@ -1699,7 +1699,7 @@
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
- "key": "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",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
@@ -1715,7 +1715,7 @@
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
- "key": "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",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
 
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
 
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
hf-data-engine/crypto_resources_unified_2025-11-11.json CHANGED
@@ -1699,7 +1699,7 @@
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
- "key": "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",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
@@ -1715,7 +1715,7 @@
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
- "key": "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",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
 
1699
  "base_url": "https://api-inference.huggingface.co/models/ElKulako/cryptobert",
1700
  "auth": {
1701
  "type": "apiKeyHeaderOptional",
1702
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1703
  "header_name": "Authorization"
1704
  },
1705
  "docs_url": "https://huggingface.co/ElKulako/cryptobert",
 
1715
  "base_url": "https://api-inference.huggingface.co/models/kk08/CryptoBERT",
1716
  "auth": {
1717
  "type": "apiKeyHeaderOptional",
1718
+ "key": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
1719
  "header_name": "Authorization"
1720
  },
1721
  "docs_url": "https://huggingface.co/kk08/CryptoBERT",
hf-data-engine/docs/archive/HF_IMPLEMENTATION_COMPLETE.md CHANGED
@@ -47,7 +47,7 @@
47
 
48
  #### 1. **Environment Configuration** (`.env`)
49
  ```env
50
- HUGGINGFACE_TOKEN=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
51
  ENABLE_SENTIMENT=true
52
  SENTIMENT_SOCIAL_MODEL=ElKulako/cryptobert
53
  SENTIMENT_NEWS_MODEL=kk08/CryptoBERT
 
47
 
48
  #### 1. **Environment Configuration** (`.env`)
49
  ```env
50
+ HUGGINGFACE_TOKEN=hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
51
  ENABLE_SENTIMENT=true
52
  SENTIMENT_SOCIAL_MODEL=ElKulako/cryptobert
53
  SENTIMENT_NEWS_MODEL=kk08/CryptoBERT
hf-data-engine/providers_config_ultimate.json CHANGED
@@ -566,7 +566,7 @@
566
  "endpoints": {},
567
  "rate_limit": {},
568
  "requires_auth": true,
569
- "api_keys": ["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"],
570
  "auth_type": "header",
571
  "auth_header": "Authorization",
572
  "priority": 8,
 
566
  "endpoints": {},
567
  "rate_limit": {},
568
  "requires_auth": true,
569
+ "api_keys": ["hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],
570
  "auth_type": "header",
571
  "auth_header": "Authorization",
572
  "priority": 8,
providers_config_ultimate.json CHANGED
@@ -566,7 +566,7 @@
566
  "endpoints": {},
567
  "rate_limit": {},
568
  "requires_auth": true,
569
- "api_keys": ["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"],
570
  "auth_type": "header",
571
  "auth_header": "Authorization",
572
  "priority": 8,
 
566
  "endpoints": {},
567
  "rate_limit": {},
568
  "requires_auth": true,
569
+ "api_keys": ["hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],
570
  "auth_type": "header",
571
  "auth_header": "Authorization",
572
  "priority": 8,
run_server.ps1 CHANGED
@@ -8,7 +8,7 @@ Write-Host ""
8
 
9
  # Set environment variables
10
  Write-Host "[1/3] Setting environment variables..." -ForegroundColor Yellow
11
- $env:HF_TOKEN = "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"
12
  $env:HF_MODE = "public"
13
  $env:PORT = "7860"
14
 
 
8
 
9
  # Set environment variables
10
  Write-Host "[1/3] Setting environment variables..." -ForegroundColor Yellow
11
+ $env:HF_TOKEN = "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
12
  $env:HF_MODE = "public"
13
  $env:PORT = "7860"
14
 
set_env.ps1 CHANGED
@@ -3,7 +3,7 @@
3
 
4
  Write-Host "Setting Hugging Face environment variables..." -ForegroundColor Cyan
5
 
6
- $env:HF_TOKEN = "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"
7
  $env:HF_MODE = "public"
8
  $env:PORT = "7860"
9
 
 
3
 
4
  Write-Host "Setting Hugging Face environment variables..." -ForegroundColor Cyan
5
 
6
+ $env:HF_TOKEN = "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
7
  $env:HF_MODE = "public"
8
  $env:PORT = "7860"
9
 
setup_cryptobert.sh CHANGED
@@ -8,7 +8,7 @@ echo "========================================="
8
  echo ""
9
 
10
  # Default token (can be overridden)
11
- DEFAULT_TOKEN="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"
12
 
13
  # Check if HF_TOKEN is already set
14
  if [ -n "$HF_TOKEN" ]; then
 
8
  echo ""
9
 
10
  # Default token (can be overridden)
11
+ DEFAULT_TOKEN="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
12
 
13
  # Check if HF_TOKEN is already set
14
  if [ -n "$HF_TOKEN" ]; then
static/js/huggingface-integration.js CHANGED
@@ -215,7 +215,7 @@ class HuggingFaceIntegration {
215
  // Priority: window.HF_API_KEY > DASHBOARD_CONFIG.HF_TOKEN > default
216
  return window.HF_API_KEY ||
217
  (window.DASHBOARD_CONFIG && window.DASHBOARD_CONFIG.HF_TOKEN) ||
218
- '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';
219
  }
220
  }
221
 
 
215
  // Priority: window.HF_API_KEY > DASHBOARD_CONFIG.HF_TOKEN > default
216
  return window.HF_API_KEY ||
217
  (window.DASHBOARD_CONFIG && window.DASHBOARD_CONFIG.HF_TOKEN) ||
218
+ 'hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
219
  }
220
  }
221
 
static/providers_config_ultimate.json CHANGED
@@ -566,7 +566,7 @@
566
  "endpoints": {},
567
  "rate_limit": {},
568
  "requires_auth": true,
569
- "api_keys": ["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"],
570
  "auth_type": "header",
571
  "auth_header": "Authorization",
572
  "priority": 8,
 
566
  "endpoints": {},
567
  "rate_limit": {},
568
  "requires_auth": true,
569
+ "api_keys": ["hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],
570
  "auth_type": "header",
571
  "auth_header": "Authorization",
572
  "priority": 8,
test_cryptobert.py CHANGED
@@ -10,7 +10,7 @@ import json
10
  from typing import Dict, Any
11
 
12
  # Ensure the token is set
13
- os.environ.setdefault("HF_TOKEN", "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")
14
 
15
  # Import after setting environment variable
16
  import config
 
10
  from typing import Dict, Any
11
 
12
  # Ensure the token is set
13
+ os.environ.setdefault("HF_TOKEN", "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
14
 
15
  # Import after setting environment variable
16
  import config