cryptoiz-mcp 4.15.2 → 4.15.4
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 +63 -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.4';
|
|
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,73 @@ 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 TransferChecked (NOT Transfer!)
|
|
79
|
+
// x402 SVM spec requires TransferChecked (instruction index 12)
|
|
80
|
+
// Accounts: [source_ata, mint, destination_ata, authority]
|
|
81
|
+
// Data: [12, amount_u64_LE, decimals_u8]
|
|
54
82
|
var tokenProgramPk = new PublicKey(TOKEN_PROGRAM);
|
|
55
|
-
var
|
|
83
|
+
var usdcMintPk = new PublicKey(USDC_MINT);
|
|
84
|
+
var transferKeys = [
|
|
56
85
|
{ pubkey: userATA, isSigner: false, isWritable: true },
|
|
86
|
+
{ pubkey: usdcMintPk, isSigner: false, isWritable: false },
|
|
57
87
|
{ pubkey: recipientATA, isSigner: false, isWritable: true },
|
|
58
88
|
{ pubkey: kp.publicKey, isSigner: true, isWritable: false },
|
|
59
89
|
];
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
data.writeUInt8(3, 0); // Transfer instruction index
|
|
64
|
-
// Write amount as u64 LE
|
|
90
|
+
// TransferChecked data: instruction_index(1) + amount_u64(8) + decimals(1) = 10 bytes
|
|
91
|
+
var transferData = Buffer.alloc(10);
|
|
92
|
+
transferData.writeUInt8(12, 0); // TransferChecked instruction index
|
|
65
93
|
var lo = amount & 0xFFFFFFFF;
|
|
66
94
|
var hi = Math.floor(amount / 0x100000000) & 0xFFFFFFFF;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
95
|
+
transferData.writeUInt32LE(lo, 1);
|
|
96
|
+
transferData.writeUInt32LE(hi, 5);
|
|
97
|
+
transferData.writeUInt8(6, 9); // USDC decimals = 6
|
|
70
98
|
var transferIx = {
|
|
71
99
|
programId: tokenProgramPk,
|
|
72
|
-
keys:
|
|
73
|
-
data:
|
|
100
|
+
keys: transferKeys,
|
|
101
|
+
data: transferData,
|
|
74
102
|
};
|
|
75
103
|
|
|
76
104
|
// Get recent blockhash
|
|
77
105
|
var bhResult = await conn.getLatestBlockhash('confirmed');
|
|
78
106
|
|
|
79
|
-
// Build V0 message
|
|
107
|
+
// Build V0 message: feePayer = Dexter, 3 instructions in required order
|
|
80
108
|
var message = new TransactionMessage({
|
|
81
109
|
payerKey: feePayerPk,
|
|
82
110
|
recentBlockhash: bhResult.blockhash,
|
|
83
|
-
instructions: [transferIx],
|
|
111
|
+
instructions: [setLimitIx, setPriceIx, transferIx],
|
|
84
112
|
}).compileToV0Message();
|
|
85
113
|
|
|
86
114
|
var vtx = new VersionedTransaction(message);
|
|
@@ -88,10 +116,10 @@ async function buildV2PaymentPayload(amount) {
|
|
|
88
116
|
// Partially sign with user keypair only (Dexter signs as feePayer later)
|
|
89
117
|
vtx.sign([kp]);
|
|
90
118
|
|
|
91
|
-
// Serialize and base64 encode
|
|
92
119
|
var serialized = vtx.serialize();
|
|
93
120
|
var txB64 = Buffer.from(serialized).toString('base64');
|
|
94
121
|
|
|
122
|
+
console.error('[cryptoiz-mcp] V2 tx built: 3 ix (ComputeLimit + ComputePrice + TransferChecked), feePayer=' + feePayerAddr.substring(0, 8) + '...');
|
|
95
123
|
return txB64;
|
|
96
124
|
}
|
|
97
125
|
|
|
@@ -210,9 +238,10 @@ async function callTool(toolName, args) {
|
|
|
210
238
|
|
|
211
239
|
if (useV2 && paymentRequirements.extra && paymentRequirements.extra.feePayer) {
|
|
212
240
|
// V2: Build partially-signed tx, Dexter pays gas
|
|
213
|
-
|
|
241
|
+
var v2FeePayer = paymentRequirements.extra.feePayer;
|
|
242
|
+
console.error('[cryptoiz-mcp] V2 mode: building 3-instruction tx for Dexter, feePayer=' + v2FeePayer.substring(0, 8) + '...');
|
|
214
243
|
try {
|
|
215
|
-
var txB64 = await buildV2PaymentPayload(amount);
|
|
244
|
+
var txB64 = await buildV2PaymentPayload(amount, v2FeePayer);
|
|
216
245
|
|
|
217
246
|
// Build V2 payment payload per x402 spec
|
|
218
247
|
var v2Payload = {
|
|
@@ -226,7 +255,7 @@ async function callTool(toolName, args) {
|
|
|
226
255
|
|
|
227
256
|
paymentHeader = Buffer.from(JSON.stringify(v2Payload)).toString('base64');
|
|
228
257
|
headerName = 'payment-signature';
|
|
229
|
-
console.error('[cryptoiz-mcp] V2
|
|
258
|
+
console.error('[cryptoiz-mcp] V2 tx ready, sending via payment-signature header');
|
|
230
259
|
} catch(e) {
|
|
231
260
|
console.error('[cryptoiz-mcp] V2 build failed: ' + e.message + ', falling back to V1');
|
|
232
261
|
useV2 = false;
|
|
@@ -259,14 +288,19 @@ async function callTool(toolName, args) {
|
|
|
259
288
|
console.error('[cryptoiz-mcp] V2 settle failed (' + resp2.status + '): ' + v2ErrBody.substring(0, 200));
|
|
260
289
|
console.error('[cryptoiz-mcp] Auto-fallback to V1 (sendUSDC on-chain)...');
|
|
261
290
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
291
|
+
try {
|
|
292
|
+
// V1: send USDC on-chain, retry with x-payment
|
|
293
|
+
var fallbackSig = await sendUSDC(amount);
|
|
294
|
+
console.error('[cryptoiz-mcp] V1 fallback TX confirmed: ' + fallbackSig);
|
|
295
|
+
|
|
296
|
+
var v1FallbackPayload = { signature: fallbackSig };
|
|
297
|
+
var v1FallbackHeader = Buffer.from(JSON.stringify(v1FallbackPayload)).toString('base64');
|
|
298
|
+
|
|
299
|
+
resp2 = await fetch(url, { headers: { 'x-payment': v1FallbackHeader } });
|
|
300
|
+
} catch(fallbackErr) {
|
|
301
|
+
console.error('[cryptoiz-mcp] V1 fallback also failed: ' + fallbackErr.message);
|
|
302
|
+
throw new Error('V2 failed (' + v2ErrBody.substring(0, 100) + '), V1 fallback also failed: ' + fallbackErr.message);
|
|
303
|
+
}
|
|
270
304
|
}
|
|
271
305
|
|
|
272
306
|
if (resp2.status !== 200) {
|
package/package.json
CHANGED