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
|
@@ -1,19 +1,54 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { getEnhancedWebSocketUrl } from '../utils/helius.js';
|
|
3
|
+
import { mcpText, mcpError, validateEnum, handleToolError, warnInvalidAddresses, warnInvalidAddress, warnAddressConflicts } from '../utils/errors.js';
|
|
4
|
+
import { fetchDoc, extractSections, truncateDoc } from '../utils/docs.js';
|
|
3
5
|
export function registerEnhancedWebSocketTools(server) {
|
|
4
|
-
server.tool('transactionSubscribe', 'Get Enhanced WebSocket config for real-time Solana transaction streaming. Filter by accounts, vote/failed txns, or signatures. Up to 50,000 addresses per filter. Business+ plans only. Returns connection config and code example.', {
|
|
6
|
+
server.tool('transactionSubscribe', 'BEST FOR: real-time transaction streaming for live UI updates (WebSocket). PREFER createWebhook for fire-and-forget server-to-server notifications. PREFER laserstreamSubscribe for lowest-latency production streaming. Get Enhanced WebSocket config for real-time Solana transaction streaming. Filter by accounts, vote/failed txns, or signatures. Up to 50,000 addresses per filter. Business+ plans only. Returns connection config and code example. Data streaming cost: 3 credits per 0.1 MB received.', {
|
|
5
7
|
vote: z.boolean().optional().describe('Include vote transactions'),
|
|
6
8
|
failed: z.boolean().optional().describe('Include failed transactions'),
|
|
7
|
-
signature: z.string().optional().describe('
|
|
8
|
-
accountInclude: z.array(z.string()).optional().describe('Accounts to include (OR logic)'),
|
|
9
|
-
accountExclude: z.array(z.string()).optional().describe('Accounts to exclude'),
|
|
10
|
-
accountRequired: z.array(z.string()).optional().describe('Accounts required (AND logic)'),
|
|
11
|
-
commitment: z.
|
|
12
|
-
encoding: z.
|
|
13
|
-
transactionDetails: z.
|
|
9
|
+
signature: z.string().optional().describe('Transaction signature (base58 encoded, 86-88 characters) to filter to'),
|
|
10
|
+
accountInclude: z.array(z.string()).optional().describe('Accounts to include (base58 encoded, up to 50,000, OR logic)'),
|
|
11
|
+
accountExclude: z.array(z.string()).optional().describe('Accounts to exclude (base58 encoded)'),
|
|
12
|
+
accountRequired: z.array(z.string()).optional().describe('Accounts required (base58 encoded, AND logic)'),
|
|
13
|
+
commitment: z.string().optional().default('confirmed'),
|
|
14
|
+
encoding: z.string().optional().default('jsonParsed'),
|
|
15
|
+
transactionDetails: z.string().optional().default('full'),
|
|
14
16
|
showRewards: z.boolean().optional().default(false),
|
|
15
17
|
maxSupportedTransactionVersion: z.number().optional().default(0)
|
|
16
18
|
}, async (params) => {
|
|
19
|
+
let err;
|
|
20
|
+
err = validateEnum(params.commitment, ['processed', 'confirmed', 'finalized'], 'Transaction Subscribe Error', 'commitment');
|
|
21
|
+
if (err)
|
|
22
|
+
return err;
|
|
23
|
+
err = validateEnum(params.encoding, ['base58', 'base64', 'jsonParsed'], 'Transaction Subscribe Error', 'encoding');
|
|
24
|
+
if (err)
|
|
25
|
+
return err;
|
|
26
|
+
err = validateEnum(params.transactionDetails, ['full', 'signatures', 'accounts', 'none'], 'Transaction Subscribe Error', 'transactionDetails');
|
|
27
|
+
if (err)
|
|
28
|
+
return err;
|
|
29
|
+
// Collect warnings for config issues that would fail at runtime
|
|
30
|
+
const warnings = [];
|
|
31
|
+
const addressArrays = [
|
|
32
|
+
['accountInclude', params.accountInclude],
|
|
33
|
+
['accountExclude', params.accountExclude],
|
|
34
|
+
['accountRequired', params.accountRequired],
|
|
35
|
+
];
|
|
36
|
+
for (const [name, arr] of addressArrays) {
|
|
37
|
+
if (arr) {
|
|
38
|
+
if (arr.length === 0) {
|
|
39
|
+
warnings.push(`${name} is an empty array. This filter will have no effect.`);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
warnings.push(...warnInvalidAddresses(name, arr));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const conflict = warnAddressConflicts('accountInclude', params.accountInclude, 'accountExclude', params.accountExclude);
|
|
47
|
+
if (conflict)
|
|
48
|
+
warnings.push(conflict);
|
|
49
|
+
if (!params.accountInclude && !params.accountExclude && !params.accountRequired && !params.signature) {
|
|
50
|
+
warnings.push('No account filters or signature specified. This will stream ALL transactions on the network, which produces very high volume. Consider adding filters to reduce traffic.');
|
|
51
|
+
}
|
|
17
52
|
try {
|
|
18
53
|
const wsUrl = getEnhancedWebSocketUrl();
|
|
19
54
|
const filter = {};
|
|
@@ -46,38 +81,36 @@ export function registerEnhancedWebSocketTools(server) {
|
|
|
46
81
|
'',
|
|
47
82
|
`**URL:** \`${wsUrl}\``,
|
|
48
83
|
'',
|
|
49
|
-
'**Subscription Request:**',
|
|
50
|
-
'```json',
|
|
51
|
-
JSON.stringify(subscriptionRequest, null, 2),
|
|
52
|
-
'```',
|
|
53
|
-
'',
|
|
54
|
-
'**Example Code:**',
|
|
55
|
-
'```typescript',
|
|
56
|
-
`const ws = new WebSocket('${wsUrl}');`,
|
|
57
|
-
'ws.on("open", () => {',
|
|
58
|
-
' ws.send(JSON.stringify(' + JSON.stringify(subscriptionRequest) + '));',
|
|
59
|
-
' setInterval(() => ws.ping(), 30000);',
|
|
60
|
-
'});',
|
|
61
|
-
'ws.on("message", (data) => {',
|
|
62
|
-
' const msg = JSON.parse(data.toString());',
|
|
63
|
-
' if (msg.method === "transactionNotification") {',
|
|
64
|
-
' console.log("Transaction:", msg.params);',
|
|
65
|
-
' }',
|
|
66
|
-
'});',
|
|
67
|
-
'```',
|
|
68
84
|
];
|
|
69
|
-
|
|
85
|
+
if (warnings.length > 0) {
|
|
86
|
+
lines.push('**Warnings:**');
|
|
87
|
+
warnings.forEach(w => lines.push(`- ${w}`));
|
|
88
|
+
lines.push('');
|
|
89
|
+
}
|
|
90
|
+
lines.push('**Subscription Request:**', '```json', JSON.stringify(subscriptionRequest, null, 2), '```', '', '**Example Code:**', '```typescript', `const ws = new WebSocket('${wsUrl}');`, 'ws.on("open", () => {', ' ws.send(JSON.stringify(' + JSON.stringify(subscriptionRequest) + '));', ' setInterval(() => ws.ping(), 30000);', '});', 'ws.on("message", (data) => {', ' const msg = JSON.parse(data.toString());', ' if (msg.method === "transactionNotification") {', ' console.log("Transaction:", msg.params);', ' }', '});', '```');
|
|
91
|
+
return mcpText(lines.join('\n'));
|
|
70
92
|
}
|
|
71
93
|
catch (err) {
|
|
72
|
-
|
|
73
|
-
return { content: [{ type: 'text', text: `Error: ${errorMsg}` }], isError: true };
|
|
94
|
+
return handleToolError(err, 'Error');
|
|
74
95
|
}
|
|
75
96
|
});
|
|
76
|
-
server.tool('accountSubscribe', 'Get Enhanced WebSocket config for real-time Solana account monitoring. Track balance changes and data updates. Business+ plans only. Returns connection config and code example.', {
|
|
77
|
-
account: z.string().describe('Account
|
|
78
|
-
encoding: z.
|
|
79
|
-
commitment: z.
|
|
97
|
+
server.tool('accountSubscribe', 'BEST FOR: real-time account change monitoring for live UI updates (WebSocket). PREFER createWebhook for fire-and-forget notifications on account changes. PREFER laserstreamSubscribe for lowest-latency production streaming. Get Enhanced WebSocket config for real-time Solana account monitoring. Track balance changes and data updates. Business+ plans only. Returns connection config and code example. Data streaming cost: 3 credits per 0.1 MB received.', {
|
|
98
|
+
account: z.string().describe('Account address (base58 encoded)'),
|
|
99
|
+
encoding: z.string().optional().default('base58'),
|
|
100
|
+
commitment: z.string().optional().default('finalized')
|
|
80
101
|
}, async ({ account, encoding, commitment }) => {
|
|
102
|
+
let err;
|
|
103
|
+
err = validateEnum(encoding, ['base58', 'base64', 'base64+zstd', 'jsonParsed'], 'Account Subscribe Error', 'encoding');
|
|
104
|
+
if (err)
|
|
105
|
+
return err;
|
|
106
|
+
err = validateEnum(commitment, ['finalized', 'confirmed', 'processed'], 'Account Subscribe Error', 'commitment');
|
|
107
|
+
if (err)
|
|
108
|
+
return err;
|
|
109
|
+
// Collect warnings for config issues that would fail at runtime
|
|
110
|
+
const warnings = [];
|
|
111
|
+
const addrWarning = warnInvalidAddress('account', account);
|
|
112
|
+
if (addrWarning)
|
|
113
|
+
warnings.push(addrWarning);
|
|
81
114
|
try {
|
|
82
115
|
const wsUrl = getEnhancedWebSocketUrl();
|
|
83
116
|
const subscriptionRequest = {
|
|
@@ -91,54 +124,51 @@ export function registerEnhancedWebSocketTools(server) {
|
|
|
91
124
|
`**Account:** \`${account}\``,
|
|
92
125
|
`**URL:** \`${wsUrl}\``,
|
|
93
126
|
'',
|
|
94
|
-
'**Subscription Request:**',
|
|
95
|
-
'```json',
|
|
96
|
-
JSON.stringify(subscriptionRequest, null, 2),
|
|
97
|
-
'```',
|
|
98
|
-
'',
|
|
99
|
-
'**Example Code:**',
|
|
100
|
-
'```typescript',
|
|
101
|
-
`const ws = new WebSocket('${wsUrl}');`,
|
|
102
|
-
'ws.on("open", () => {',
|
|
103
|
-
' ws.send(JSON.stringify(' + JSON.stringify(subscriptionRequest) + '));',
|
|
104
|
-
' setInterval(() => ws.ping(), 30000);',
|
|
105
|
-
'});',
|
|
106
|
-
'ws.on("message", (data) => {',
|
|
107
|
-
' const msg = JSON.parse(data.toString());',
|
|
108
|
-
' if (msg.method === "accountNotification") {',
|
|
109
|
-
' console.log("Account updated:", msg.params.result.value);',
|
|
110
|
-
' }',
|
|
111
|
-
'});',
|
|
112
|
-
'```',
|
|
113
127
|
];
|
|
114
|
-
|
|
128
|
+
if (warnings.length > 0) {
|
|
129
|
+
lines.push('**Warnings:**');
|
|
130
|
+
warnings.forEach(w => lines.push(`- ${w}`));
|
|
131
|
+
lines.push('');
|
|
132
|
+
}
|
|
133
|
+
lines.push('**Subscription Request:**', '```json', JSON.stringify(subscriptionRequest, null, 2), '```', '', '**Example Code:**', '```typescript', `const ws = new WebSocket('${wsUrl}');`, 'ws.on("open", () => {', ' ws.send(JSON.stringify(' + JSON.stringify(subscriptionRequest) + '));', ' setInterval(() => ws.ping(), 30000);', '});', 'ws.on("message", (data) => {', ' const msg = JSON.parse(data.toString());', ' if (msg.method === "accountNotification") {', ' console.log("Account updated:", msg.params.result.value);', ' }', '});', '```');
|
|
134
|
+
return mcpText(lines.join('\n'));
|
|
115
135
|
}
|
|
116
136
|
catch (err) {
|
|
117
|
-
|
|
118
|
-
return { content: [{ type: 'text', text: `Error: ${errorMsg}` }], isError: true };
|
|
137
|
+
return handleToolError(err, 'Error');
|
|
119
138
|
}
|
|
120
139
|
});
|
|
121
|
-
server.tool('getEnhancedWebSocketInfo', 'Get Helius Enhanced WebSocket capabilities, endpoints, and plan requirements. 1.5-2x faster than standard WebSockets.', {}, async () => {
|
|
140
|
+
server.tool('getEnhancedWebSocketInfo', 'Get Helius Enhanced WebSocket capabilities, endpoints, and plan requirements. 1.5-2x faster than standard WebSockets. Fetches live from official documentation.', {}, async () => {
|
|
141
|
+
let wsUrl;
|
|
122
142
|
try {
|
|
123
|
-
|
|
124
|
-
const lines = [
|
|
125
|
-
'**Helius Enhanced WebSocket Service**',
|
|
126
|
-
'',
|
|
127
|
-
`**Endpoint:** \`${wsUrl}\``,
|
|
128
|
-
'',
|
|
129
|
-
'**Subscriptions:** transactionSubscribe, accountSubscribe',
|
|
130
|
-
'**Speed:** 1.5-2x faster than standard WebSockets',
|
|
131
|
-
'**Filtering:** Up to 50,000 addresses per filter',
|
|
132
|
-
'**Plans:** Business or Professional tier',
|
|
133
|
-
'**Timeout:** 10 min inactivity, ping every 30-60s',
|
|
134
|
-
'',
|
|
135
|
-
'**Docs:** https://www.helius.dev/docs/enhanced-websockets',
|
|
136
|
-
];
|
|
137
|
-
return { content: [{ type: 'text', text: lines.join('\n') }] };
|
|
143
|
+
wsUrl = getEnhancedWebSocketUrl();
|
|
138
144
|
}
|
|
139
145
|
catch (err) {
|
|
140
|
-
|
|
141
|
-
|
|
146
|
+
return handleToolError(err, 'Enhanced WebSocket Error');
|
|
147
|
+
}
|
|
148
|
+
let content;
|
|
149
|
+
try {
|
|
150
|
+
content = await fetchDoc('enhanced-websockets');
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return mcpError('Could not fetch live Enhanced WebSocket documentation. Try:\n' +
|
|
154
|
+
'- `lookupHeliusDocs({ topic: \'enhanced-websockets\' })` for full documentation\n' +
|
|
155
|
+
'- Visit https://www.helius.dev/docs/enhanced-websockets directly');
|
|
142
156
|
}
|
|
157
|
+
const capabilities = extractSections(content, ['capabilities', 'features'], { includeLooseMatches: false });
|
|
158
|
+
const subscriptions = extractSections(content, ['subscriptions', 'endpoints'], { includeLooseMatches: false });
|
|
159
|
+
const plans = extractSections(content, ['plan requirements', 'plans'], { includeLooseMatches: false });
|
|
160
|
+
const sections = [capabilities, subscriptions, plans].filter(Boolean).join('\n\n');
|
|
161
|
+
const body = sections || truncateDoc(content);
|
|
162
|
+
const result = [
|
|
163
|
+
'# Helius Enhanced WebSockets (Official)',
|
|
164
|
+
'',
|
|
165
|
+
`**Endpoint:** \`${wsUrl}\``,
|
|
166
|
+
'',
|
|
167
|
+
body,
|
|
168
|
+
'',
|
|
169
|
+
'---',
|
|
170
|
+
'Source: https://www.helius.dev/docs/enhanced-websockets (fetched live)',
|
|
171
|
+
].join('\n');
|
|
172
|
+
return mcpText(result);
|
|
143
173
|
});
|
|
144
174
|
}
|
package/dist/tools/fees.js
CHANGED
|
@@ -1,74 +1,55 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
2
|
+
import { getHeliusClient, hasApiKey } from '../utils/helius.js';
|
|
3
3
|
import { noApiKeyResponse } from './shared.js';
|
|
4
|
+
import { mcpText, validateEnum, handleToolError } from '../utils/errors.js';
|
|
4
5
|
export function registerFeeTools(server) {
|
|
5
6
|
// Get Priority Fee Estimate
|
|
6
|
-
server.tool('getPriorityFeeEstimate', 'Get optimal priority fee estimates for Solana transactions. Returns recommended fees in microlamports for different priority levels (Min, Low, Medium, High, VeryHigh, UnsafeMax). Essential for ensuring transaction confirmation during network congestion.', {
|
|
7
|
-
accountKeys: z.array(z.string()).optional().describe('Account addresses involved in transaction for more accurate estimates'),
|
|
8
|
-
priorityLevel: z.
|
|
7
|
+
server.tool('getPriorityFeeEstimate', 'BEST FOR: determining optimal priority fees before sending a transaction. Get optimal priority fee estimates for Solana transactions. Returns recommended fees in microlamports for different priority levels (Min, Low, Medium, High, VeryHigh, UnsafeMax). Essential for ensuring transaction confirmation during network congestion. Credit cost: 1 credit (Priority Fee API).', {
|
|
8
|
+
accountKeys: z.array(z.string()).optional().describe('Account addresses (base58 encoded) involved in transaction for more accurate estimates'),
|
|
9
|
+
priorityLevel: z.string().optional().describe('Desired priority level'),
|
|
9
10
|
includeAllLevels: z.boolean().optional().default(true).describe('Return fees for all priority levels')
|
|
10
11
|
}, async ({ accountKeys, priorityLevel, includeAllLevels }) => {
|
|
11
12
|
if (!hasApiKey())
|
|
12
13
|
return noApiKeyResponse();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
method: 'getPriorityFeeEstimate',
|
|
18
|
-
params: [{
|
|
19
|
-
...(accountKeys && { accountKeys }),
|
|
20
|
-
options: {
|
|
21
|
-
...(priorityLevel && { priorityLevel }),
|
|
22
|
-
includeAllPriorityFeeLevels: includeAllLevels
|
|
23
|
-
}
|
|
24
|
-
}]
|
|
25
|
-
};
|
|
26
|
-
const response = await fetch(url, {
|
|
27
|
-
method: 'POST',
|
|
28
|
-
headers: { 'Content-Type': 'application/json' },
|
|
29
|
-
body: JSON.stringify(requestBody)
|
|
30
|
-
});
|
|
31
|
-
const data = await response.json();
|
|
32
|
-
if (data.error) {
|
|
33
|
-
return {
|
|
34
|
-
content: [{
|
|
35
|
-
type: 'text',
|
|
36
|
-
text: `**Priority Fee Estimate Error**\n\n${data.error.message}`
|
|
37
|
-
}]
|
|
38
|
-
};
|
|
14
|
+
if (priorityLevel) {
|
|
15
|
+
const err = validateEnum(priorityLevel, ['Min', 'Low', 'Medium', 'High', 'VeryHigh', 'UnsafeMax'], 'Priority Fee Estimate', 'priority level');
|
|
16
|
+
if (err)
|
|
17
|
+
return err;
|
|
39
18
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
19
|
+
try {
|
|
20
|
+
const helius = getHeliusClient();
|
|
21
|
+
const result = await helius.getPriorityFeeEstimate({
|
|
22
|
+
...(accountKeys && { accountKeys }),
|
|
23
|
+
options: {
|
|
24
|
+
...(priorityLevel && { priorityLevel: priorityLevel }),
|
|
25
|
+
includeAllPriorityFeeLevels: includeAllLevels
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
if (!result) {
|
|
29
|
+
return mcpText(`**Priority Fee Estimate**\n\nNo fee data available.`);
|
|
30
|
+
}
|
|
31
|
+
const lines = ['**Priority Fee Estimate**', ''];
|
|
32
|
+
if (result.priorityFeeLevels) {
|
|
33
|
+
const levels = result.priorityFeeLevels;
|
|
34
|
+
lines.push('| Level | Fee (microlamports) |');
|
|
35
|
+
lines.push('|-------|-------------------|');
|
|
36
|
+
lines.push(`| Min | ${levels.min.toLocaleString()} |`);
|
|
37
|
+
lines.push(`| Low | ${levels.low.toLocaleString()} |`);
|
|
38
|
+
lines.push(`| Medium | ${levels.medium.toLocaleString()} |`);
|
|
39
|
+
lines.push(`| High | ${levels.high.toLocaleString()} |`);
|
|
40
|
+
lines.push(`| Very High | ${levels.veryHigh.toLocaleString()} |`);
|
|
41
|
+
lines.push(`| Unsafe Max | ${levels.unsafeMax.toLocaleString()} |`);
|
|
42
|
+
}
|
|
43
|
+
else if (result.priorityFeeEstimate !== undefined) {
|
|
44
|
+
lines.push(`**Estimated Fee:** ${result.priorityFeeEstimate.toLocaleString()} microlamports`);
|
|
45
|
+
}
|
|
46
|
+
if (accountKeys && accountKeys.length > 0) {
|
|
47
|
+
lines.push('', `*Estimate based on ${accountKeys.length} account(s)*`);
|
|
48
|
+
}
|
|
49
|
+
return mcpText(lines.join('\n'));
|
|
48
50
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const levels = result.priorityFeeLevels;
|
|
52
|
-
lines.push('| Level | Fee (microlamports) |');
|
|
53
|
-
lines.push('|-------|-------------------|');
|
|
54
|
-
lines.push(`| Min | ${levels.min.toLocaleString()} |`);
|
|
55
|
-
lines.push(`| Low | ${levels.low.toLocaleString()} |`);
|
|
56
|
-
lines.push(`| Medium | ${levels.medium.toLocaleString()} |`);
|
|
57
|
-
lines.push(`| High | ${levels.high.toLocaleString()} |`);
|
|
58
|
-
lines.push(`| Very High | ${levels.veryHigh.toLocaleString()} |`);
|
|
59
|
-
lines.push(`| Unsafe Max | ${levels.unsafeMax.toLocaleString()} |`);
|
|
51
|
+
catch (err) {
|
|
52
|
+
return handleToolError(err, 'Error fetching priority fee estimate');
|
|
60
53
|
}
|
|
61
|
-
else if (result.priorityFeeEstimate !== undefined) {
|
|
62
|
-
lines.push(`**Estimated Fee:** ${result.priorityFeeEstimate.toLocaleString()} microlamports`);
|
|
63
|
-
}
|
|
64
|
-
if (accountKeys && accountKeys.length > 0) {
|
|
65
|
-
lines.push('', `*Estimate based on ${accountKeys.length} account(s)*`);
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
content: [{
|
|
69
|
-
type: 'text',
|
|
70
|
-
text: lines.join('\n')
|
|
71
|
-
}]
|
|
72
|
-
};
|
|
73
54
|
});
|
|
74
55
|
}
|