stake_msol
Stake SOL tokens to receive mSOL tokens and earn staking rewards through Marinade Finance's liquid staking protocol on Solana.
Instructions
Stake your SOL tokens with Marinade Finance to receive mSOL tokens and earn rewards.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| amount | Yes | The amount of SOL to stake |
Implementation Reference
- src/tools.ts:308-391 (handler)The handler function (callback) for the stake_msol tool. It converts SOL amount to lamports, checks wallet balance, creates a Marinade instance, deposits SOL to receive mSOL, sends and confirms the transaction, and returns success or error details.callback: async ({ amount }: { amount: number }) => { try { const amountLamports = MarinadeUtils.solToLamports(amount); const { wallet, connection } = createSolanaConfig() const balance = await connection.getBalance(wallet.publicKey); if (balance < amountLamports) { return { content: [ { type: "text", text: JSON.stringify({ error: "Insufficient balance", reason: `Required: ${amount} SOL (${amountLamports} lamports), Available: ${balance / LAMPORTS_PER_SOL} SOL (${balance} lamports)` }, null, 2), }, ], }; } const config = new MarinadeConfig({ connection, publicKey: wallet.publicKey, }) const marinade = new Marinade(config) const { associatedMSolTokenAccountAddress, transaction, } = await marinade.deposit(amountLamports, { mintToOwnerAddress: wallet.publicKey, }) const signature = await sendAndConfirmTransaction(connection, transaction, [wallet], { commitment: "confirmed", preflightCommitment: "processed", skipPreflight: false, maxRetries: 3, }) return { content: [ { type: "text", text: JSON.stringify({ success: true, signature, mSolTokenAccount: associatedMSolTokenAccountAddress, amountStaked: amount, amountStakedLamports: amountLamports.toString(), explorerUrl: `https://solscan.io/tx/${signature}${process.env.ENVIRONMENT === 'MAINNET' ? '' : '?cluster=devnet'}` }, null, 2), }, ], }; } catch (err) { const isAbort = (err as Error)?.name === "AbortError"; const isTimeout = (err as Error)?.message?.includes("timeout"); McpLogger.error("Error in stake_msol tool:", String(err)); return { content: [ { type: "text", text: JSON.stringify( { error: isAbort || isTimeout ? "Request timed out" : "Failed to stake SOL", reason: String((err as Error)?.message ?? err), suggestion: isAbort || isTimeout ? "The transaction may still be processing. Check your wallet or try again with a different RPC endpoint." : "Please check your wallet balance and network connection." }, null, 2 ), }, ], }; } }
- src/tools.ts:305-307 (schema)Input schema definition for the stake_msol tool using Zod, specifying the 'amount' parameter as a non-negative number representing SOL to stake.inputSchema: { amount: z.number().min(0).describe("The amount of SOL to stake"), },
- src/server.ts:24-43 (registration)Generic registration loop in the MCP server that registers the stake_msol tool (and others) from the marinadeFinanceTools array using server.registerTool with the tool's name, metadata, schema, and a wrapper around its callback.for (const t of marinadeFinanceTools) { server.registerTool( t.name, { title: t.title, description: t.description, inputSchema: t.inputSchema }, async (args) => { const result = await t.callback(args); return { content: result.content.map(item => ({ ...item, type: "text" as const })) }; } ); }