stake_msol
Stake SOL tokens to receive mSOL 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 callback function that implements the stake_msol tool logic: validates balance, creates Marinade instance, calls deposit, sends transaction, and handles errors.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)Zod schema for the input parameter 'amount' of SOL to stake.inputSchema: { amount: z.number().min(0).describe("The amount of SOL to stake"), },
- src/tools.ts:302-392 (registration)The stake_msol tool object definition and registration within the onChainTools array.name: "stake_msol", title: "Stake SOL for mSOL", description: "Stake your SOL tokens with Marinade Finance to receive mSOL tokens and earn rewards.", inputSchema: { amount: z.number().min(0).describe("The amount of SOL to stake"), }, 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 ), }, ], }; } } },