cryptoiz-mcp 4.16.8 → 4.16.10
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/index.js +132 -22
- package/package.json +15 -5
- package/setup.js +0 -0
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
var VERSION = 'v4.16.
|
|
2
|
+
var VERSION = 'v4.16.10';
|
|
3
3
|
var GATEWAY = 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-x402-gateway';
|
|
4
4
|
var TOOL_ENDPOINTS = {
|
|
5
5
|
get_whale_alpha: 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-alpha-scanner',
|
|
@@ -18,6 +18,7 @@ var SOL_RPC = 'https://api.mainnet-beta.solana.com';
|
|
|
18
18
|
var TOKEN_PROGRAM = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA';
|
|
19
19
|
var ATA_PROGRAM = 'ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL';
|
|
20
20
|
var MEMO_PROGRAM = 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr';
|
|
21
|
+
var COMPUTE_BUDGET_PROGRAM = 'ComputeBudget111111111111111111111111111111';
|
|
21
22
|
|
|
22
23
|
var _updateNotified = false;
|
|
23
24
|
function notifyUpdate(data, headers) {
|
|
@@ -29,11 +30,16 @@ function notifyUpdate(data, headers) {
|
|
|
29
30
|
console.error('[cryptoiz-mcp] UPDATE: ' + VERSION + ' -> ' + latest + ' | Run: ' + cmd);
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
var
|
|
33
|
-
var
|
|
34
|
-
var
|
|
35
|
-
var
|
|
36
|
-
var
|
|
33
|
+
var solana = require('@solana/web3.js');
|
|
34
|
+
var Connection = solana.Connection;
|
|
35
|
+
var PublicKey = solana.PublicKey;
|
|
36
|
+
var Transaction = solana.Transaction;
|
|
37
|
+
var TransactionMessage = solana.TransactionMessage;
|
|
38
|
+
var VersionedTransaction = solana.VersionedTransaction;
|
|
39
|
+
var Keypair = solana.Keypair;
|
|
40
|
+
// Fix bs58 v6 ESM-only issue: support both CJS (v5) and ESM-compiled (v6)
|
|
41
|
+
var _bs58mod = require('bs58');
|
|
42
|
+
var bs58 = _bs58mod.default || _bs58mod;
|
|
37
43
|
var Server = require('@modelcontextprotocol/sdk/server/index.js').Server;
|
|
38
44
|
var StdioServerTransport = require('@modelcontextprotocol/sdk/server/stdio.js').StdioServerTransport;
|
|
39
45
|
var CallToolRequestSchema = require('@modelcontextprotocol/sdk/types.js').CallToolRequestSchema;
|
|
@@ -53,27 +59,75 @@ function findATA(wallet, mint) {
|
|
|
53
59
|
return PublicKey.findProgramAddressSync([walletPk.toBuffer(), tokPk.toBuffer(), mintPk.toBuffer()], ataPk)[0];
|
|
54
60
|
}
|
|
55
61
|
|
|
56
|
-
//
|
|
62
|
+
// V2: Dexter gas-sponsored. 4-ix tx: Limit + Price + TransferChecked + Memo(nonce)
|
|
63
|
+
// Dexter pays SOL gas — user only needs USDC
|
|
64
|
+
async function buildV2PaymentPayload(amount, feePayerAddr) {
|
|
65
|
+
var kp = getKeypair();
|
|
66
|
+
var conn = new Connection(SOL_RPC, 'confirmed');
|
|
67
|
+
var userATA = findATA(kp.publicKey.toBase58(), USDC_MINT);
|
|
68
|
+
var recipientATA = findATA(RECIPIENT, USDC_MINT);
|
|
69
|
+
var feePayerPk = new PublicKey(feePayerAddr);
|
|
70
|
+
var computeBudgetPk = new PublicKey(COMPUTE_BUDGET_PROGRAM);
|
|
71
|
+
var tokenProgramPk = new PublicKey(TOKEN_PROGRAM);
|
|
72
|
+
var usdcMintPk = new PublicKey(USDC_MINT);
|
|
73
|
+
// ComputeUnitLimit(20000)
|
|
74
|
+
var setLimitData = Buffer.alloc(5);
|
|
75
|
+
setLimitData[0] = 0x02;
|
|
76
|
+
setLimitData.writeUInt32LE(20000, 1);
|
|
77
|
+
var setLimitIx = { programId: computeBudgetPk, keys: [], data: setLimitData };
|
|
78
|
+
// ComputeUnitPrice(1)
|
|
79
|
+
var setPriceData = Buffer.alloc(9);
|
|
80
|
+
setPriceData[0] = 0x03;
|
|
81
|
+
setPriceData.writeBigUInt64LE(BigInt(1), 1);
|
|
82
|
+
var setPriceIx = { programId: computeBudgetPk, keys: [], data: setPriceData };
|
|
83
|
+
// TransferChecked
|
|
84
|
+
var transferKeys = [
|
|
85
|
+
{ pubkey: userATA, isSigner: false, isWritable: true },
|
|
86
|
+
{ pubkey: usdcMintPk, isSigner: false, isWritable: false },
|
|
87
|
+
{ pubkey: recipientATA, isSigner: false, isWritable: true },
|
|
88
|
+
{ pubkey: kp.publicKey, isSigner: true, isWritable: false },
|
|
89
|
+
];
|
|
90
|
+
var transferData = Buffer.alloc(10);
|
|
91
|
+
transferData[0] = 0x0c;
|
|
92
|
+
transferData.writeUInt32LE(amount & 0xFFFFFFFF, 1);
|
|
93
|
+
transferData.writeUInt32LE(Math.floor(amount / 0x100000000) & 0xFFFFFFFF, 5);
|
|
94
|
+
transferData[9] = 6;
|
|
95
|
+
var transferIx = { programId: tokenProgramPk, keys: transferKeys, data: transferData };
|
|
96
|
+
// FIX v4.16.10: NO Memo instruction in V2 — Dexter scheme_exact_svm whitelist
|
|
97
|
+
// only allows ComputeBudget + SPL Token + Lighthouse. Memo would be rejected.
|
|
98
|
+
var bh = await conn.getLatestBlockhash('confirmed');
|
|
99
|
+
var message = new TransactionMessage({
|
|
100
|
+
payerKey: feePayerPk,
|
|
101
|
+
recentBlockhash: bh.blockhash,
|
|
102
|
+
instructions: [setLimitIx, setPriceIx, transferIx],
|
|
103
|
+
}).compileToV0Message();
|
|
104
|
+
var vtx = new VersionedTransaction(message);
|
|
105
|
+
vtx.sign([kp]);
|
|
106
|
+
var txB64 = Buffer.from(vtx.serialize()).toString('base64');
|
|
107
|
+
console.error('[cryptoiz-mcp] V2 tx built (Dexter gas-sponsored), 3 ix: limit+price+transferChecked');
|
|
108
|
+
return txB64;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// V1: direct on-chain, user pays SOL gas (fallback only)
|
|
57
112
|
async function sendUSDC(amount, toolName) {
|
|
58
113
|
var kp = getKeypair();
|
|
59
114
|
var conn = new Connection(SOL_RPC, 'confirmed');
|
|
60
115
|
var userATA = findATA(kp.publicKey.toBase58(), USDC_MINT);
|
|
61
116
|
var recipientATA = findATA(RECIPIENT, USDC_MINT);
|
|
62
|
-
// TransferChecked ix
|
|
63
117
|
var keys = [
|
|
64
118
|
{ pubkey: userATA, isSigner: false, isWritable: true },
|
|
65
119
|
{ pubkey: new PublicKey(USDC_MINT), isSigner: false, isWritable: false },
|
|
66
120
|
{ pubkey: recipientATA, isSigner: false, isWritable: true },
|
|
67
121
|
{ pubkey: kp.publicKey, isSigner: true, isWritable: false },
|
|
68
122
|
];
|
|
69
|
-
|
|
123
|
+
// FIX v4.16.10: TransferChecked needs 10 bytes (1 disc + 8 amount + 1 decimals)
|
|
124
|
+
var data = Buffer.alloc(10);
|
|
70
125
|
data[0] = 0x0c;
|
|
71
126
|
data.writeUInt32LE(amount & 0xFFFFFFFF, 1);
|
|
72
127
|
data.writeUInt32LE(Math.floor(amount / 0x100000000) & 0xFFFFFFFF, 5);
|
|
73
|
-
data[
|
|
128
|
+
data[9] = 6;
|
|
74
129
|
var transferIx = { programId: new PublicKey(TOKEN_PROGRAM), keys: keys, data: data };
|
|
75
|
-
|
|
76
|
-
var nonce = Date.now().toString(16) + Math.floor(Math.random() * 0xffff).toString(16);
|
|
130
|
+
var nonce = Date.now().toString(16) + Math.floor(Math.random()*0xffff).toString(16);
|
|
77
131
|
var memoIx = {
|
|
78
132
|
programId: new PublicKey(MEMO_PROGRAM),
|
|
79
133
|
keys: [],
|
|
@@ -86,7 +140,7 @@ async function sendUSDC(amount, toolName) {
|
|
|
86
140
|
tx.sign(kp);
|
|
87
141
|
var sig = await conn.sendRawTransaction(tx.serialize(), { skipPreflight: false });
|
|
88
142
|
await conn.confirmTransaction({ signature: sig, blockhash: bh.blockhash, lastValidBlockHeight: bh.lastValidBlockHeight }, 'confirmed');
|
|
89
|
-
console.error('[cryptoiz-mcp] TX: ' + sig);
|
|
143
|
+
console.error('[cryptoiz-mcp] V1 TX: ' + sig);
|
|
90
144
|
return sig;
|
|
91
145
|
}
|
|
92
146
|
|
|
@@ -101,22 +155,78 @@ async function callTool(toolName, args) {
|
|
|
101
155
|
if (toolName === 'get_whale_divergence' && args && args.timeframe) queryParts.push('tf=' + args.timeframe);
|
|
102
156
|
if (toolName === 'get_token_ca' && args && args.name) queryParts.push('name=' + encodeURIComponent(args.name));
|
|
103
157
|
var url = (TOOL_ENDPOINTS[toolName] || GATEWAY) + '?' + queryParts.join('&');
|
|
158
|
+
|
|
104
159
|
// Step 1: discovery
|
|
105
160
|
var resp1 = await fetch(url, { headers: clientHeaders() });
|
|
106
161
|
if (resp1.status === 200) { var d = await resp1.json(); notifyUpdate(d, resp1.headers); return d; }
|
|
107
162
|
if (resp1.status !== 402) throw new Error('Server error ' + resp1.status + ': ' + (await resp1.text()).substring(0, 200));
|
|
163
|
+
|
|
108
164
|
// Step 2: parse payment requirements
|
|
109
165
|
var payReq = null;
|
|
166
|
+
var useV2 = false;
|
|
110
167
|
var prHeader = resp1.headers.get('payment-required');
|
|
111
|
-
if (prHeader) {
|
|
112
|
-
|
|
168
|
+
if (prHeader) {
|
|
169
|
+
try {
|
|
170
|
+
var arr = JSON.parse(Buffer.from(prHeader, 'base64').toString('utf8'));
|
|
171
|
+
if (arr && arr[0]) { payReq = arr[0]; useV2 = true; }
|
|
172
|
+
} catch(_e) {}
|
|
173
|
+
}
|
|
174
|
+
if (!payReq) {
|
|
175
|
+
var b402 = await resp1.json();
|
|
176
|
+
if (b402 && b402.accepts && b402.accepts[0]) payReq = b402.accepts[0];
|
|
177
|
+
}
|
|
113
178
|
if (!payReq) throw new Error('No payment requirements in 402');
|
|
179
|
+
|
|
114
180
|
var amount = parseInt(payReq.maxAmountRequired || payReq.amount || '10000');
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
var
|
|
118
|
-
|
|
119
|
-
|
|
181
|
+
var hasFeePayer = payReq.extra && payReq.extra.feePayer;
|
|
182
|
+
var paymentHeader = '';
|
|
183
|
+
var headerName = '';
|
|
184
|
+
|
|
185
|
+
// Step 3: Try V2 Dexter (gas-sponsored by Dexter — user only needs USDC)
|
|
186
|
+
if (useV2 && hasFeePayer) {
|
|
187
|
+
console.error('[cryptoiz-mcp] V2 mode: Dexter gas-sponsored, paying ' + (amount/1000000).toFixed(4) + ' USDC');
|
|
188
|
+
try {
|
|
189
|
+
var txB64 = await buildV2PaymentPayload(amount, payReq.extra.feePayer);
|
|
190
|
+
// FIX v4.16.10: x402Version:2 (was 1), add 'accepted' (chosen PaymentRequirements
|
|
191
|
+
// verbatim — Dexter /verify needs this to match amount/asset/payTo). Removed bogus
|
|
192
|
+
// signature field — V2 schema only has payload.transaction.
|
|
193
|
+
var v2Payload = {
|
|
194
|
+
x402Version: 2,
|
|
195
|
+
scheme: 'exact',
|
|
196
|
+
network: payReq.network || 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp',
|
|
197
|
+
accepted: payReq,
|
|
198
|
+
payload: { transaction: txB64 },
|
|
199
|
+
extensions: {}
|
|
200
|
+
};
|
|
201
|
+
paymentHeader = Buffer.from(JSON.stringify(v2Payload)).toString('base64');
|
|
202
|
+
headerName = 'payment-signature';
|
|
203
|
+
} catch(v2Err) {
|
|
204
|
+
console.error('[cryptoiz-mcp] V2 build failed: ' + v2Err.message + ' -> fallback V1');
|
|
205
|
+
useV2 = false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Step 4: V1 fallback (user pays gas — only if V2 failed)
|
|
210
|
+
if (!paymentHeader) {
|
|
211
|
+
console.error('[cryptoiz-mcp] V1 fallback: direct on-chain transfer');
|
|
212
|
+
var sig = await sendUSDC(amount, toolName);
|
|
213
|
+
paymentHeader = Buffer.from(JSON.stringify({ signature: sig })).toString('base64');
|
|
214
|
+
headerName = 'x-payment';
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Step 5: submit payment
|
|
218
|
+
var headers2 = {};
|
|
219
|
+
headers2[headerName] = paymentHeader;
|
|
220
|
+
var resp2 = await fetch(url, { headers: clientHeaders(headers2) });
|
|
221
|
+
|
|
222
|
+
// Step 6: if V2 failed at server, retry with V1
|
|
223
|
+
if (resp2.status !== 200 && useV2) {
|
|
224
|
+
console.error('[cryptoiz-mcp] V2 settle failed, trying V1 fallback...');
|
|
225
|
+
var fallbackSig = await sendUSDC(amount, toolName);
|
|
226
|
+
var v1Header = Buffer.from(JSON.stringify({ signature: fallbackSig })).toString('base64');
|
|
227
|
+
resp2 = await fetch(url, { headers: clientHeaders({ 'x-payment': v1Header }) });
|
|
228
|
+
}
|
|
229
|
+
|
|
120
230
|
if (resp2.status !== 200) throw new Error('Payment failed ' + resp2.status + ': ' + (await resp2.text()).substring(0, 300));
|
|
121
231
|
var data = await resp2.json();
|
|
122
232
|
notifyUpdate(data, resp2.headers);
|
|
@@ -131,7 +241,7 @@ var TOOLS = [
|
|
|
131
241
|
{ name: 'get_whale_distribution', description: 'Distribution phase tokens. Cost: $0.02 USDC', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
132
242
|
{ name: 'get_btc_regime', description: 'BTC macro regime. Cost: $0.01 USDC', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
133
243
|
{ name: 'get_btc_futures_signal', description: 'BTC futures signal. Cost: $0.03 USDC', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
134
|
-
{ name: 'get_token_ca', description: 'Token contract address
|
|
244
|
+
{ name: 'get_token_ca', description: 'Token contract address. FREE', inputSchema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'], additionalProperties: false } },
|
|
135
245
|
{ name: 'get_status', description: 'CryptoIZ MCP status. FREE', inputSchema: { type: 'object', properties: {}, additionalProperties: false } },
|
|
136
246
|
];
|
|
137
247
|
|
|
@@ -149,6 +259,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
149
259
|
async function main() {
|
|
150
260
|
var transport = new StdioServerTransport();
|
|
151
261
|
await server.connect(transport);
|
|
152
|
-
console.error('[cryptoiz-mcp] ' + VERSION + ' running (V1
|
|
262
|
+
console.error('[cryptoiz-mcp] ' + VERSION + ' running (V2 Dexter gas-sponsored + V1 fallback)');
|
|
153
263
|
}
|
|
154
264
|
main().catch(console.error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cryptoiz-mcp",
|
|
3
|
-
"version": "4.16.
|
|
3
|
+
"version": "4.16.10",
|
|
4
4
|
"description": "CryptoIZ MCP Server - Solana DEX whale intelligence via Claude Desktop with x402 USDC micropayments",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -8,14 +8,24 @@
|
|
|
8
8
|
"cryptoiz-mcp": "./index.js",
|
|
9
9
|
"cryptoiz-mcp-setup": "./setup.js"
|
|
10
10
|
},
|
|
11
|
-
"files": [
|
|
11
|
+
"files": [
|
|
12
|
+
"index.js",
|
|
13
|
+
"setup.js",
|
|
14
|
+
"package.json",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
12
17
|
"dependencies": {
|
|
13
18
|
"@modelcontextprotocol/sdk": "^1.0.4",
|
|
14
19
|
"@solana/web3.js": "^1.95.8",
|
|
15
20
|
"bs58": "^6.0.0"
|
|
16
21
|
},
|
|
17
|
-
"engines": {
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=18.0.0"
|
|
24
|
+
},
|
|
18
25
|
"author": "CryptoIZ",
|
|
19
26
|
"license": "MIT",
|
|
20
|
-
"repository": {
|
|
21
|
-
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/dadang11/cryptoiz-mcp.git"
|
|
30
|
+
}
|
|
31
|
+
}
|
package/setup.js
CHANGED
|
File without changes
|