helius-mcp 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tools/config.js +4 -4
- package/dist/tools/docs.d.ts +2 -0
- package/dist/tools/docs.js +215 -0
- package/dist/tools/guides.js +49 -19
- package/dist/tools/index.js +2 -0
- package/dist/tools/plans.js +7 -5
- package/dist/utils/docs.d.ts +47 -0
- package/dist/utils/docs.js +168 -0
- package/dist/utils/helius.js +1 -1
- package/package.json +1 -1
package/dist/tools/config.js
CHANGED
|
@@ -35,15 +35,15 @@ export function registerConfigTools(server) {
|
|
|
35
35
|
'"env": { "HELIUS_API_KEY": "your-api-key" }',
|
|
36
36
|
'```',
|
|
37
37
|
'',
|
|
38
|
-
'**Get your free API key at: https://
|
|
38
|
+
'**Get your free API key at: https://dashboard.helius.dev/api-keys**',
|
|
39
39
|
'',
|
|
40
40
|
'Note: Guide tools (getRateLimitInfo, getSenderInfo, etc.) work without an API key.',
|
|
41
41
|
].join('\n')
|
|
42
42
|
}]
|
|
43
43
|
};
|
|
44
44
|
});
|
|
45
|
-
server.tool('setHeliusApiKey', 'Set the Helius API key for the current session. Required before using data tools (getBalance, getAsset, etc.). Get your free API key at https://
|
|
46
|
-
apiKey: z.string().describe('Your Helius API key from https://
|
|
45
|
+
server.tool('setHeliusApiKey', 'Set the Helius API key for the current session. Required before using data tools (getBalance, getAsset, etc.). Get your free API key at https://dashboard.helius.dev/api-keys', {
|
|
46
|
+
apiKey: z.string().describe('Your Helius API key from https://dashboard.helius.dev/api-keys'),
|
|
47
47
|
network: z.enum(['mainnet-beta', 'devnet']).optional().default('mainnet-beta').describe('Network to use (default: mainnet-beta)')
|
|
48
48
|
}, async ({ apiKey, network }) => {
|
|
49
49
|
setApiKey(apiKey);
|
|
@@ -67,7 +67,7 @@ export function registerConfigTools(server) {
|
|
|
67
67
|
'',
|
|
68
68
|
'Please check your key and try again.',
|
|
69
69
|
'',
|
|
70
|
-
'Get your free API key at: https://
|
|
70
|
+
'Get your free API key at: https://dashboard.helius.dev/api-keys',
|
|
71
71
|
].join('\n')
|
|
72
72
|
}],
|
|
73
73
|
isError: true
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { fetchDoc, getDocsIndex } from '../utils/docs.js';
|
|
3
|
+
export function registerDocsTools(server) {
|
|
4
|
+
/**
|
|
5
|
+
* Lookup Helius documentation - fetches official docs for accurate information
|
|
6
|
+
*/
|
|
7
|
+
server.tool('lookupHeliusDocs', 'Fetch official Helius documentation for accurate, up-to-date information. Use this when you need precise details about APIs, pricing, rate limits, or features. Returns the official llms.txt documentation which is optimized for AI consumption.', {
|
|
8
|
+
topic: z
|
|
9
|
+
.enum([
|
|
10
|
+
'overview',
|
|
11
|
+
'das',
|
|
12
|
+
'rpc',
|
|
13
|
+
'websocket',
|
|
14
|
+
'enhanced-websockets',
|
|
15
|
+
'webhooks',
|
|
16
|
+
'enhanced-transactions',
|
|
17
|
+
'sender',
|
|
18
|
+
'priority-fee',
|
|
19
|
+
'laserstream',
|
|
20
|
+
'wallet-api',
|
|
21
|
+
'zk-compression',
|
|
22
|
+
'dedicated-nodes',
|
|
23
|
+
'shred-delivery',
|
|
24
|
+
])
|
|
25
|
+
.describe('Documentation topic to fetch'),
|
|
26
|
+
section: z
|
|
27
|
+
.string()
|
|
28
|
+
.optional()
|
|
29
|
+
.describe('Optional: specific section to extract (e.g., "credits", "rate limits", "parameters"). If provided, returns only matching sections.'),
|
|
30
|
+
}, async ({ topic, section }) => {
|
|
31
|
+
try {
|
|
32
|
+
const content = await fetchDoc(topic);
|
|
33
|
+
// If a section filter is provided, extract relevant parts
|
|
34
|
+
if (section) {
|
|
35
|
+
const sectionLower = section.toLowerCase();
|
|
36
|
+
const lines = content.split('\n');
|
|
37
|
+
const relevantLines = [];
|
|
38
|
+
let inRelevantSection = false;
|
|
39
|
+
let sectionDepth = 0;
|
|
40
|
+
for (const line of lines) {
|
|
41
|
+
// Check if this is a header
|
|
42
|
+
const headerMatch = line.match(/^(#{1,4})\s+(.+)/);
|
|
43
|
+
if (headerMatch) {
|
|
44
|
+
const depth = headerMatch[1].length;
|
|
45
|
+
const title = headerMatch[2].toLowerCase();
|
|
46
|
+
if (title.includes(sectionLower)) {
|
|
47
|
+
inRelevantSection = true;
|
|
48
|
+
sectionDepth = depth;
|
|
49
|
+
relevantLines.push(line);
|
|
50
|
+
}
|
|
51
|
+
else if (inRelevantSection && depth <= sectionDepth) {
|
|
52
|
+
// We've hit a new section at same or higher level
|
|
53
|
+
inRelevantSection = false;
|
|
54
|
+
}
|
|
55
|
+
else if (inRelevantSection) {
|
|
56
|
+
relevantLines.push(line);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (inRelevantSection) {
|
|
60
|
+
relevantLines.push(line);
|
|
61
|
+
}
|
|
62
|
+
else if (line.toLowerCase().includes(sectionLower)) {
|
|
63
|
+
// Include lines that mention the section keyword even outside headers
|
|
64
|
+
relevantLines.push(line);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (relevantLines.length > 0) {
|
|
68
|
+
const result = [
|
|
69
|
+
`# Helius Docs: ${topic} (filtered by "${section}")`,
|
|
70
|
+
'',
|
|
71
|
+
...relevantLines,
|
|
72
|
+
'',
|
|
73
|
+
'---',
|
|
74
|
+
`Source: https://www.helius.dev/docs (${topic})`,
|
|
75
|
+
].join('\n');
|
|
76
|
+
return { content: [{ type: 'text', text: result }] };
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
return {
|
|
80
|
+
content: [
|
|
81
|
+
{
|
|
82
|
+
type: 'text',
|
|
83
|
+
text: `No sections matching "${section}" found in ${topic} docs. Returning full documentation:\n\n${content}`,
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// Return full documentation
|
|
90
|
+
const result = [
|
|
91
|
+
`# Helius Docs: ${topic}`,
|
|
92
|
+
'',
|
|
93
|
+
content,
|
|
94
|
+
'',
|
|
95
|
+
'---',
|
|
96
|
+
`Source: https://www.helius.dev/docs`,
|
|
97
|
+
].join('\n');
|
|
98
|
+
return { content: [{ type: 'text', text: result }] };
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
102
|
+
return {
|
|
103
|
+
content: [
|
|
104
|
+
{
|
|
105
|
+
type: 'text',
|
|
106
|
+
text: `Error fetching docs: ${errorMsg}\n\nTry again or check https://www.helius.dev/docs directly.`,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
isError: true,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
/**
|
|
114
|
+
* List available documentation topics
|
|
115
|
+
*/
|
|
116
|
+
server.tool('listHeliusDocTopics', 'List all available Helius documentation topics that can be fetched with lookupHeliusDocs.', {}, async () => {
|
|
117
|
+
const index = getDocsIndex();
|
|
118
|
+
const lines = [
|
|
119
|
+
'# Available Helius Documentation Topics',
|
|
120
|
+
'',
|
|
121
|
+
'Use `lookupHeliusDocs` with any of these topics to fetch official documentation:',
|
|
122
|
+
'',
|
|
123
|
+
'| Topic | Description |',
|
|
124
|
+
'|-------|-------------|',
|
|
125
|
+
...index.map((doc) => `| \`${doc.key}\` | ${doc.description} |`),
|
|
126
|
+
'',
|
|
127
|
+
'## Usage Examples',
|
|
128
|
+
'',
|
|
129
|
+
'```',
|
|
130
|
+
'// Get overview with plans, credits, rate limits',
|
|
131
|
+
'lookupHeliusDocs({ topic: "overview" })',
|
|
132
|
+
'',
|
|
133
|
+
'// Get DAS API documentation',
|
|
134
|
+
'lookupHeliusDocs({ topic: "das" })',
|
|
135
|
+
'',
|
|
136
|
+
'// Get specific section from docs',
|
|
137
|
+
'lookupHeliusDocs({ topic: "overview", section: "credits" })',
|
|
138
|
+
'lookupHeliusDocs({ topic: "das", section: "rate limits" })',
|
|
139
|
+
'```',
|
|
140
|
+
];
|
|
141
|
+
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
142
|
+
});
|
|
143
|
+
/**
|
|
144
|
+
* Get credits information from official docs
|
|
145
|
+
*/
|
|
146
|
+
server.tool('getHeliusCreditsInfo', 'Get official Helius credit costs from documentation. Fetches the latest pricing information directly from Helius docs.', {}, async () => {
|
|
147
|
+
try {
|
|
148
|
+
const content = await fetchDoc('overview');
|
|
149
|
+
// Extract credits section
|
|
150
|
+
const lines = content.split('\n');
|
|
151
|
+
const creditsLines = [];
|
|
152
|
+
let inCreditsSection = false;
|
|
153
|
+
for (let i = 0; i < lines.length; i++) {
|
|
154
|
+
const line = lines[i];
|
|
155
|
+
// Look for Credits section
|
|
156
|
+
if (line.includes('## Credits') || line.includes('| Credits |')) {
|
|
157
|
+
inCreditsSection = true;
|
|
158
|
+
}
|
|
159
|
+
if (inCreditsSection) {
|
|
160
|
+
creditsLines.push(line);
|
|
161
|
+
// Stop at next major section
|
|
162
|
+
if (creditsLines.length > 2 && line.startsWith('## ') && !line.includes('Credits')) {
|
|
163
|
+
creditsLines.pop(); // Remove the next section header
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Also look for the credits table
|
|
169
|
+
const tableLines = [];
|
|
170
|
+
for (let i = 0; i < lines.length; i++) {
|
|
171
|
+
if (lines[i].includes('| Credits |') || lines[i].includes('| 0 |') || lines[i].includes('| 1 |') || lines[i].includes('| 3 |') || lines[i].includes('| 10 |') || lines[i].includes('| 100 |')) {
|
|
172
|
+
// Collect table lines
|
|
173
|
+
let j = i;
|
|
174
|
+
while (j < lines.length && (lines[j].includes('|') || lines[j].trim() === '')) {
|
|
175
|
+
if (lines[j].includes('|')) {
|
|
176
|
+
tableLines.push(lines[j]);
|
|
177
|
+
}
|
|
178
|
+
j++;
|
|
179
|
+
if (j - i > 20)
|
|
180
|
+
break; // Safety limit
|
|
181
|
+
}
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const result = [
|
|
186
|
+
'# Helius Credit Costs (Official)',
|
|
187
|
+
'',
|
|
188
|
+
'Source: https://www.helius.dev/docs (fetched live)',
|
|
189
|
+
'',
|
|
190
|
+
...tableLines,
|
|
191
|
+
'',
|
|
192
|
+
'## Key Points',
|
|
193
|
+
'- Credits are consumed per API call',
|
|
194
|
+
'- Monthly allocation resets each billing cycle',
|
|
195
|
+
'- Additional credits: $5 per million (paid plans)',
|
|
196
|
+
'',
|
|
197
|
+
'## Credit Tiers',
|
|
198
|
+
'| Plan | Monthly Credits |',
|
|
199
|
+
'|------|-----------------|',
|
|
200
|
+
'| Free | 1M |',
|
|
201
|
+
'| Developer ($49/mo) | 10M |',
|
|
202
|
+
'| Business ($499/mo) | 100M |',
|
|
203
|
+
'| Professional ($999/mo) | 200M |',
|
|
204
|
+
].join('\n');
|
|
205
|
+
return { content: [{ type: 'text', text: result }] };
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
209
|
+
return {
|
|
210
|
+
content: [{ type: 'text', text: `Error fetching credits info: ${errorMsg}` }],
|
|
211
|
+
isError: true,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
package/dist/tools/guides.js
CHANGED
|
@@ -30,38 +30,68 @@ const RATE_LIMITS = {
|
|
|
30
30
|
websocket: { connections: 250, enhanced: 100 },
|
|
31
31
|
},
|
|
32
32
|
};
|
|
33
|
-
// Credit costs per method
|
|
33
|
+
// Credit costs per method - aligned with official Helius docs
|
|
34
|
+
// Source: https://www.helius.dev/docs/billing/credits
|
|
34
35
|
const CREDIT_COSTS = {
|
|
35
|
-
//
|
|
36
|
+
// === 0 CREDITS ===
|
|
37
|
+
'Helius Sender': { cost: 0, notes: 'Ultra-low latency transaction submission' },
|
|
38
|
+
// === 1 CREDIT (Standard RPC) ===
|
|
36
39
|
getBalance: { cost: 1 },
|
|
37
40
|
getAccountInfo: { cost: 1 },
|
|
38
|
-
getMultipleAccounts: { cost: 1
|
|
39
|
-
getTransaction: { cost: 1 },
|
|
40
|
-
getSignaturesForAddress: { cost: 1 },
|
|
41
|
-
getBlock: { cost: 1 },
|
|
41
|
+
getMultipleAccounts: { cost: 1 },
|
|
42
42
|
getBlockHeight: { cost: 1 },
|
|
43
43
|
getSlot: { cost: 1 },
|
|
44
44
|
getLatestBlockhash: { cost: 1 },
|
|
45
|
-
sendTransaction: { cost: 1 },
|
|
45
|
+
sendTransaction: { cost: 1, notes: 'Via staked connections' },
|
|
46
46
|
simulateTransaction: { cost: 1 },
|
|
47
47
|
getTokenAccountsByOwner: { cost: 1 },
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
getProgramAccountsV2: { cost: 1, notes: 'Paginated version' },
|
|
49
|
+
getTokenAccountsByOwnerV2: { cost: 1, notes: 'Paginated version' },
|
|
50
|
+
simulateBundle: { cost: 1, notes: 'Jito bundle simulation' },
|
|
51
|
+
'Priority Fee API': { cost: 1 },
|
|
52
|
+
'getSignatureStatuses (recent)': { cost: 1, notes: 'With searchTransactionHistory: false' },
|
|
53
|
+
// === 3 CREDITS (Data Streaming) ===
|
|
54
|
+
'LaserStream gRPC': { cost: '3 per 0.1 MB', notes: 'Uncompressed data streamed' },
|
|
55
|
+
'Enhanced WebSockets': { cost: '3 per 0.1 MB', notes: 'Uncompressed data streamed' },
|
|
56
|
+
// === 10 CREDITS (Historical Data & DAS API) ===
|
|
57
|
+
getProgramAccounts: { cost: 10, notes: 'Use getProgramAccountsV2 for 1 credit' },
|
|
58
|
+
getBlock: { cost: 10, notes: 'Historical/archival data' },
|
|
59
|
+
getBlocks: { cost: 10 },
|
|
60
|
+
getBlocksWithLimit: { cost: 10 },
|
|
61
|
+
getBlockTime: { cost: 10 },
|
|
62
|
+
getTransaction: { cost: 10, notes: 'Historical/archival data' },
|
|
63
|
+
getSignaturesForAddress: { cost: 10 },
|
|
64
|
+
getInflationReward: { cost: 10 },
|
|
65
|
+
'getSignatureStatuses (historical)': { cost: 10, notes: 'With searchTransactionHistory: true' },
|
|
66
|
+
// DAS API (all 10 credits)
|
|
50
67
|
getAsset: { cost: 10 },
|
|
51
|
-
|
|
68
|
+
getAssetBatch: { cost: 10 },
|
|
69
|
+
getAssetsByOwner: { cost: 10 },
|
|
52
70
|
getAssetsByGroup: { cost: 10 },
|
|
53
71
|
getAssetsByCreator: { cost: 10 },
|
|
54
|
-
|
|
72
|
+
getAssetsByAuthority: { cost: 10 },
|
|
73
|
+
searchAssets: { cost: 10 },
|
|
55
74
|
getAssetProof: { cost: 10 },
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
75
|
+
getAssetProofBatch: { cost: 10 },
|
|
76
|
+
getNftEditions: { cost: 10 },
|
|
77
|
+
getSignaturesForAsset: { cost: 10 },
|
|
78
|
+
getTokenAccounts: { cost: 10 },
|
|
79
|
+
// ZK Compression (10 credits)
|
|
80
|
+
'ZK Compression API': { cost: 10 },
|
|
81
|
+
// === 100 CREDITS (Enhanced APIs) ===
|
|
82
|
+
'Enhanced Transactions API': { cost: 100, notes: 'parseTransactions, parsed history' },
|
|
83
|
+
getTransactionsForAddress: { cost: 100, notes: 'Developer+ plans only' },
|
|
84
|
+
getValidityProof: { cost: 100, notes: 'ZK Compression - computationally intensive' },
|
|
85
|
+
// Wallet API (all 100 credits)
|
|
86
|
+
'Wallet Identity': { cost: 100 },
|
|
87
|
+
'Batch Identity Lookup': { cost: 100, notes: 'Up to 100 addresses' },
|
|
88
|
+
'Wallet Balances': { cost: 100 },
|
|
89
|
+
'Wallet History': { cost: 100 },
|
|
90
|
+
'Token Transfers': { cost: 100 },
|
|
91
|
+
'Wallet Funding Source': { cost: 100 },
|
|
60
92
|
// Webhooks
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
wsConnection: { cost: 1, notes: 'Per new connection opened' },
|
|
64
|
-
wsDataStreaming: { cost: '3 per 0.1 MB', notes: 'Enhanced WS only; Standard WS is free' },
|
|
93
|
+
'Webhook Events': { cost: 1, notes: 'Per event delivered' },
|
|
94
|
+
'Webhook Management': { cost: 100, notes: 'Create, edit, or delete' },
|
|
65
95
|
};
|
|
66
96
|
// Error codes and their meanings
|
|
67
97
|
const ERROR_CODES = {
|
package/dist/tools/index.js
CHANGED
|
@@ -14,6 +14,7 @@ import { registerLaserstreamTools } from './laserstream.js';
|
|
|
14
14
|
import { registerWalletTools } from './wallet.js';
|
|
15
15
|
import { registerPlanTools } from './plans.js';
|
|
16
16
|
import { registerGuideTools } from './guides.js';
|
|
17
|
+
import { registerDocsTools } from './docs.js';
|
|
17
18
|
export function registerTools(server) {
|
|
18
19
|
registerConfigTools(server);
|
|
19
20
|
registerBalanceTools(server);
|
|
@@ -31,4 +32,5 @@ export function registerTools(server) {
|
|
|
31
32
|
registerWalletTools(server);
|
|
32
33
|
registerPlanTools(server);
|
|
33
34
|
registerGuideTools(server);
|
|
35
|
+
registerDocsTools(server);
|
|
34
36
|
}
|
package/dist/tools/plans.js
CHANGED
|
@@ -189,11 +189,13 @@ export function registerPlanTools(server) {
|
|
|
189
189
|
'- **Data add-ons:** Starting at $500/mo for Professional',
|
|
190
190
|
'- **Features:** 24h historical replay, lowest latency',
|
|
191
191
|
'',
|
|
192
|
-
'### Credit Costs',
|
|
193
|
-
'-
|
|
194
|
-
'-
|
|
195
|
-
'-
|
|
196
|
-
'-
|
|
192
|
+
'### Credit Costs (from docs)',
|
|
193
|
+
'- **0 credits**: Helius Sender',
|
|
194
|
+
'- **1 credit**: Standard RPC, sendTransaction, Priority Fee API, webhook events',
|
|
195
|
+
'- **3 credits**: per 0.1 MB streamed (LaserStream, Enhanced WS)',
|
|
196
|
+
'- **10 credits**: getProgramAccounts, historical data (getBlock, getTransaction, etc.), DAS API',
|
|
197
|
+
'- **100 credits**: Enhanced Transactions, Wallet API, getValidityProof (ZK), webhook management',
|
|
198
|
+
'- **Additional credits**: $5 per million (all paid plans)',
|
|
197
199
|
'',
|
|
198
200
|
'**Docs:** https://www.helius.dev/pricing',
|
|
199
201
|
];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helius Documentation Fetcher
|
|
3
|
+
*
|
|
4
|
+
* Fetches official Helius documentation from GitHub for accurate, up-to-date information.
|
|
5
|
+
* Uses llms.txt files which are AI-optimized summaries of the documentation.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DOCS_INDEX: Record<string, {
|
|
8
|
+
path: string;
|
|
9
|
+
description: string;
|
|
10
|
+
}>;
|
|
11
|
+
/**
|
|
12
|
+
* Fetch a specific documentation file
|
|
13
|
+
*/
|
|
14
|
+
export declare function fetchDoc(docKey: string): Promise<string>;
|
|
15
|
+
/**
|
|
16
|
+
* Fetch multiple documentation files
|
|
17
|
+
*/
|
|
18
|
+
export declare function fetchDocs(docKeys: string[]): Promise<Map<string, string>>;
|
|
19
|
+
/**
|
|
20
|
+
* Get the list of available documentation topics
|
|
21
|
+
*/
|
|
22
|
+
export declare function getAvailableDocTopics(): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Get documentation index with descriptions
|
|
25
|
+
*/
|
|
26
|
+
export declare function getDocsIndex(): Array<{
|
|
27
|
+
key: string;
|
|
28
|
+
description: string;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Search docs content for a specific term (searches cached docs only)
|
|
32
|
+
*/
|
|
33
|
+
export declare function searchCachedDocs(searchTerm: string): Array<{
|
|
34
|
+
docKey: string;
|
|
35
|
+
matches: string[];
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Clear the docs cache (useful for forcing fresh fetches)
|
|
39
|
+
*/
|
|
40
|
+
export declare function clearDocsCache(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Get cache stats
|
|
43
|
+
*/
|
|
44
|
+
export declare function getDocsCacheStats(): {
|
|
45
|
+
cachedDocs: string[];
|
|
46
|
+
totalSize: number;
|
|
47
|
+
};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helius Documentation Fetcher
|
|
3
|
+
*
|
|
4
|
+
* Fetches official Helius documentation from GitHub for accurate, up-to-date information.
|
|
5
|
+
* Uses llms.txt files which are AI-optimized summaries of the documentation.
|
|
6
|
+
*/
|
|
7
|
+
// GitHub raw URL base for Helius docs
|
|
8
|
+
const DOCS_BASE_URL = 'https://raw.githubusercontent.com/helius-labs/docs/main';
|
|
9
|
+
// Available llms.txt documentation files
|
|
10
|
+
export const DOCS_INDEX = {
|
|
11
|
+
overview: {
|
|
12
|
+
path: '/llms.txt',
|
|
13
|
+
description: 'Main Helius overview: plans, credits, rate limits, use cases, API index',
|
|
14
|
+
},
|
|
15
|
+
das: {
|
|
16
|
+
path: '/api-reference/das/llms.txt',
|
|
17
|
+
description: 'DAS API: getAsset, getAssetsByOwner, searchAssets, compressed NFTs',
|
|
18
|
+
},
|
|
19
|
+
rpc: {
|
|
20
|
+
path: '/api-reference/rpc/http/llms.txt',
|
|
21
|
+
description: 'Standard Solana RPC methods with Helius enhancements',
|
|
22
|
+
},
|
|
23
|
+
websocket: {
|
|
24
|
+
path: '/api-reference/rpc/websocket/llms.txt',
|
|
25
|
+
description: 'Standard Solana WebSocket subscriptions',
|
|
26
|
+
},
|
|
27
|
+
'enhanced-websockets': {
|
|
28
|
+
path: '/enhanced-websockets/llms.txt',
|
|
29
|
+
description: 'Enhanced WebSockets: transactionSubscribe, accountSubscribe, filtering',
|
|
30
|
+
},
|
|
31
|
+
webhooks: {
|
|
32
|
+
path: '/api-reference/webhooks/llms.txt',
|
|
33
|
+
description: 'Webhooks: setup, transaction types, delivery, troubleshooting',
|
|
34
|
+
},
|
|
35
|
+
'enhanced-transactions': {
|
|
36
|
+
path: '/api-reference/enhanced-transactions/llms.txt',
|
|
37
|
+
description: 'Enhanced Transactions API: parseTransactions, transaction history',
|
|
38
|
+
},
|
|
39
|
+
sender: {
|
|
40
|
+
path: '/api-reference/sender/llms.txt',
|
|
41
|
+
description: 'Helius Sender: transaction submission, SWQoS, tips, latency',
|
|
42
|
+
},
|
|
43
|
+
'priority-fee': {
|
|
44
|
+
path: '/api-reference/priority-fee/llms.txt',
|
|
45
|
+
description: 'Priority Fee API: fee estimation, compute units',
|
|
46
|
+
},
|
|
47
|
+
laserstream: {
|
|
48
|
+
path: '/api-reference/laserstream/grpc/llms.txt',
|
|
49
|
+
description: 'LaserStream gRPC: real-time streaming, subscriptions, replay',
|
|
50
|
+
},
|
|
51
|
+
'wallet-api': {
|
|
52
|
+
path: '/api-reference/wallet-api/llms.txt',
|
|
53
|
+
description: 'Wallet API: balances, history, transfers, identity, funding source',
|
|
54
|
+
},
|
|
55
|
+
'zk-compression': {
|
|
56
|
+
path: '/api-reference/zk-compression/llms.txt',
|
|
57
|
+
description: 'ZK Compression API: compressed accounts, validity proofs',
|
|
58
|
+
},
|
|
59
|
+
'dedicated-nodes': {
|
|
60
|
+
path: '/dedicated-nodes/llms.txt',
|
|
61
|
+
description: 'Dedicated Nodes: private infrastructure, Yellowstone gRPC',
|
|
62
|
+
},
|
|
63
|
+
'shred-delivery': {
|
|
64
|
+
path: '/shred-delivery/llms.txt',
|
|
65
|
+
description: 'Shred Delivery: lowest latency, UDP shreds',
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
// In-memory cache for fetched docs (per session)
|
|
69
|
+
const docsCache = new Map();
|
|
70
|
+
const CACHE_TTL_MS = 30 * 60 * 1000; // 30 minutes
|
|
71
|
+
/**
|
|
72
|
+
* Fetch a specific documentation file
|
|
73
|
+
*/
|
|
74
|
+
export async function fetchDoc(docKey) {
|
|
75
|
+
const docInfo = DOCS_INDEX[docKey];
|
|
76
|
+
if (!docInfo) {
|
|
77
|
+
const availableKeys = Object.keys(DOCS_INDEX).join(', ');
|
|
78
|
+
throw new Error(`Unknown doc key: "${docKey}". Available: ${availableKeys}`);
|
|
79
|
+
}
|
|
80
|
+
// Check cache
|
|
81
|
+
const cached = docsCache.get(docKey);
|
|
82
|
+
if (cached && Date.now() - cached.fetchedAt < CACHE_TTL_MS) {
|
|
83
|
+
return cached.content;
|
|
84
|
+
}
|
|
85
|
+
// Fetch from GitHub
|
|
86
|
+
const url = `${DOCS_BASE_URL}${docInfo.path}`;
|
|
87
|
+
try {
|
|
88
|
+
const response = await fetch(url);
|
|
89
|
+
if (!response.ok) {
|
|
90
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
91
|
+
}
|
|
92
|
+
const content = await response.text();
|
|
93
|
+
// Cache the result
|
|
94
|
+
docsCache.set(docKey, { content, fetchedAt: Date.now() });
|
|
95
|
+
return content;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
99
|
+
throw new Error(`Failed to fetch docs from ${url}: ${errorMsg}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Fetch multiple documentation files
|
|
104
|
+
*/
|
|
105
|
+
export async function fetchDocs(docKeys) {
|
|
106
|
+
const results = new Map();
|
|
107
|
+
const errors = [];
|
|
108
|
+
await Promise.all(docKeys.map(async (key) => {
|
|
109
|
+
try {
|
|
110
|
+
const content = await fetchDoc(key);
|
|
111
|
+
results.set(key, content);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
errors.push(`${key}: ${error instanceof Error ? error.message : String(error)}`);
|
|
115
|
+
}
|
|
116
|
+
}));
|
|
117
|
+
if (errors.length > 0 && results.size === 0) {
|
|
118
|
+
throw new Error(`Failed to fetch any docs:\n${errors.join('\n')}`);
|
|
119
|
+
}
|
|
120
|
+
return results;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get the list of available documentation topics
|
|
124
|
+
*/
|
|
125
|
+
export function getAvailableDocTopics() {
|
|
126
|
+
return Object.keys(DOCS_INDEX);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get documentation index with descriptions
|
|
130
|
+
*/
|
|
131
|
+
export function getDocsIndex() {
|
|
132
|
+
return Object.entries(DOCS_INDEX).map(([key, info]) => ({
|
|
133
|
+
key,
|
|
134
|
+
description: info.description,
|
|
135
|
+
}));
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Search docs content for a specific term (searches cached docs only)
|
|
139
|
+
*/
|
|
140
|
+
export function searchCachedDocs(searchTerm) {
|
|
141
|
+
const results = [];
|
|
142
|
+
const searchLower = searchTerm.toLowerCase();
|
|
143
|
+
for (const [docKey, cached] of docsCache.entries()) {
|
|
144
|
+
const lines = cached.content.split('\n');
|
|
145
|
+
const matches = lines.filter((line) => line.toLowerCase().includes(searchLower));
|
|
146
|
+
if (matches.length > 0) {
|
|
147
|
+
results.push({ docKey, matches: matches.slice(0, 5) }); // Limit to 5 matches per doc
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return results;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Clear the docs cache (useful for forcing fresh fetches)
|
|
154
|
+
*/
|
|
155
|
+
export function clearDocsCache() {
|
|
156
|
+
docsCache.clear();
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Get cache stats
|
|
160
|
+
*/
|
|
161
|
+
export function getDocsCacheStats() {
|
|
162
|
+
const cachedDocs = Array.from(docsCache.keys());
|
|
163
|
+
let totalSize = 0;
|
|
164
|
+
for (const cached of docsCache.values()) {
|
|
165
|
+
totalSize += cached.content.length;
|
|
166
|
+
}
|
|
167
|
+
return { cachedDocs, totalSize };
|
|
168
|
+
}
|
package/dist/utils/helius.js
CHANGED
|
@@ -12,7 +12,7 @@ export function getApiKey() {
|
|
|
12
12
|
throw new Error('API key not set. Please use the setHeliusApiKey tool first:\n\n' +
|
|
13
13
|
' Tool: setHeliusApiKey\n' +
|
|
14
14
|
' Arguments: { "apiKey": "your-helius-api-key" }\n\n' +
|
|
15
|
-
'Get your free API key at: https://
|
|
15
|
+
'Get your free API key at: https://dashboard.helius.dev/api-keys');
|
|
16
16
|
}
|
|
17
17
|
return apiKey;
|
|
18
18
|
}
|