kinetic-mcp 1.0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kinetic
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Solana Trading MCP Server
2
+
3
+ An MCP (Model Context Protocol) server that connects to the Kinetic Solana trading platform, designed for Claude Desktop. It runs locally on your machine and lets you check balances and execute swaps through natural language conversation.
4
+
5
+ ## Quick Start
6
+
7
+ Add this to your Claude Desktop config file (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
8
+
9
+ ```json
10
+ {
11
+ "mcpServers": {
12
+ "solana-trading": {
13
+ "command": "npx",
14
+ "args": ["-y", "kinetic-mcp"],
15
+ "env": {
16
+ "SOLANA_KEYPAIR_PATH": "/absolute/path/to/your/keypair.json"
17
+ }
18
+ }
19
+ }
20
+ }
21
+ ```
22
+
23
+ Restart Claude Desktop (fully quit and reopen). See the [getting started guide](docs/getting-started.md) for keypair setup and Phantom export instructions.
24
+
25
+ ## Usage
26
+
27
+ - "What's my SOL balance?"
28
+ - "Show me all my token holdings"
29
+ - "Swap 0.01 SOL for USDC" — Claude shows a quote preview and asks for confirmation
30
+ - "Swap 100 USDC for SOL with 1% slippage" — specify custom slippage
31
+
32
+ Claude will ask for permission the first time it uses a tool. Click "Allow for This Chat" or "Allow Always".
33
+
34
+ ## Safety Guardrails
35
+
36
+ - **Two-step confirmation** — swaps always show a quote preview first; you must confirm before execution
37
+ - **Max trade size** — `MAX_TRADE_SOL` limits swap size in SOL-equivalent (default: 10 SOL)
38
+ - **Slippage cap** — maximum 10% (1000 bps) enforced by input validation
39
+ - **No private key exposure** — keypair is loaded from a local file only, never accepted as tool input
40
+
41
+ ## Available Tools
42
+
43
+ | Tool | Description | Inputs |
44
+ | -------------------- | -------------------------------------- | ------------------------------------------------------------------------ |
45
+ | `get_wallet_balance` | Get SOL balance and all token holdings | None |
46
+ | `swap_tokens` | Swap one token for another | `from_token`, `to_token`, `amount`, `slippage_bps` (optional), `confirm` |
47
+
48
+ ## Architecture
49
+
50
+ - **Swap execution**: Kinetic API (quote → build transaction → send transaction)
51
+ - **On-chain data**: Direct Solana RPC (balances, token accounts, mint info)
52
+ - **Token resolution**: Well-known token table + on-chain mint lookup
53
+
54
+ ## Troubleshooting
55
+
56
+ | Problem | Solution |
57
+ | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
58
+ | No hammer icon appears | Check that the path in `claude_desktop_config.json` is correct and absolute. Run `npm run build`. Fully restart Claude Desktop. |
59
+ | "Unable to connect to MCP server" | Check Claude Desktop logs for errors. Verify `npm run build` succeeds. Make sure `build/index.js` exists. |
60
+ | Tools appear but return errors | Check your env var values. Verify `SOLANA_KEYPAIR_PATH` points to a valid keypair file. Test network access. |
61
+ | "Cannot find module" errors | Run `npm install && npm run build`. Make sure you're using Node.js 20+. |
62
+ | Import errors about ES modules | Verify `"type": "module"` is in package.json. Rebuild with `npm run build`. |
63
+ | Balance shows mint addresses | Token not in well-known table. Use mint address for swaps with unknown tokens. |
64
+
65
+ **Where to find Claude Desktop logs:**
66
+
67
+ - **macOS**: `~/Library/Logs/Claude/`
68
+ - **Windows**: `%APPDATA%\Claude\logs\`
69
+
70
+ ## Development
71
+
72
+ ```bash
73
+ npm run dev # Watch mode (recompile on change)
74
+ npm run test # Run tests
75
+ npm run lint # Run ESLint
76
+ npm run format:check # Check Prettier formatting
77
+ npm run typecheck # Type-check without emitting
78
+ npm run clean # Remove build output
79
+ ```
80
+
81
+ ## Environment Variables
82
+
83
+ | Variable | Required | Default | Description |
84
+ | -------------------------- | -------- | ------------------------------------- | ------------------------------------ |
85
+ | `SOLANA_KEYPAIR_PATH` | Yes | — | Path to Solana keypair JSON file |
86
+ | `API_BASE_URL` | No | `https://api.kinetic.xyz` | Kinetic API base URL |
87
+ | `AUTH_BASE_URL` | No | `https://auth.kinetic.xyz` | Kinetic auth base URL |
88
+ | `API_KEY` | No | — | Kinetic API key (higher rate limits) |
89
+ | `SOLANA_RPC_URL` | No | `https://api.mainnet-beta.solana.com` | Solana RPC endpoint |
90
+ | `MAX_TRADE_SOL` | No | `10` | Max swap size in SOL-equivalent |
91
+ | `PRIORITY_FEE_LAMPORTS` | No | `400000` | Priority fee for transactions |
92
+ | `DYNAMIC_SLIPPAGE_MIN_BPS` | No | `1` | Minimum dynamic slippage (bps) |
93
+ | `DYNAMIC_SLIPPAGE_MAX_BPS` | No | `300` | Maximum dynamic slippage (bps) |
94
+ | `JITO_ENABLED` | No | `false` | Enable Jito MEV protection |
95
+ | `REQUEST_TIMEOUT_MS` | No | `30000` | API request timeout (ms) |
96
+ | `SEND_TX_TIMEOUT_MS` | No | `120000` | sendTransaction stream timeout (ms) |
97
+ | `LOG_LEVEL` | No | `info` | Log level (debug, info, warn, error) |
@@ -0,0 +1,48 @@
1
+ import { z } from "zod";
2
+ const httpsUrl = z
3
+ .string()
4
+ .url()
5
+ .refine((u) => u.startsWith("https://"), {
6
+ message: "URL must use HTTPS",
7
+ });
8
+ const configSchema = z.object({
9
+ solanaKeypairPath: z.string().min(1, "SOLANA_KEYPAIR_PATH is required"),
10
+ apiBaseUrl: httpsUrl.default("https://api.kinetic.xyz"),
11
+ authBaseUrl: httpsUrl.default("https://auth.kinetic.xyz"),
12
+ apiKey: z.string().optional(),
13
+ maxTradeSol: z.coerce.number().positive().default(10),
14
+ solanaRpcUrl: httpsUrl.default("https://api.mainnet-beta.solana.com"),
15
+ requestTimeoutMs: z.coerce.number().int().positive().default(30_000),
16
+ sendTxTimeoutMs: z.coerce.number().int().positive().default(120_000),
17
+ priorityFeeLamports: z.coerce.number().int().nonnegative().default(400_000),
18
+ dynamicSlippageMinBps: z.coerce.number().int().nonnegative().default(1),
19
+ dynamicSlippageMaxBps: z.coerce.number().int().positive().default(300),
20
+ jitoEnabled: z
21
+ .enum(["true", "false", "1", "0", ""])
22
+ .default("false")
23
+ .transform((v) => v === "true" || v === "1"),
24
+ logLevel: z.enum(["debug", "info", "warn", "error"]).default("info"),
25
+ });
26
+ export function loadConfig() {
27
+ const result = configSchema.safeParse({
28
+ solanaKeypairPath: process.env.SOLANA_KEYPAIR_PATH,
29
+ apiBaseUrl: process.env.API_BASE_URL || undefined,
30
+ authBaseUrl: process.env.AUTH_BASE_URL || undefined,
31
+ apiKey: process.env.API_KEY || undefined,
32
+ maxTradeSol: process.env.MAX_TRADE_SOL || undefined,
33
+ solanaRpcUrl: process.env.SOLANA_RPC_URL || undefined,
34
+ requestTimeoutMs: process.env.REQUEST_TIMEOUT_MS || undefined,
35
+ sendTxTimeoutMs: process.env.SEND_TX_TIMEOUT_MS || undefined,
36
+ priorityFeeLamports: process.env.PRIORITY_FEE_LAMPORTS || undefined,
37
+ dynamicSlippageMinBps: process.env.DYNAMIC_SLIPPAGE_MIN_BPS || undefined,
38
+ dynamicSlippageMaxBps: process.env.DYNAMIC_SLIPPAGE_MAX_BPS || undefined,
39
+ jitoEnabled: process.env.JITO_ENABLED || undefined,
40
+ logLevel: process.env.LOG_LEVEL || undefined,
41
+ });
42
+ if (!result.success) {
43
+ const errors = result.error.issues.map((i) => ` ${i.path.join(".")}: ${i.message}`);
44
+ throw new Error(`Invalid configuration:\n${errors.join("\n")}`);
45
+ }
46
+ return result.data;
47
+ }
48
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
package/build/index.js ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
3
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
+ import { z } from "zod";
6
+ import { loadConfig } from "./config.js";
7
+ import { createLogger } from "./logger.js";
8
+ import { initSolana, loadKeypair, getWalletAddress } from "./utils/solana.js";
9
+ import { initApiClient } from "./utils/api-client.js";
10
+ import { initTokenResolver } from "./utils/token-resolver.js";
11
+ import { initSwap, swapTokens } from "./tools/swap.js";
12
+ import { getWalletBalance } from "./tools/balance.js";
13
+ const require = createRequire(import.meta.url);
14
+ const { version } = require("../package.json");
15
+ async function main() {
16
+ // Load and validate config
17
+ const config = loadConfig();
18
+ const logger = createLogger(config);
19
+ // Initialize modules with config + logger
20
+ initSolana(config, logger);
21
+ initApiClient(config, logger);
22
+ initTokenResolver(logger);
23
+ initSwap(config);
24
+ // Validate keypair at startup
25
+ try {
26
+ loadKeypair(config.solanaKeypairPath);
27
+ }
28
+ catch (err) {
29
+ logger.fatal({ err }, "Invalid keypair file");
30
+ process.exit(1);
31
+ }
32
+ // Log config
33
+ const walletAddress = getWalletAddress();
34
+ logger.info({
35
+ wallet: walletAddress,
36
+ apiBaseUrl: config.apiBaseUrl,
37
+ rpcUrl: config.solanaRpcUrl,
38
+ hasApiKey: !!config.apiKey,
39
+ maxTradeSol: config.maxTradeSol,
40
+ version,
41
+ }, "Solana Trading MCP Server starting");
42
+ const server = new McpServer({
43
+ name: "kinetic-mcp",
44
+ version,
45
+ });
46
+ // --- Tool: get_wallet_balance ---
47
+ server.tool("get_wallet_balance", "Get SOL balance and all token balances for the connected wallet", {}, async () => {
48
+ return getWalletBalance();
49
+ });
50
+ // --- Tool: swap_tokens ---
51
+ server.tool("swap_tokens", "Swap one Solana token for another. IMPORTANT: Always call first with confirm=false to preview the quote, then call again with confirm=true and identical parameters to execute. Never set confirm=true without previewing first.", {
52
+ from_token: z.string().describe("Token to sell — symbol (e.g. 'SOL') or mint address"),
53
+ to_token: z.string().describe("Token to buy — symbol (e.g. 'BONK') or mint address"),
54
+ amount: z
55
+ .number()
56
+ .positive()
57
+ .describe("Amount of from_token to swap, in human units (e.g. 1.5 for 1.5 SOL)"),
58
+ slippage_bps: z
59
+ .number()
60
+ .int()
61
+ .min(1)
62
+ .max(1000)
63
+ .optional()
64
+ .describe("Slippage tolerance in basis points. Default 200 (2%). Max 1000 (10%)."),
65
+ confirm: z
66
+ .boolean()
67
+ .default(false)
68
+ .describe("false = preview quote only (always do this first); true = execute the swap with same parameters"),
69
+ }, async (params) => {
70
+ return swapTokens(params);
71
+ });
72
+ logger.info({ tools: ["get_wallet_balance", "swap_tokens"] }, "Tools registered");
73
+ // Graceful shutdown
74
+ const shutdown = () => {
75
+ logger.info("Shutting down...");
76
+ server.close();
77
+ process.exit(0);
78
+ };
79
+ process.on("SIGTERM", shutdown);
80
+ process.on("SIGINT", shutdown);
81
+ const transport = new StdioServerTransport();
82
+ await server.connect(transport);
83
+ logger.info("Server started");
84
+ }
85
+ main().catch((err) => {
86
+ // Can't use logger here — config may not have loaded
87
+ console.error("FATAL:", err);
88
+ process.exit(1);
89
+ });
90
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import pino from "pino";
2
+ export function createLogger(config) {
3
+ return pino({
4
+ level: config.logLevel,
5
+ redact: ["apiKey", "*.apiKey", "keypairPath", "*.keypairPath"],
6
+ }, pino.destination(2));
7
+ }
8
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,UAAU,YAAY,CAAC,MAAgC;IAC3D,OAAO,IAAI,CACT;QACE,KAAK,EAAE,MAAM,CAAC,QAAQ;QACtB,MAAM,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,CAAC;KAC/D,EACD,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,105 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import { TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID } from "@solana/spl-token";
3
+ import { getConnection, getWalletAddress } from "../utils/solana.js";
4
+ import { resolveTokenByMint } from "../utils/token-resolver.js";
5
+ import { formatError } from "../utils/errors.js";
6
+ async function fetchTokenAccounts(publicKey, programId) {
7
+ const connection = getConnection();
8
+ const result = await connection.getParsedTokenAccountsByOwner(publicKey, {
9
+ programId,
10
+ });
11
+ const accounts = [];
12
+ for (const item of result.value) {
13
+ const info = item.account.data.parsed.info;
14
+ const uiAmount = info.tokenAmount.uiAmount;
15
+ if (uiAmount && uiAmount > 0) {
16
+ accounts.push({
17
+ mint: info.mint,
18
+ amount: uiAmount,
19
+ decimals: info.tokenAmount.decimals,
20
+ });
21
+ }
22
+ }
23
+ return accounts;
24
+ }
25
+ export async function getWalletBalance() {
26
+ try {
27
+ const address = getWalletAddress();
28
+ const publicKey = new PublicKey(address);
29
+ const connection = getConnection();
30
+ // Fetch SOL balance
31
+ const lamports = await connection.getBalance(publicKey);
32
+ const solBalance = lamports / 1e9;
33
+ // Fetch SPL token accounts (both programs in parallel)
34
+ const [splAccounts, token2022Accounts] = await Promise.all([
35
+ fetchTokenAccounts(publicKey, TOKEN_PROGRAM_ID),
36
+ fetchTokenAccounts(publicKey, TOKEN_2022_PROGRAM_ID),
37
+ ]);
38
+ const allAccounts = [...splAccounts, ...token2022Accounts];
39
+ // Resolve token info
40
+ const tokens = [];
41
+ let unverifiedCount = 0;
42
+ for (const account of allAccounts) {
43
+ const tokenInfo = resolveTokenByMint(account.mint);
44
+ if (tokenInfo) {
45
+ tokens.push({
46
+ symbol: tokenInfo.symbol,
47
+ mint: account.mint,
48
+ amount: account.amount,
49
+ decimals: account.decimals,
50
+ });
51
+ }
52
+ else {
53
+ tokens.push({
54
+ symbol: account.mint.slice(0, 6) + "...",
55
+ mint: account.mint,
56
+ amount: account.amount,
57
+ decimals: account.decimals,
58
+ });
59
+ unverifiedCount++;
60
+ }
61
+ }
62
+ // Sort by amount (highest first)
63
+ tokens.sort((a, b) => b.amount - a.amount);
64
+ // Format output
65
+ const lines = [];
66
+ lines.push(`SOL: ${solBalance.toFixed(4)}`);
67
+ if (tokens.length === 0 && solBalance === 0) {
68
+ return {
69
+ content: [
70
+ {
71
+ type: "text",
72
+ text: `Wallet: ${address}\n\nYour wallet has 0 SOL and no token holdings.`,
73
+ },
74
+ ],
75
+ };
76
+ }
77
+ if (tokens.length > 0) {
78
+ lines.push("");
79
+ lines.push("Tokens:");
80
+ for (const token of tokens) {
81
+ const amountStr = token.amount >= 1
82
+ ? token.amount.toLocaleString("en-US", {
83
+ maximumFractionDigits: 4,
84
+ })
85
+ : token.amount.toPrecision(4);
86
+ lines.push(` ${token.symbol}: ${amountStr}`);
87
+ }
88
+ }
89
+ if (unverifiedCount > 0) {
90
+ lines.push(`\n ...and ${unverifiedCount} unverified token${unverifiedCount === 1 ? "" : "s"} with small balances`);
91
+ }
92
+ return {
93
+ content: [
94
+ {
95
+ type: "text",
96
+ text: `Wallet: ${address}\n\n${lines.join("\n")}`,
97
+ },
98
+ ],
99
+ };
100
+ }
101
+ catch (error) {
102
+ return formatError(error, "get_wallet_balance");
103
+ }
104
+ }
105
+ //# sourceMappingURL=balance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balance.js","sourceRoot":"","sources":["../../src/tools/balance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,154 @@
1
+ import { VersionedTransaction } from "@solana/web3.js";
2
+ import { resolveToken } from "../utils/token-resolver.js";
3
+ import { loadKeypair, SOL_MINT } from "../utils/solana.js";
4
+ import { toBaseUnits } from "../utils/math.js";
5
+ import { getQuote, buildSwapTransaction, sendTransaction } from "../utils/api-client.js";
6
+ import { formatError } from "../utils/errors.js";
7
+ let cfg;
8
+ export function initSwap(config) {
9
+ cfg = config;
10
+ }
11
+ async function checkTradeSize(amount, fromMint, fromSymbol, fromDecimals) {
12
+ if (fromMint === SOL_MINT) {
13
+ if (amount > cfg.maxTradeSol) {
14
+ return `Trade size (${amount} SOL) exceeds maximum of ${cfg.maxTradeSol} SOL.`;
15
+ }
16
+ return null;
17
+ }
18
+ // Use a Kinetic quote to convert token amount to SOL-equivalent
19
+ const baseUnits = Number(toBaseUnits(amount, fromDecimals));
20
+ try {
21
+ const quote = await getQuote({
22
+ inputToken: fromMint,
23
+ outputToken: SOL_MINT,
24
+ amount: baseUnits,
25
+ });
26
+ const solOutRaw = parseInt(quote.outAmount, 10);
27
+ if (Number.isNaN(solOutRaw)) {
28
+ return `Cannot verify trade size for ${fromSymbol}: invalid quote response. Trade blocked for safety.`;
29
+ }
30
+ const solEquiv = solOutRaw / 1e9; // SOL has 9 decimals
31
+ if (solEquiv > cfg.maxTradeSol) {
32
+ return `Trade size (${amount} ${fromSymbol} ≈ ${solEquiv.toFixed(2)} SOL) exceeds maximum of ${cfg.maxTradeSol} SOL.`;
33
+ }
34
+ }
35
+ catch (err) {
36
+ return `Cannot verify trade size for ${fromSymbol}: ${err instanceof Error ? err.message : "quote failed"}. Trade blocked for safety.`;
37
+ }
38
+ return null;
39
+ }
40
+ function formatStreamEvents(events) {
41
+ const lines = [];
42
+ for (const event of events) {
43
+ if ("error" in event) {
44
+ lines.push(`Error: ${event.error}`);
45
+ }
46
+ else if ("txHash" in event) {
47
+ lines.push(`Transaction: ${event.txHash}`);
48
+ lines.push(`Solscan: https://solscan.io/tx/${event.txHash}`);
49
+ }
50
+ else if ("walletTransactionInfo" in event) {
51
+ lines.push("Status: finalized");
52
+ }
53
+ else if ("status" in event) {
54
+ lines.push(`Status: ${event.status}`);
55
+ }
56
+ }
57
+ return lines.join("\n");
58
+ }
59
+ export async function swapTokens(params) {
60
+ try {
61
+ const { from_token, to_token, amount, confirm } = params;
62
+ const slippageBps = params.slippage_bps ?? 200;
63
+ // Resolve tokens
64
+ const fromToken = await resolveToken(from_token);
65
+ const toToken = await resolveToken(to_token);
66
+ // Safety check: trade size
67
+ const tradeSizeError = await checkTradeSize(amount, fromToken.mint, fromToken.symbol, fromToken.decimals);
68
+ if (tradeSizeError) {
69
+ return {
70
+ content: [{ type: "text", text: tradeSizeError }],
71
+ isError: true,
72
+ };
73
+ }
74
+ // Convert to base units (string-based to avoid floating-point precision loss)
75
+ const baseUnits = Number(toBaseUnits(amount, fromToken.decimals));
76
+ // Get quote from Kinetic
77
+ const quote = await getQuote({
78
+ inputToken: fromToken.mint,
79
+ outputToken: toToken.mint,
80
+ amount: baseUnits,
81
+ slippageBps,
82
+ });
83
+ // Calculate human-readable amounts
84
+ const outAmountRaw = parseInt(quote.outAmount, 10);
85
+ const minReceivedRaw = parseInt(quote.otherAmountThreshold, 10);
86
+ if (Number.isNaN(outAmountRaw) || Number.isNaN(minReceivedRaw)) {
87
+ throw new Error("Quote returned invalid amount values.");
88
+ }
89
+ const outAmount = outAmountRaw / Math.pow(10, toToken.decimals);
90
+ const minReceived = minReceivedRaw / Math.pow(10, toToken.decimals);
91
+ // Route description
92
+ const route = quote.routePlan.map((r) => r.swapInfo.label).join(" → ");
93
+ if (!confirm) {
94
+ const preview = [
95
+ "Swap Quote Preview",
96
+ "─".repeat(30),
97
+ `Input: ${amount} ${fromToken.symbol}`,
98
+ `Expected output: ${outAmount.toLocaleString("en-US", { maximumFractionDigits: 6 })} ${toToken.symbol}`,
99
+ `Minimum received (after slippage): ${minReceived.toLocaleString("en-US", { maximumFractionDigits: 6 })} ${toToken.symbol}`,
100
+ `Price impact: ${quote.priceImpactPct}%`,
101
+ `Route: ${route}`,
102
+ `Slippage tolerance: ${slippageBps} bps (${slippageBps / 100}%)`,
103
+ "",
104
+ "To execute this swap, call again with confirm=true and the same parameters.",
105
+ ].join("\n");
106
+ return { content: [{ type: "text", text: preview }] };
107
+ }
108
+ // Execute swap via Kinetic
109
+ const keypair = loadKeypair(cfg.solanaKeypairPath);
110
+ const walletAddress = keypair.publicKey.toBase58();
111
+ // Build swap transaction from the quote (pass user's slippage as dynamicSlippage.maxBps)
112
+ const { swapTransaction } = await buildSwapTransaction(walletAddress, quote, slippageBps);
113
+ // Deserialize and sign
114
+ const txBytes = Buffer.from(swapTransaction, "base64");
115
+ const transaction = VersionedTransaction.deserialize(txBytes);
116
+ transaction.sign([keypair]);
117
+ const signedBase64 = Buffer.from(transaction.serialize()).toString("base64");
118
+ // Send transaction via Kinetic
119
+ const events = await sendTransaction({
120
+ unsignedBase64: swapTransaction,
121
+ signedBase64,
122
+ walletAddress,
123
+ fromTokenAddress: fromToken.mint,
124
+ fromTokenAmount: baseUnits.toString(),
125
+ toTokenAddress: toToken.mint,
126
+ });
127
+ // Check for errors in stream
128
+ const errors = events.filter((e) => "error" in e);
129
+ if (errors.length > 0) {
130
+ return {
131
+ content: [
132
+ {
133
+ type: "text",
134
+ text: `Swap failed:\n${errors.map((e) => e.error).join("\n")}`,
135
+ },
136
+ ],
137
+ isError: true,
138
+ };
139
+ }
140
+ const result = [
141
+ "Swap Executed",
142
+ "─".repeat(30),
143
+ `Swapped: ${amount} ${fromToken.symbol} → ${outAmount.toLocaleString("en-US", { maximumFractionDigits: 6 })} ${toToken.symbol} (expected)`,
144
+ `Route: ${route}`,
145
+ "",
146
+ formatStreamEvents(events),
147
+ ].join("\n");
148
+ return { content: [{ type: "text", text: result }] };
149
+ }
150
+ catch (error) {
151
+ return formatError(error, "swap_tokens");
152
+ }
153
+ }
154
+ //# sourceMappingURL=swap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap.js","sourceRoot":"","sources":["../../src/tools/swap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ export const quoteResponseSchema = z.object({
3
+ inputMint: z.string(),
4
+ inAmount: z.string(),
5
+ outputMint: z.string(),
6
+ outAmount: z.string(),
7
+ otherAmountThreshold: z.string(),
8
+ swapMode: z.string().optional(),
9
+ slippageBps: z.number().optional(),
10
+ priceImpactPct: z.union([z.string(), z.number()]),
11
+ routePlan: z.array(z.object({
12
+ swapInfo: z.object({
13
+ ammKey: z.string(),
14
+ label: z.string().optional(),
15
+ inputMint: z.string(),
16
+ outputMint: z.string(),
17
+ inAmount: z.string(),
18
+ outAmount: z.string(),
19
+ feeAmount: z.string().optional(),
20
+ feeMint: z.string().optional(),
21
+ }),
22
+ percent: z.number(),
23
+ })),
24
+ apiVersion: z.string().optional(),
25
+ });
26
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/types/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,oBAAoB,EAAE,CAAC,CAAC,MAAM,EAAE;IAChC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IACjD,SAAS,EAAE,CAAC,CAAC,KAAK,CAChB,CAAC,CAAC,MAAM,CAAC;QACP,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;YACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;YAClB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC5B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;YACtB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;YACpB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAChC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SAC/B,CAAC;QACF,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;KACpB,CAAC,CACH;IACD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAC"}