helius-mcp 0.5.3 → 1.2.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/LICENSE +1 -1
  3. package/README.md +97 -21
  4. package/dist/http.d.ts +1 -0
  5. package/dist/http.js +2 -0
  6. package/dist/index.js +93 -2
  7. package/dist/scripts/validate-catalog.d.ts +13 -0
  8. package/dist/scripts/validate-catalog.js +76 -0
  9. package/dist/tools/accounts.js +114 -204
  10. package/dist/tools/assets.js +109 -123
  11. package/dist/tools/auth.d.ts +2 -0
  12. package/dist/tools/auth.js +459 -0
  13. package/dist/tools/balance.js +28 -32
  14. package/dist/tools/blocks.js +68 -87
  15. package/dist/tools/config.js +18 -79
  16. package/dist/tools/das-extras.js +56 -41
  17. package/dist/tools/docs.js +12 -54
  18. package/dist/tools/enhanced-websockets.js +104 -74
  19. package/dist/tools/fees.js +42 -61
  20. package/dist/tools/guides.js +126 -515
  21. package/dist/tools/index.js +50 -2
  22. package/dist/tools/laserstream.js +107 -53
  23. package/dist/tools/network.js +47 -69
  24. package/dist/tools/plans.d.ts +21 -0
  25. package/dist/tools/plans.js +105 -246
  26. package/dist/tools/product-catalog.d.ts +10 -0
  27. package/dist/tools/product-catalog.js +123 -0
  28. package/dist/tools/recommend.d.ts +4 -0
  29. package/dist/tools/recommend.js +233 -0
  30. package/dist/tools/shared.js +8 -3
  31. package/dist/tools/solana-knowledge.d.ts +2 -0
  32. package/dist/tools/solana-knowledge.js +544 -0
  33. package/dist/tools/tokens.js +17 -18
  34. package/dist/tools/transactions.js +232 -302
  35. package/dist/tools/transfers.d.ts +2 -0
  36. package/dist/tools/transfers.js +270 -0
  37. package/dist/tools/wallet.js +175 -177
  38. package/dist/tools/webhooks.js +80 -82
  39. package/dist/types/transaction-types.d.ts +1 -1
  40. package/dist/types/transaction-types.js +2 -1
  41. package/dist/utils/config.d.ts +27 -0
  42. package/dist/utils/config.js +76 -0
  43. package/dist/utils/docs.d.ts +24 -0
  44. package/dist/utils/docs.js +72 -0
  45. package/dist/utils/errors.d.ts +32 -0
  46. package/dist/utils/errors.js +157 -0
  47. package/dist/utils/feedback.d.ts +16 -0
  48. package/dist/utils/feedback.js +87 -0
  49. package/dist/utils/formatters.d.ts +0 -1
  50. package/dist/utils/formatters.js +0 -3
  51. package/dist/utils/helius.d.ts +15 -5
  52. package/dist/utils/helius.js +52 -45
  53. package/dist/version.d.ts +1 -0
  54. package/dist/version.js +1 -0
  55. package/package.json +17 -7
  56. package/system-prompts/helius/claude.system.md +170 -0
  57. package/system-prompts/helius/full.md +2868 -0
  58. package/system-prompts/helius/openai.developer.md +170 -0
  59. package/system-prompts/helius-dflow/claude.system.md +290 -0
  60. package/system-prompts/helius-dflow/full.md +3647 -0
  61. package/system-prompts/helius-dflow/openai.developer.md +290 -0
  62. package/system-prompts/helius-phantom/claude.system.md +348 -0
  63. package/system-prompts/helius-phantom/full.md +5472 -0
  64. package/system-prompts/helius-phantom/openai.developer.md +348 -0
  65. package/system-prompts/svm/claude.system.md +174 -0
  66. package/system-prompts/svm/full.md +699 -0
  67. package/system-prompts/svm/openai.developer.md +174 -0
@@ -1,99 +1,6 @@
1
1
  import { z } from 'zod';
