cryptoiz-mcp 4.15.2 → 4.15.3
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 +56 -29
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprot
|
|
|
9
9
|
import { Connection, Keypair, PublicKey, Transaction, SystemProgram, VersionedTransaction, TransactionMessage } from '@solana/web3.js';
|
|
10
10
|
import bs58 from 'bs58';
|
|
11
11
|
|
|
12
|
-
var VERSION = 'v4.15.
|
|
12
|
+
var VERSION = 'v4.15.3';
|
|
13
13
|
var GATEWAY = 'https://rehqwsypjnjirhuiapqh.supabase.co/functions/v1/mcp-x402-gateway';
|
|
14
14
|
var RECIPIENT = 'DsKmdkYx49Xc1WhqMUAztwhdYPTqieyC98VmnnJdgpXX';
|
|
15
15
|
var USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
|
|
@@ -42,45 +42,66 @@ function findATA(wallet, mint) {
|
|
|
42
42
|
|
|
43
43
|
// ===== V2: Build partially-signed tx for Dexter facilitator =====
|
|
44
44
|
// Dexter pays gas (feePayer), user only signs the transfer
|
|
45
|
-
|
|
45
|
+
// Tx MUST contain 3 instructions in order: SetComputeUnitLimit, SetComputeUnitPrice, SPL Transfer
|
|
46
|
+
var COMPUTE_BUDGET_PROGRAM = 'ComputeBudget111111111111111111111111111111';
|
|
47
|
+
|
|
48
|
+
async function buildV2PaymentPayload(amount, feePayerAddr) {
|
|
46
49
|
var kp = getKeypair();
|
|
47
50
|
var conn = new Connection(SOL_RPC, 'confirmed');
|
|
48
51
|
|
|
49
52
|
var userATA = findATA(kp.publicKey.toBase58(), USDC_MINT);
|
|
50
53
|
var recipientATA = findATA(RECIPIENT, USDC_MINT);
|
|
51
|
-
var feePayerPk = new PublicKey(
|
|
54
|
+
var feePayerPk = new PublicKey(feePayerAddr);
|
|
55
|
+
var computeBudgetPk = new PublicKey(COMPUTE_BUDGET_PROGRAM);
|
|
56
|
+
|
|
57
|
+
// Instruction 1: SetComputeUnitLimit (instruction index 2, u32 units)
|
|
58
|
+
var setLimitData = Buffer.alloc(5);
|
|
59
|
+
setLimitData.writeUInt8(2, 0);
|
|
60
|
+
setLimitData.writeUInt32LE(200000, 1);
|
|
61
|
+
var setLimitIx = {
|
|
62
|
+
programId: computeBudgetPk,
|
|
63
|
+
keys: [],
|
|
64
|
+
data: setLimitData,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Instruction 2: SetComputeUnitPrice (instruction index 3, u64 microLamports)
|
|
68
|
+
var setPriceData = Buffer.alloc(9);
|
|
69
|
+
setPriceData.writeUInt8(3, 0);
|
|
70
|
+
setPriceData.writeUInt32LE(50000, 1); // 50000 microLamports
|
|
71
|
+
setPriceData.writeUInt32LE(0, 5);
|
|
72
|
+
var setPriceIx = {
|
|
73
|
+
programId: computeBudgetPk,
|
|
74
|
+
keys: [],
|
|
75
|
+
data: setPriceData,
|
|
76
|
+
};
|
|
52
77
|
|
|
53
|
-
//
|
|
78
|
+
// Instruction 3: SPL Token Transfer
|
|
54
79
|
var tokenProgramPk = new PublicKey(TOKEN_PROGRAM);
|
|
55
|
-
var
|
|
80
|
+
var transferKeys = [
|
|
56
81
|
{ pubkey: userATA, isSigner: false, isWritable: true },
|
|
57
82
|
{ pubkey: recipientATA, isSigner: false, isWritable: true },
|
|
58
83
|
{ pubkey: kp.publicKey, isSigner: true, isWritable: false },
|
|
59
84
|
];
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
var data = Buffer.alloc(9);
|
|
63
|
-
data.writeUInt8(3, 0); // Transfer instruction index
|
|
64
|
-
// Write amount as u64 LE
|
|
85
|
+
var transferData = Buffer.alloc(9);
|
|
86
|
+
transferData.writeUInt8(3, 0);
|
|
65
87
|
var lo = amount & 0xFFFFFFFF;
|
|
66
88
|
var hi = Math.floor(amount / 0x100000000) & 0xFFFFFFFF;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
89
|
+
transferData.writeUInt32LE(lo, 1);
|
|
90
|
+
transferData.writeUInt32LE(hi, 5);
|
|
70
91
|
var transferIx = {
|
|
71
92
|
programId: tokenProgramPk,
|
|
72
|
-
keys:
|
|
73
|
-
data:
|
|
93
|
+
keys: transferKeys,
|
|
94
|
+
data: transferData,
|
|
74
95
|
};
|
|
75
96
|
|
|
76
97
|
// Get recent blockhash
|
|
77
98
|
var bhResult = await conn.getLatestBlockhash('confirmed');
|
|
78
99
|
|
|
79
|
-
// Build V0 message
|
|
100
|
+
// Build V0 message: feePayer = Dexter, 3 instructions in required order
|
|
80
101
|
var message = new TransactionMessage({
|
|
81
102
|
payerKey: feePayerPk,
|
|
82
103
|
recentBlockhash: bhResult.blockhash,
|
|
83
|
-
instructions: [transferIx],
|
|
104
|
+
instructions: [setLimitIx, setPriceIx, transferIx],
|
|
84
105
|
}).compileToV0Message();
|
|
85
106
|
|
|
86
107
|
var vtx = new VersionedTransaction(message);
|
|
@@ -88,10 +109,10 @@ async function buildV2PaymentPayload(amount) {
|
|
|
88
109
|
// Partially sign with user keypair only (Dexter signs as feePayer later)
|
|
89
110
|
vtx.sign([kp]);
|
|
90
111
|
|
|
91
|
-
// Serialize and base64 encode
|
|
92
112
|
var serialized = vtx.serialize();
|
|
93
113
|
var txB64 = Buffer.from(serialized).toString('base64');
|
|
94
114
|
|
|
115
|
+
console.error('[cryptoiz-mcp] V2 tx built: 3 instructions (ComputeLimit + ComputePrice + Transfer), feePayer=' + feePayerAddr.substring(0, 8) + '...');
|
|
95
116
|
return txB64;
|
|
96
117
|
}
|
|
97
118
|
|
|
@@ -210,9 +231,10 @@ async function callTool(toolName, args) {
|
|
|
210
231
|
|
|
211
232
|
if (useV2 && paymentRequirements.extra && paymentRequirements.extra.feePayer) {
|
|
212
233
|
// V2: Build partially-signed tx, Dexter pays gas
|
|
213
|
-
|
|
234
|
+
var v2FeePayer = paymentRequirements.extra.feePayer;
|
|
235
|
+
console.error('[cryptoiz-mcp] V2 mode: building 3-instruction tx for Dexter, feePayer=' + v2FeePayer.substring(0, 8) + '...');
|
|
214
236
|
try {
|
|
215
|
-
var txB64 = await buildV2PaymentPayload(amount);
|
|
237
|
+
var txB64 = await buildV2PaymentPayload(amount, v2FeePayer);
|
|
216
238
|
|
|
217
239
|
// Build V2 payment payload per x402 spec
|
|
218
240
|
var v2Payload = {
|
|
@@ -226,7 +248,7 @@ async function callTool(toolName, args) {
|
|
|
226
248
|
|
|
227
249
|
paymentHeader = Buffer.from(JSON.stringify(v2Payload)).toString('base64');
|
|
228
250
|
headerName = 'payment-signature';
|
|
229
|
-
console.error('[cryptoiz-mcp] V2
|
|
251
|
+
console.error('[cryptoiz-mcp] V2 tx ready, sending via payment-signature header');
|
|
230
252
|
} catch(e) {
|
|
231
253
|
console.error('[cryptoiz-mcp] V2 build failed: ' + e.message + ', falling back to V1');
|
|
232
254
|
useV2 = false;
|
|
@@ -259,14 +281,19 @@ async function callTool(toolName, args) {
|
|
|
259
281
|
console.error('[cryptoiz-mcp] V2 settle failed (' + resp2.status + '): ' + v2ErrBody.substring(0, 200));
|
|
260
282
|
console.error('[cryptoiz-mcp] Auto-fallback to V1 (sendUSDC on-chain)...');
|
|
261
283
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
284
|
+
try {
|
|
285
|
+
// V1: send USDC on-chain, retry with x-payment
|
|
286
|
+
var fallbackSig = await sendUSDC(amount);
|
|
287
|
+
console.error('[cryptoiz-mcp] V1 fallback TX confirmed: ' + fallbackSig);
|
|
288
|
+
|
|
289
|
+
var v1FallbackPayload = { signature: fallbackSig };
|
|
290
|
+
var v1FallbackHeader = Buffer.from(JSON.stringify(v1FallbackPayload)).toString('base64');
|
|
291
|
+
|
|
292
|
+
resp2 = await fetch(url, { headers: { 'x-payment': v1FallbackHeader } });
|
|
293
|
+
} catch(fallbackErr) {
|
|
294
|
+
console.error('[cryptoiz-mcp] V1 fallback also failed: ' + fallbackErr.message);
|
|
295
|
+
throw new Error('V2 failed (' + v2ErrBody.substring(0, 100) + '), V1 fallback also failed: ' + fallbackErr.message);
|
|
296
|
+
}
|
|
270
297
|
}
|
|
271
298
|
|
|
272
299
|
if (resp2.status !== 200) {
|
package/package.json
CHANGED