transferCoin.ts•5.14 kB
import { Tool } from "@modelcontextprotocol/sdk/types.js";
import { getAptosClient } from "../../config.js";
import { getDefaultAccount } from "../../utils/account.js";
import { formatAddress } from "../../utils/format.js";
export const TRANSFER_COIN: Tool = {
name: "transfer_coin",
description: "Transfer a specific coin type to another Aptos account. This is used for sending custom coins or tokens from your account to another address. Returns the transaction hash upon successful transfer.",
inputSchema: {
type: "object",
properties: {
recipient_address: {
type: "string",
description: "Recipient Aptos address, e.g., 0x1 or 0x742d35Cc6634C0532925a3b8D6Ac0C4db9c8b3",
},
coin_type: {
type: "string",
description: "Coin type identifier, e.g., '0x1::aptos_coin::AptosCoin' or custom coin type",
},
amount: {
type: "string",
description: "Amount of coins to transfer (in smallest unit)",
},
max_gas_amount: {
type: "number",
description: "Maximum gas amount for the transaction (optional)",
default: 2000,
},
},
required: ["recipient_address", "coin_type", "amount"],
},
};
/**
* Transfers a specific coin type to another account
* @param args The arguments containing recipient address, coin type, and amount
* @returns The transfer transaction details
*/
export async function transferCoinHandler(args: Record<string, any> | undefined) {
if (!isTransferCoinArgs(args)) {
throw new Error("Invalid arguments for transfer_coin");
}
const { recipient_address, coin_type, amount, max_gas_amount = 2000 } = args;
try {
const results = await performTransferCoin(recipient_address, coin_type, amount, max_gas_amount);
return {
content: [{ type: "text", text: results }],
isError: false,
};
} catch (error) {
return {
content: [
{
type: "text",
text: `Error transferring coin: ${error instanceof Error ? error.message : String(error)}`,
},
],
isError: true,
};
}
}
/**
* Transfers a specific coin type to another account
* @param recipientAddress The recipient's Aptos address
* @param coinType The coin type identifier
* @param amount The amount of coins to transfer
* @param maxGasAmount Maximum gas amount for the transaction
* @returns The transfer transaction details as a formatted string
*/
export async function performTransferCoin(
recipientAddress: string,
coinType: string,
amount: string,
maxGasAmount: number = 2000
): Promise<string> {
try {
const aptos = getAptosClient();
const senderAccount = getDefaultAccount();
// Build the coin transfer transaction
const transaction = await aptos.transaction.build.simple({
sender: senderAccount.accountAddress,
data: {
function: "0x1::aptos_account::transfer_coins",
typeArguments: [coinType],
functionArguments: [recipientAddress, amount],
},
options: {
maxGasAmount,
},
});
// Sign and submit the transaction
const committedTxn = await aptos.signAndSubmitTransaction({
signer: senderAccount,
transaction,
});
// Wait for transaction confirmation
const executedTxn = await aptos.waitForTransaction({
transactionHash: committedTxn.hash,
});
return `Coin Transfer Successful:
From: ${formatAddress(senderAccount.accountAddress.toString())}
To: ${formatAddress(recipientAddress)}
Coin Type: ${coinType}
Amount: ${amount}
Transaction Hash: ${committedTxn.hash}
Gas Used: ${executedTxn.gas_used}
Status: ${executedTxn.success ? 'Success' : 'Failed'}
✅ Transfer completed successfully!`;
} catch (error) {
console.error('Error transferring coin:', error);
if (error instanceof Error) {
if (error.message.includes('insufficient')) {
throw new Error("Insufficient coin balance to complete the transfer");
}
if (error.message.includes('invalid')) {
throw new Error("Invalid recipient address or coin type format");
}
if (error.message.includes('not registered')) {
throw new Error("Recipient account is not registered for this coin type");
}
}
throw new Error(`Failed to transfer coin: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Checks if the provided arguments are valid for the transferCoin tool
* @param args The arguments to check
* @returns True if the arguments are valid, false otherwise
*/
export function isTransferCoinArgs(args: unknown): args is {
recipient_address: string;
coin_type: string;
amount: string;
max_gas_amount?: number
} {
return (
typeof args === "object" &&
args !== null &&
"recipient_address" in args &&
typeof (args as any).recipient_address === "string" &&
"coin_type" in args &&
typeof (args as any).coin_type === "string" &&
"amount" in args &&
typeof (args as any).amount === "string" &&
(!(args as any).max_gas_amount || typeof (args as any).max_gas_amount === "number")
);
}