2
- // Rate limit data by plan
3
- const RATE_LIMITS = {
4
- free: {
5
- rpc: { rps: 10, burst: 15 },
6
- sendTransaction: { rps: 1 },
7
- getProgramAccounts: { rps: 5 },
8
- das: { rps: 2 },
9
- websocket: { connections: 5, enhanced: 0 },
10
- },
11
- developer: {
12
- rpc: { rps: 50, burst: 75 },
13
- sendTransaction: { rps: 5 },
14
- getProgramAccounts: { rps: 25 },
15
- das: { rps: 10 },
16
- websocket: { connections: 150, enhanced: 0 },
17
- },
18
- business: {
19
- rpc: { rps: 200, burst: 300 },
20
- sendTransaction: { rps: 50 },
21
- getProgramAccounts: { rps: 50 },
22
- das: { rps: 50 },
23
- websocket: { connections: 250, enhanced: 100 },
24
- },
25
- professional: {
26
- rpc: { rps: 500, burst: 750 },
27
- sendTransaction: { rps: 100 },
28
- getProgramAccounts: { rps: 75 },
29
- das: { rps: 100 },
30
- websocket: { connections: 250, enhanced: 100 },
31
- },
32
- };
33
- // Credit costs per method - aligned with official Helius docs
34
- // Source: https://www.helius.dev/docs/billing/credits
35
- const CREDIT_COSTS = {
36
- // === 0 CREDITS ===
37
- 'Helius Sender': { cost: 0, notes: 'Ultra-low latency transaction submission' },
38
- // === 1 CREDIT (Standard RPC) ===
39
- getBalance: { cost: 1 },
40
- getAccountInfo: { cost: 1 },
41
- getMultipleAccounts: { cost: 1 },
42
- getBlockHeight: { cost: 1 },
43
- getSlot: { cost: 1 },
44
- getLatestBlockhash: { cost: 1 },
45
- sendTransaction: { cost: 1, notes: 'Via staked connections' },
46
- simulateTransaction: { cost: 1 },
47
- getTokenAccountsByOwner: { cost: 1 },
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)
67
- getAsset: { cost: 10 },
68
- getAssetBatch: { cost: 10 },
69
- getAssetsByOwner: { cost: 10 },
70
- getAssetsByGroup: { cost: 10 },
71
- getAssetsByCreator: { cost: 10 },
72
- getAssetsByAuthority: { cost: 10 },
73
- searchAssets: { cost: 10 },
74
- getAssetProof: { cost: 10 },
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 },
92
- // Webhooks
93
- 'Webhook Events': { cost: 1, notes: 'Per event delivered' },
94
- 'Webhook Management': { cost: 100, notes: 'Create, edit, or delete' },
95
- };
96
- // Error codes and their meanings
2
+ import { fetchDoc, fetchDocs, extractSections, truncateDoc } from '../utils/docs.js';
3
+ // Error codes and their meanings — no canonical llms.txt equivalent
97
4
  const ERROR_CODES = {
98
5
  '-32600': {
99
6
  meaning: 'Invalid Request',
@@ -219,244 +126,88 @@ const ERROR_CODES = {
219
126
  },
220
127
  };
221
128
  export function registerGuideTools(server) {
222
- // Tool 1: getRateLimitInfo
223
- server.tool('getRateLimitInfo', 'Get detailed rate limit information including RPS limits, credit costs per method, and burst windows. Helps understand the difference between credits (total monthly quota) and RPS (requests per second limit).', {
224
- plan: z
225
- .enum(['free', 'developer', 'business', 'professional', 'all'])
226
- .optional()
227
- .default('all')
228
- .describe('Plan to show rate limits for'),
229
- showCreditCosts: z
230
- .boolean()
231
- .optional()
232
- .default(true)
233
- .describe('Include credit costs per API method'),
234
- }, async ({ plan, showCreditCosts }) => {
235
- const lines = [];
236
- lines.push('# Rate Limits & Credits Guide', '');
237
- lines.push('## Key Concepts', '');
238
- lines.push('- **Credits**: Monthly quota (1M, 10M, 100M, etc.). Each API call costs credits.');
239
- lines.push('- **RPS**: Requests per second limit. Even with credits remaining, you can hit RPS limits.');
240
- lines.push('- **Burst**: Brief allowance above RPS for short spikes.');
241
- lines.push('- **429 errors**: Can mean EITHER credits exhausted OR RPS exceeded. Check dashboard to distinguish.');
242
- lines.push('');
243
- // Rate limits table
244
- if (plan === 'all') {
245
- lines.push('## Rate Limits by Plan', '');
246
- lines.push('| Limit | Free | Developer | Business | Professional |');
247
- lines.push('|-------|------|-----------|----------|--------------|');
248
- lines.push(`| RPC RPS | ${RATE_LIMITS.free.rpc.rps} | ${RATE_LIMITS.developer.rpc.rps} | ${RATE_LIMITS.business.rpc.rps} | ${RATE_LIMITS.professional.rpc.rps} |`);
249
- lines.push(`| sendTransaction | ${RATE_LIMITS.free.sendTransaction.rps}/s | ${RATE_LIMITS.developer.sendTransaction.rps}/s | ${RATE_LIMITS.business.sendTransaction.rps}/s | ${RATE_LIMITS.professional.sendTransaction.rps}/s |`);
250
- lines.push(`| getProgramAccounts | ${RATE_LIMITS.free.getProgramAccounts.rps}/s | ${RATE_LIMITS.developer.getProgramAccounts.rps}/s | ${RATE_LIMITS.business.getProgramAccounts.rps}/s | ${RATE_LIMITS.professional.getProgramAccounts.rps}/s |`);
251
- lines.push(`| DAS API | ${RATE_LIMITS.free.das.rps}/s | ${RATE_LIMITS.developer.das.rps}/s | ${RATE_LIMITS.business.das.rps}/s | ${RATE_LIMITS.professional.das.rps}/s |`);
252
- lines.push(`| WS Connections | ${RATE_LIMITS.free.websocket.connections} | ${RATE_LIMITS.developer.websocket.connections} | ${RATE_LIMITS.business.websocket.connections} | ${RATE_LIMITS.professional.websocket.connections} |`);
253
- lines.push(`| Enhanced WS | ${RATE_LIMITS.free.websocket.enhanced} | ${RATE_LIMITS.developer.websocket.enhanced} | ${RATE_LIMITS.business.websocket.enhanced} | ${RATE_LIMITS.professional.websocket.enhanced} |`);
129
+ // Tool 1: getRateLimitInfo — fetches live billing docs
130
+ server.tool('getRateLimitInfo', 'BEST FOR: per-method rate limits and credit costs. PREFER getHeliusPlanInfo for plan pricing/features. Get official Helius rate limits and credit costs per API method. Fetches live from billing docs.', {}, async () => {
131
+ try {
132
+ const content = await fetchDoc('billing');
133
+ const rateLimits = extractSections(content, ['rate limits', 'standard rate limits'], { includeLooseMatches: false });
134
+ const creditCosts = extractSections(content, ['credit costs', 'credits system'], { includeLooseMatches: false });
135
+ const sections = [rateLimits, creditCosts].filter(Boolean).join('\n\n');
136
+ const body = sections || truncateDoc(content);
137
+ const result = [
138
+ '# Helius Rate Limits & Credits (Official)',
139
+ '',
140
+ body,
141
+ '',
142
+ '---',
143
+ 'Source: https://www.helius.dev/docs/billing (fetched live)',
144
+ ].join('\n');
145
+ return { content: [{ type: 'text', text: result }] };
254
146
  }
255
- else {
256
- const limits = RATE_LIMITS[plan];
257
- lines.push(`## ${plan.charAt(0).toUpperCase() + plan.slice(1)} Plan Rate Limits`, '');
258
- lines.push(`- **RPC RPS**: ${limits.rpc.rps} (burst: ${limits.rpc.burst})`);
259
- lines.push(`- **sendTransaction**: ${limits.sendTransaction.rps}/sec`);
260
- lines.push(`- **getProgramAccounts**: ${limits.getProgramAccounts.rps}/sec`);
261
- lines.push(`- **DAS API**: ${limits.das.rps}/sec`);
262
- lines.push(`- **WebSocket Connections**: ${limits.websocket.connections}`);
263
- lines.push(`- **Enhanced WebSocket**: ${limits.websocket.enhanced}`);
264
- }
265
- if (showCreditCosts) {
266
- lines.push('', '## Credit Costs per Method', '');
267
- lines.push('| Method | Credits | Notes |');
268
- lines.push('|--------|---------|-------|');
269
- for (const [method, info] of Object.entries(CREDIT_COSTS)) {
270
- lines.push(`| ${method} | ${info.cost} | ${info.notes || ''} |`);
271
- }
147
+ catch (error) {
148
+ const errorMsg = error instanceof Error ? error.message : String(error);
149
+ return {
150
+ content: [{ type: 'text', text: `Error fetching rate limit info: ${errorMsg}` }],
151
+ isError: true,
152
+ };
272
153
  }
273
- lines.push('', '## Best Practices', '');
274
- lines.push('1. **Implement exponential backoff** on 429 errors');
275
- lines.push('2. **Use batch requests** (getMultipleAccounts vs multiple getAccountInfo)');
276
- lines.push('3. **Cache responses** where appropriate (blockhash valid ~60-90s)');
277
- lines.push('4. **Monitor usage** in dashboard to avoid surprises');
278
- lines.push('5. **Spread requests** evenly rather than bursting');
279
- return { content: [{ type: 'text', text: lines.join('\n') }] };
280
- });
281
- // Tool 2: getSenderInfo
282
- server.tool('getSenderInfo', 'Get information about Helius Sender for transaction submission. Covers Sender vs Jito direct, SWQoS routing, tips, landing latency, and best practices for fast transaction landing.', {}, async () => {
283
- const lines = [
284
- '# Helius Sender Guide',
285
- '',
286
- '## What is Sender?',
287
- 'Sender is Helius\'s optimized transaction submission service that uses Stake-Weighted Quality of Service (SWQoS) for faster, more reliable transaction landing.',
288
- '',
289
- '## Key Features',
290
- '- **SWQoS Routing**: Uses staked connections for priority access to leaders',
291
- '- **Jito Integration**: Bundles transactions with Jito for MEV protection',
292
- '- **No Extra Cost**: Included in all paid plans',
293
- '- **No CORS Issues**: Use `Content-Type: text/plain` from browsers',
294
- '',
295
- '## Sender vs Direct Jito',
296
- '',
297
- '| Feature | Helius Sender | Direct Jito |',
298
- '|---------|---------------|-------------|',
299
- '| SWQoS | Included | No |',
300
- '| Jito Bundles | Auto-bundled | Manual |',
301
- '| Tips | Helius handles | You manage |',
302
- '| Setup | Use Helius RPC | Separate integration |',
303
- '',
304
- '## Tips & Fees',
305
- '',
306
- '### Default Tip',
307
- '- **Amount**: ~0.0002 SOL (200,000 lamports)',
308
- '- **Recipient**: Helius tip account (re-bundled with Jito)',
309
- '- **Sufficient for most cases**: Yes, works for normal transactions',
310
- '',
311
- '### Priority Fees',
312
- '- Add `ComputeBudgetProgram.setComputeUnitPrice()` for higher priority',
313
- '- Higher fees = better chance of landing in competitive slots',
314
- '- Use `getPriorityFeeEstimate` to get recommended fees',
315
- '',
316
- '## Expected Latency',
317
- '',
318
- '| Metric | Typical Range |',
319
- '|--------|---------------|',
320
- '| Send to Helius | ~100ms |',
321
- '| Landing (confirmation) | 200-700ms |',
322
- '| Total end-to-end | 300-800ms |',
323
- '',
324
- '**Note**: Latency varies with:',
325
- '- Leader geography (closer = faster)',
326
- '- Network congestion',
327
- '- Priority fee amount',
328
- '- Transaction complexity',
329
- '',
330
- '## Usage',
331
- '',
332
- '### Standard RPC',
333
- '```',
334
- 'POST https://mainnet.helius-rpc.com/?api-key=<KEY>',
335
- 'Content-Type: application/json',
336
- '',
337
- '{"jsonrpc":"2.0","id":1,"method":"sendTransaction","params":["<base64-tx>"]}',
338
- '```',
339
- '',
340
- '### Browser (No CORS)',
341
- '```',
342
- 'POST https://mainnet.helius-rpc.com/?api-key=<KEY>',
343
- 'Content-Type: text/plain',
344
- '',
345
- '<base64-tx>',
346
- '```',
347
- '',
348
- '## Limitations',
349
- '- **No batch submit**: Cannot send multiple transactions in one request',
350
- '- **No durable nonce batching**: Each tx needs its own nonce account',
351
- '- **No rebates**: Tips are not refunded on backrun/bribe endpoints',
352
- '',
353
- '## Best Practices',
354
- '',
355
- '1. **Use fresh blockhash**: Get blockhash right before signing (valid ~60-90s)',
356
- '2. **Rebroadcast**: Resend every 200-500ms until confirmed or expired',
357
- '3. **Set skipPreflight: false** in dev to catch errors early',
358
- '4. **Monitor with Laserstream**: Use for accurate landing latency measurement',
359
- '5. **Use priority fees**: Especially during congestion',
360
- '',
361
- '## Measuring Landing Latency',
362
- 'Use **block index position**, not account update timing:',
363
- '- Subscribe to blocks via Laserstream/gRPC',
364
- '- Note slot and transaction index when your tx appears',
365
- '- Compare to when you sent',
366
- ];
367
- return { content: [{ type: 'text', text: lines.join('\n') }] };
368
154
  });
369
- // Tool 3: getWebhookGuide
370
- server.tool('getWebhookGuide', 'Get detailed information about Helius webhooks including delivery guarantees, latency expectations, configuration options, and troubleshooting common issues.', {
371
- topic: z
372
- .enum(['overview', 'delivery', 'configuration', 'troubleshooting', 'all'])
373
- .optional()
374
- .default('all')
375
- .describe('Specific topic to focus on'),
376
- }, async ({ topic }) => {
377
- const lines = [];
378
- const showOverview = topic === 'all' || topic === 'overview';
379
- const showDelivery = topic === 'all' || topic === 'delivery';
380
- const showConfig = topic === 'all' || topic === 'configuration';
381
- const showTroubleshooting = topic === 'all' || topic === 'troubleshooting';
382
- lines.push('# Helius Webhooks Guide', '');
383
- if (showOverview) {
384
- lines.push('## Overview', '');
385
- lines.push('Webhooks push blockchain events to your endpoint in real-time.', '');
386
- lines.push('### Webhook Types');
387
- lines.push('- **Enhanced**: Parsed, human-readable events (transfers, swaps, NFT sales)');
388
- lines.push('- **Raw**: Unparsed transaction data');
389
- lines.push('- **Discord**: Formatted for Discord channels');
390
- lines.push('');
391
- lines.push('### Transaction Types');
392
- lines.push('`TRANSFER`, `SWAP`, `NFT_SALE`, `NFT_MINT`, `NFT_LISTING`, `BURN`, `ANY`');
393
- lines.push('');
155
+ // Tool 2: getSenderInfo — fetches live sender docs
156
+ server.tool('getSenderInfo', 'Get information about Helius Sender for transaction submission. Fetches live from official documentation covering SWQoS routing, tips, latency, and best practices.', {}, async () => {
157
+ try {
158
+ const content = await fetchDoc('sender');
159
+ const howItWorks = extractSections(content, ['how it works', 'overview'], { includeLooseMatches: false });
160
+ const endpoints = extractSections(content, ['endpoints', 'api'], { includeLooseMatches: false });
161
+ const bestPractices = extractSections(content, ['best practices', 'tips'], { includeLooseMatches: false });
162
+ const sections = [howItWorks, endpoints, bestPractices].filter(Boolean).join('\n\n');
163
+ const body = sections || truncateDoc(content);
164
+ const result = [
165
+ '# Helius Sender (Official)',
166
+ '',
167
+ body,
168
+ '',
169
+ '---',
170
+ 'Source: https://www.helius.dev/docs (fetched live)',
171
+ ].join('\n');
172
+ return { content: [{ type: 'text', text: result }] };
394
173
  }
395
- if (showDelivery) {
396
- lines.push('## Delivery Guarantees', '');
397
- lines.push('### Latency');
398
- lines.push('- **Enhanced webhooks**: ~15-20 slots (~6-8 seconds) from on-chain confirmation');
399
- lines.push('- **Raw webhooks**: Slightly faster but unparsed');
400
- lines.push('');
401
- lines.push('### Commitment Level');
402
- lines.push('- Webhooks fire on **confirmed** commitment by default');
403
- lines.push('- Not processed (too early) or finalized (too slow)');
404
- lines.push('');
405
- lines.push('### Retry Policy');
406
- lines.push('- Helius retries failed deliveries with exponential backoff');
407
- lines.push('- Your endpoint should return 2xx within timeout');
408
- lines.push('- After retries exhausted, event may be dropped');
409
- lines.push('');
410
- lines.push('### Ordering');
411
- lines.push('- Events are generally in order but **not guaranteed**');
412
- lines.push('- Use transaction signature + slot for deduplication');
413
- lines.push('');
174
+ catch (error) {
175
+ const errorMsg = error instanceof Error ? error.message : String(error);
176
+ return {
177
+ content: [{ type: 'text', text: `Error fetching Sender info: ${errorMsg}` }],
178
+ isError: true,
179
+ };
414
180
  }
415
- if (showConfig) {
416
- lines.push('## Configuration', '');
417
- lines.push('### Account Addresses');
418
- lines.push('- Add addresses to monitor (up to limits per plan)');
419
- lines.push('- New addresses may take a few seconds to activate');
420
- lines.push('');
421
- lines.push('### Transaction Types');
422
- lines.push('- Use `ANY` to receive all transaction types');
423
- lines.push('- Or specify: `TRANSFER`, `SWAP`, `NFT_SALE`, etc.');
424
- lines.push('');
425
- lines.push('### Webhook URL');
426
- lines.push('- Must be HTTPS');
427
- lines.push('- Must respond within timeout (typically 30s)');
428
- lines.push('- Return 2xx for success');
429
- lines.push('');
181
+ });
182
+ // Tool 3: getWebhookGuide — fetches live webhooks docs
183
+ server.tool('getWebhookGuide', 'Get official Helius webhook documentation including delivery guarantees, latency, configuration, and troubleshooting. Fetches live from documentation.', {}, async () => {
184
+ try {
185
+ const content = await fetchDoc('webhooks');
186
+ const setup = extractSections(content, ['setup', 'configuration'], { includeLooseMatches: false });
187
+ const types = extractSections(content, ['transaction types', 'event types'], { includeLooseMatches: false });
188
+ const delivery = extractSections(content, ['delivery', 'troubleshooting'], { includeLooseMatches: false });
189
+ const sections = [setup, types, delivery].filter(Boolean).join('\n\n');
190
+ const body = sections || truncateDoc(content);
191
+ const result = [
192
+ '# Helius Webhooks (Official)',
193
+ '',
194
+ body,
195
+ '',
196
+ '---',
197
+ 'Source: https://www.helius.dev/docs (fetched live)',
198
+ ].join('\n');
199
+ return { content: [{ type: 'text', text: result }] };
430
200
  }
431
- if (showTroubleshooting) {
432
- lines.push('## Troubleshooting', '');
433
- lines.push('### Missing Events');
434
- lines.push('1. **Check transaction type filter**: Use `ANY` if unsure');
435
- lines.push('2. **Verify address is added**: Check webhook config');
436
- lines.push('3. **New ATA issue**: First transfer to new ATA may be missed');
437
- lines.push('4. **Endpoint timeout**: Ensure fast response (<30s)');
438
- lines.push('5. **Check webhook health**: Look for POST timeouts in your logs');
439
- lines.push('');
440
- lines.push('### Duplicate Events');
441
- lines.push('- Use transaction signature as idempotency key');
442
- lines.push('- Store processed signatures to dedupe');
443
- lines.push('');
444
- lines.push('### Delayed Events');
445
- lines.push('- Normal latency is ~15-20 slots');
446
- lines.push('- Check status.helius.dev for incidents');
447
- lines.push('- Consider Enhanced WebSockets or Laserstream for lower latency');
448
- lines.push('');
449
- lines.push('### ATA Creation Edge Case');
450
- lines.push('- When a token transfer creates a new ATA in the same tx:');
451
- lines.push(' - Raw webhooks: May only fire if dest ATA pre-exists');
452
- lines.push(' - Enhanced webhooks: Should handle but verify');
453
- lines.push('- Workaround: Also subscribe to the token mint');
454
- lines.push('');
201
+ catch (error) {
202
+ const errorMsg = error instanceof Error ? error.message : String(error);
203
+ return {
204
+ content: [{ type: 'text', text: `Error fetching webhook guide: ${errorMsg}` }],
205
+ isError: true,
206
+ };
455
207
  }
456
- return { content: [{ type: 'text', text: lines.join('\n') }] };
457
208
  });
458
- // Tool 4: troubleshootError
459
- server.tool('troubleshootError', 'Get detailed explanation and fixes for common Helius/Solana RPC error codes. Covers JSON-RPC errors, HTTP status codes, and WebSocket close codes.', {
209
+ // Tool 4: troubleshootError — kept hardcoded (no llms.txt equivalent)
210
+ server.tool('troubleshootError', 'BEST FOR: diagnosing specific error codes — use this first for any error. Get detailed explanation and fixes for Helius/Solana error codes. Covers JSON-RPC errors, HTTP status codes, and WebSocket close codes.', {
460
211
  errorCode: z
461
212
  .string()
462
213
  .describe('Error code to troubleshoot (e.g., "-32603", "429", "1006")'),
@@ -484,226 +235,86 @@ export function registerGuideTools(server) {
484
235
  lines.push('3. Check your plan limits in dashboard');
485
236
  lines.push('4. Try the request with curl to isolate client issues');
486
237
  lines.push('5. Contact support with request ID if persistent');
487
- }
488
- lines.push('', '## Common Error Codes Reference', '');
489
- lines.push('| Code | Meaning |');
490
- lines.push('|------|---------|');
491
- for (const [c, e] of Object.entries(ERROR_CODES)) {
492
- lines.push(`| ${c} | ${e.meaning} |`);
238
+ // Only show full reference table when code is unknown
239
+ lines.push('', '## Common Error Codes Reference', '');
240
+ lines.push('| Code | Meaning |');
241
+ lines.push('|------|---------|');
242
+ for (const [c, e] of Object.entries(ERROR_CODES)) {
243
+ lines.push(`| ${c} | ${e.meaning} |`);
244
+ }
493
245
  }
494
246
  return { content: [{ type: 'text', text: lines.join('\n') }] };
495
247
  });
496
- // Tool 5: getLatencyComparison
497
- server.tool('getLatencyComparison', 'Compare latency across Helius products: Standard WebSockets, Enhanced WebSockets, Laserstream (gRPC), and Shred Stream. Helps choose the right product for latency-sensitive applications.', {}, async () => {
498
- const lines = [
499
- '# Helius Latency Comparison',
500
- '',
501
- '## Product Latency Hierarchy (fastest to slowest)',
502
- '',
503
- '```',
504
- 'Shred Stream (~5-10ms ahead of Laserstream)',
505
- ' ↓',
506
- 'Laserstream gRPC (~50-100ms from block production)',
507
- '',
508
- 'Enhanced WebSockets (1.5-2x faster than Standard)',
509
- '',
510
- 'Standard WebSockets (~1-2 seconds)',
511
- ' ↓',
512
- 'Webhooks (~15-20 slots / 6-8 seconds)',
513
- '```',
514
- '',
515
- '## Detailed Comparison',
516
- '',
517
- '| Product | Typical Latency | Commitment | Plan Required |',
518
- '|---------|-----------------|------------|---------------|',
519
- '| Shred Stream | 5-10ms faster than LS | Pre-processed | Custom |',
520
- '| Laserstream | 50-100ms | Processed/Confirmed | Professional ($999) |',
521
- '| Enhanced WS | ~500ms-1s | Processed | Business ($499) |',
522
- '| Standard WS | 1-2s | Confirmed | Free |',
523
- '| Webhooks | 6-8s | Confirmed | Free |',
524
- '',
525
- '## Product Details',
526
- '',
527
- '### Shred Stream',
528
- '- **What**: Raw UDP shreds or pre-deshredded transactions',
529
- '- **Latency**: 5-10ms faster than Laserstream',
530
- '- **Cost**: ~$6K/IP/month',
531
- '- **Best for**: Ultra-low-latency trading, MEV',
532
- '',
533
- '### Laserstream (gRPC)',
534
- '- **What**: gRPC streaming with transaction/account/block subscriptions',
535
- '- **Latency**: ~50-100ms from block production',
536
- '- **Features**:',
537
- ' - Up to 50,000 address filters',
538
- ' - 24h historical replay',
539
- ' - Processed/Confirmed/Finalized commitment',
540
- '- **Plan access**:',
541
- ' - Developer: Devnet only',
542
- ' - Professional: Full mainnet + devnet',
543
- '',
544
- '### Enhanced WebSockets',
545
- '- **What**: Optimized WebSocket streams (transactionSubscribe, accountSubscribe)',
546
- '- **Latency**: 1.5-2x faster than standard',
547
- '- **Features**:',
548
- ' - Up to 50,000 address filters',
549
- ' - 10-minute inactivity timeout (ping every 30-60s)',
550
- ' - 100 connections (Business/Professional)',
551
- '- **Plan access**: Business ($499) and above',
552
- '',
553
- '### Standard WebSockets',
554
- '- **What**: Solana-native WebSocket subscriptions',
555
- '- **Latency**: 1-2 seconds',
556
- '- **Commitment**: Confirmed only (no processed on free)',
557
- '- **Connections**: 5 (Free), 150 (Developer), 250 (Business+)',
558
- '',
559
- '### Webhooks',
560
- '- **What**: HTTP POST to your endpoint on events',
561
- '- **Latency**: ~15-20 slots (6-8 seconds)',
562
- '- **Best for**: Non-latency-critical notifications',
563
- '',
564
- '## Choosing the Right Product',
565
- '',
566
- '| Use Case | Recommended | Why |',
567
- '|----------|-------------|-----|',
568
- '| Copy trading | Laserstream | Lowest latency for tx detection |',
569
- '| MEV/Arbitrage | Shred Stream | Pre-block transaction visibility |',
570
- '| Real-time UI | Enhanced WS | Good balance of speed and cost |',
571
- '| Notifications | Webhooks | Simple, no connection management |',
572
- '| Development | Standard WS | Free, good enough for testing |',
573
- '',
574
- '## Measuring Latency',
575
- '',
576
- '### Correct Method',
577
- '1. Subscribe to blocks via Laserstream/gRPC',
578
- '2. Note slot number and transaction index when your tx appears',
579
- '3. Compare to when you submitted',
580
- '',
581
- '### Incorrect Method',
582
- '- Using account update timing (varies by indexer, not true landing time)',
583
- '- Comparing different endpoints with different commitments',
584
- '',
585
- '## Regional Considerations',
586
- '',
587
- '- **Closest region = lowest latency**',
588
- '- Available regions: US (multiple), EU (FRA, AMS), Asia (SG, TYO)',
589
- '- Leader schedule affects latency (leaders rotate every ~400ms)',
590
- ];
591
- return { content: [{ type: 'text', text: lines.join('\n') }] };
248
+ // Tool 5: getLatencyComparison — fetches live docs for all streaming products
249
+ server.tool('getLatencyComparison', 'Compare latency across Helius streaming products: Standard WebSockets, Enhanced WebSockets, Laserstream (gRPC), and Shred Stream. Fetches live from official documentation.', {}, async () => {
250
+ try {
251
+ const docs = await fetchDocs(['laserstream', 'enhanced-websockets', 'shred-delivery']);
252
+ const sections = [
253
+ '# Helius Streaming Products: Latency Comparison (Official)',
254
+ '',
255
+ '> The following is fetched live from official Helius documentation.',
256
+ '',
257
+ ];
258
+ const labels = {
259
+ laserstream: 'LaserStream (gRPC)',
260
+ 'enhanced-websockets': 'Enhanced WebSockets',
261
+ 'shred-delivery': 'Shred Delivery',
262
+ };
263
+ for (const [key, content] of docs.entries()) {
264
+ const latency = extractSections(content, ['latency', 'performance'], { includeLooseMatches: false });
265
+ const speed = extractSections(content, ['speed', 'comparison'], { includeLooseMatches: false });
266
+ const combined = [latency, speed].filter(Boolean).join('\n\n');
267
+ sections.push(`## ${labels[key] ?? key}`, '', combined || truncateDoc(content), '', '---', '');
268
+ }
269
+ sections.push('Source: https://www.helius.dev/docs (fetched live)');
270
+ return { content: [{ type: 'text', text: sections.join('\n') }] };
271
+ }
272
+ catch (error) {
273
+ const errorMsg = error instanceof Error ? error.message : String(error);
274
+ return {
275
+ content: [{ type: 'text', text: `Error fetching latency comparison: ${errorMsg}` }],
276
+ isError: true,
277
+ };
278
+ }
592
279
  });
593
- // Tool 6: getPumpFunGuide
280
+ // Tool 6: getPumpFunGuide — kept hardcoded (no llms.txt equivalent)
594
281
  server.tool('getPumpFunGuide', 'Guide for working with pump.fun tokens on Helius. Covers why getAssetsByCreator does not work, how to track migrations/graduates, and best practices for pump.fun token queries.', {}, async () => {
595
282
  const lines = [
596
283
  '# Pump.fun Tokens Guide',
597
284
  '',
598
285
  '## Why getAssetsByCreator Doesn\'t Work',
599
286
  '',
600
- 'When you call `getAssetsByCreator` with a pump.fun deployer wallet, it returns empty.',
601
- '',
602
- '**Reason**: DAS API\'s "creator" field refers to **Metaplex creators** metadata, not the wallet that deployed the token.',
603
- '',
604
- '- Pump.fun tokens don\'t use Metaplex creators array',
605
- '- The deployer wallet is not stored in the same way',
606
- '- DAS cannot index pump.fun deployers as "creators"',
287
+ 'DAS API\'s "creator" field refers to **Metaplex creators** metadata, not the deployer wallet. Pump.fun tokens don\'t use the Metaplex creators array, so `getAssetsByCreator` returns empty.',
607
288
  '',
608
289
  '## How to Find Pump.fun Tokens',
609
290
  '',
610
- '### Option 1: Listen to Migration Events',
611
- '```',
612
- '// Subscribe to pump.fun migration program',
613
- 'Program ID: 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P',
614
- '',
615
- '// Filter for "migrate" instruction',
616
- '// This fires when a token graduates from bonding curve',
617
- '```',
618
- '',
619
- '### Option 2: Query by Mint/Update Authority',
620
- '',
621
- 'Instead of creator, try:',
622
- '- `getAsset` with the specific mint address',
623
- '- Filter by update authority or freeze authority',
624
- '- Search by token metadata name/symbol patterns',
625
- '',
626
- '### Option 3: Historical Backfill',
627
- '',
628
- 'For historical graduated tokens:',
629
- '```',
630
- '1. Query migration program transaction history',
631
- '2. Parse the "migrate" instruction logs',
632
- '3. Extract token mint addresses',
633
- '4. Use getAsset to get full token details',
634
- '```',
291
+ '1. **By mint address** `getAsset` with the specific mint address (most direct)',
292
+ '2. **By authority** — `searchAssets` filtering by update/freeze authority',
293
+ '3. **Listen to migrations** — Subscribe to the migration program to catch graduates:',
294
+ ' - Migration Program: `6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P`',
295
+ ' - Use `transactionSubscribe` or `laserstreamSubscribe` with `accountInclude` set to this program',
296
+ '4. **Historical backfill** — Query migration program transaction history, parse "migrate" instructions, extract mint addresses',
635
297
  '',
636
298
  '## Tracking Migrations (Graduates)',
637
299
  '',
638
- '### What is a Migration/Graduate?',
639
300
  'When a pump.fun token completes its bonding curve, it "graduates" and migrates to Raydium.',
640
301
  '',
641
- '### Migration Program',
642
- '```',
643
- 'Program: 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P',
644
- 'Instruction: migrate',
645
- '```',
646
- '',
647
- '### Real-time Migration Tracking',
302
+ '**Real-time tracking:**',
648
303
  '```typescript',
649
- '// Using Laserstream/gRPC',
650
- 'subscribe({',
651
- ' transactions: {',
652
- ' accountInclude: ["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"],',
653
- ' }',
654
- '});',
655
- '',
656
- '// Or Enhanced WebSockets',
304
+ '// Laserstream or Enhanced WebSockets',
657
305
  'transactionSubscribe({',
658
306
  ' accountInclude: ["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"],',
659
307
  '});',
660
308
  '```',
661
309
  '',
662
- '### Historical Migrations',
310
+ '**Historical migrations:**',
663
311
  '```typescript',
664
- '// Get past migrations',
665
312
  'const signatures = await connection.getSignaturesForAddress(',
666
313
  ' new PublicKey("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"),',
667
314
  ' { limit: 1000 }',
668
315
  ');',
669
- '',
670
- '// Parse each transaction for migrate instruction',
671
- 'for (const sig of signatures) {',
672
- ' const tx = await parseTransactions([sig.signature]);',
673
- ' // Extract token mint from parsed data',
674
- '}',
675
- '```',
676
- '',
677
- '## Common Pump.fun Queries',
678
- '',
679
- '### Get Token Details',
680
- '```typescript',
681
- '// If you have the mint address',
682
- 'const asset = await helius.getAsset({ id: mintAddress });',
683
- '```',
684
- '',
685
- '### Check if Token is Graduated',
686
- '```typescript',
687
- '// Graduated tokens will have Raydium LP',
688
- '// Check for AMM/CPMM pool with the token',
689
- '```',
690
- '',
691
- '### Get Token Holders',
692
- '```typescript',
693
- 'const holders = await helius.getTokenAccounts({',
694
- ' mint: mintAddress,',
695
- ' limit: 100,',
696
- '});',
316
+ '// Parse each transaction with parseTransactions to extract token mints',
697
317
  '```',
698
- '',
699
- '## Feature Request Status',
700
- '',
701
- 'Helius is aware of demand for:',
702
- '- Native pump.fun migration filter in Events API',
703
- '- Historical graduates backfill endpoint',
704
- '- Creator-by-deployer-wallet queries',
705
- '',
706
- 'Check docs.helius.dev for updates.',
707
318
  ];
708
319
  return { content: [{ type: 'text', text: lines.join('\n') }] };
709
320
  });