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.
- package/CHANGELOG.md +52 -0
- package/LICENSE +1 -1
- package/README.md +97 -21
- package/dist/http.d.ts +1 -0
- package/dist/http.js +2 -0
- package/dist/index.js +93 -2
- package/dist/scripts/validate-catalog.d.ts +13 -0
- package/dist/scripts/validate-catalog.js +76 -0
- package/dist/tools/accounts.js +114 -204
- package/dist/tools/assets.js +109 -123
- package/dist/tools/auth.d.ts +2 -0
- package/dist/tools/auth.js +459 -0
- package/dist/tools/balance.js +28 -32
- package/dist/tools/blocks.js +68 -87
- package/dist/tools/config.js +18 -79
- package/dist/tools/das-extras.js +56 -41
- package/dist/tools/docs.js +12 -54
- package/dist/tools/enhanced-websockets.js +104 -74
- package/dist/tools/fees.js +42 -61
- package/dist/tools/guides.js +126 -515
- package/dist/tools/index.js +50 -2
- package/dist/tools/laserstream.js +107 -53
- package/dist/tools/network.js +47 -69
- package/dist/tools/plans.d.ts +21 -0
- package/dist/tools/plans.js +105 -246
- package/dist/tools/product-catalog.d.ts +10 -0
- package/dist/tools/product-catalog.js +123 -0
- package/dist/tools/recommend.d.ts +4 -0
- package/dist/tools/recommend.js +233 -0
- package/dist/tools/shared.js +8 -3
- package/dist/tools/solana-knowledge.d.ts +2 -0
- package/dist/tools/solana-knowledge.js +544 -0
- package/dist/tools/tokens.js +17 -18
- package/dist/tools/transactions.js +232 -302
- package/dist/tools/transfers.d.ts +2 -0
- package/dist/tools/transfers.js +270 -0
- package/dist/tools/wallet.js +175 -177
- package/dist/tools/webhooks.js +80 -82
- package/dist/types/transaction-types.d.ts +1 -1
- package/dist/types/transaction-types.js +2 -1
- package/dist/utils/config.d.ts +27 -0
- package/dist/utils/config.js +76 -0
- package/dist/utils/docs.d.ts +24 -0
- package/dist/utils/docs.js +72 -0
- package/dist/utils/errors.d.ts +32 -0
- package/dist/utils/errors.js +157 -0
- package/dist/utils/feedback.d.ts +16 -0
- package/dist/utils/feedback.js +87 -0
- package/dist/utils/formatters.d.ts +0 -1
- package/dist/utils/formatters.js +0 -3
- package/dist/utils/helius.d.ts +15 -5
- package/dist/utils/helius.js +52 -45
- package/dist/version.d.ts +1 -0
- package/dist/version.js +1 -0
- package/package.json +17 -7
- package/system-prompts/helius/claude.system.md +170 -0
- package/system-prompts/helius/full.md +2868 -0
- package/system-prompts/helius/openai.developer.md +170 -0
- package/system-prompts/helius-dflow/claude.system.md +290 -0
- package/system-prompts/helius-dflow/full.md +3647 -0
- package/system-prompts/helius-dflow/openai.developer.md +290 -0
- package/system-prompts/helius-phantom/claude.system.md +348 -0
- package/system-prompts/helius-phantom/full.md +5472 -0
- package/system-prompts/helius-phantom/openai.developer.md +348 -0
- package/system-prompts/svm/claude.system.md +174 -0
- package/system-prompts/svm/full.md +699 -0
- package/system-prompts/svm/openai.developer.md +174 -0
package/dist/tools/guides.js
CHANGED
|
@@ -1,99 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
|
|
3
|
-
|
|
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', '
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
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
|
-
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
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
|
|
370
|
-
server.tool('
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
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
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
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
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
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
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
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
|
|
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
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
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.
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
'
|
|
518
|
-
'
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
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
|
-
'
|
|
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
|
-
'
|
|
611
|
-
'
|
|
612
|
-
'
|
|
613
|
-
'Program
|
|
614
|
-
'',
|
|
615
|
-
'
|
|
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
|
-
'
|
|
642
|
-
'```',
|
|
643
|
-
'Program: 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P',
|
|
644
|
-
'Instruction: migrate',
|
|
645
|
-
'```',
|
|
646
|
-
'',
|
|
647
|
-
'### Real-time Migration Tracking',
|
|
302
|
+
'**Real-time tracking:**',
|
|
648
303
|
'```typescript',
|
|
649
|
-
'//
|
|
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
|
-
'
|
|
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
|
});
|