diff --git a/packages/plugin-evm/src/actions/transfer.ts b/packages/plugin-evm/src/actions/transfer.ts index bf1f57bfab..61b2bacbbe 100644 --- a/packages/plugin-evm/src/actions/transfer.ts +++ b/packages/plugin-evm/src/actions/transfer.ts @@ -14,6 +14,8 @@ import type { Transaction, TransferParams } from "../types"; import { transferTemplate } from "../templates"; export { transferTemplate }; + +// Exported for tests export class TransferAction { constructor(private walletProvider: WalletProvider) {} @@ -22,6 +24,12 @@ export class TransferAction { `Transferring: ${params.amount} tokens to (${params.toAddress} on ${params.fromChain})` ); + if (!params.data) { + params.data = "0x"; + } + + await this.walletProvider.switchChain(params.fromChain); + const walletClient = this.walletProvider.getWalletClient( params.fromChain ); @@ -106,29 +114,44 @@ export const transferAction = { options: any, callback?: HandlerCallback ) => { - try { - const walletProvider = initWalletProvider(runtime); - const action = new TransferAction(walletProvider); - const transferDetails = await buildTransferDetails( - state, - runtime, - walletProvider - ); - const tx = await action.transfer(transferDetails); + console.log("Transfer action handler called"); + const walletProvider = initWalletProvider(runtime); + const action = new TransferAction(walletProvider); + + // Compose transfer context + const transferContext = composeContext({ + state, + template: transferTemplate, + }); + + // Generate transfer content + const content = await generateObjectDeprecated({ + runtime, + context: transferContext, + modelClass: ModelClass.LARGE, + }); + + const paramOptions: TransferParams = { + fromChain: content.fromChain, + toAddress: content.toAddress, + amount: content.amount, + data: content.data, + }; + try { + const transferResp = await action.transfer(paramOptions); if (callback) { callback({ - text: `Successfully transferred ${formatEther(tx.value)} tokens to ${tx.to}\nTransaction hash: ${tx.hash}\nChain: ${transferDetails.fromChain}`, + text: `Successfully transferred ${paramOptions.amount} tokens to ${paramOptions.toAddress}\nTransaction Hash: ${transferResp.hash}`, content: { success: true, - hash: tx.hash, - amount: formatEther(tx.value), - recipient: tx.to, - chain: transferDetails.fromChain, + hash: transferResp.hash, + amount: formatEther(transferResp.value), + recipient: transferResp.to, + chain: content.fromChain, }, }); } - return true; } catch (error) { console.error("Error during token transfer:", error); diff --git a/packages/plugin-evm/src/templates/index.ts b/packages/plugin-evm/src/templates/index.ts index 20d6ef19af..68c6be91d7 100644 --- a/packages/plugin-evm/src/templates/index.ts +++ b/packages/plugin-evm/src/templates/index.ts @@ -5,17 +5,19 @@ export const transferTemplate = `Given the recent messages and wallet informatio {{walletInfo}} Extract the following information about the requested transfer: -- Chain to execute on (like in viem/chains) -- Amount to transfer (only number without coin symbol) -- Recipient address +- Chain to execute on: Must be one of ["ethereum", "base", ...] (like in viem/chains) +- Amount to transfer: Must be a string representing the amount in ETH (only number without coin symbol, e.g., "0.1") +- Recipient address: Must be a valid Ethereum address starting with "0x" +- Token symbol or address (if not native token): Optional, leave as null for ETH transfers -Respond with a JSON markdown block containing only the extracted values: +Respond with a JSON markdown block containing only the extracted values. All fields except 'token' are required: \`\`\`json { "fromChain": SUPPORTED_CHAINS, "amount": string, - "toAddress": string + "toAddress": string, + "token": string | null } \`\`\` `;