diff --git a/packages/plugin-evm/src/actions/bridge.ts b/packages/plugin-evm/src/actions/bridge.ts index 811b9cdfc2..5683f814b3 100644 --- a/packages/plugin-evm/src/actions/bridge.ts +++ b/packages/plugin-evm/src/actions/bridge.ts @@ -1,13 +1,20 @@ import type { IAgentRuntime, Memory, State } from "@elizaos/core"; +import { + composeContext, + generateObjectDeprecated, + ModelClass, +} from "@elizaos/core"; import { createConfig, executeRoute, ExtendedChain, getRoutes, } from "@lifi/sdk"; -import { WalletProvider } from "../providers/wallet"; + +import { initWalletProvider, WalletProvider } from "../providers/wallet"; import { bridgeTemplate } from "../templates"; import type { BridgeParams, Transaction } from "../types"; +import { parseEther } from "viem"; export { bridgeTemplate }; @@ -54,7 +61,7 @@ export class BridgeAction { toChainId: this.walletProvider.getChainConfigs(params.toChain).id, fromTokenAddress: params.fromToken, toTokenAddress: params.toToken, - fromAmount: params.amount, + fromAmount: parseEther(params.amount).toString(), fromAddress: fromAddress, toAddress: params.toAddress || fromAddress, }); @@ -84,16 +91,56 @@ export const bridgeAction = { description: "Bridge tokens between different chains", handler: async ( runtime: IAgentRuntime, - message: Memory, + _message: Memory, state: State, - options: any + _options: any, + callback?: any ) => { - const privateKey = runtime.getSetting( - "EVM_PRIVATE_KEY" - ) as `0x${string}`; - const walletProvider = new WalletProvider(privateKey); + console.log("Bridge action handler called"); + const walletProvider = initWalletProvider(runtime); const action = new BridgeAction(walletProvider); - return action.bridge(options); + + // Compose bridge context + const bridgeContext = composeContext({ + state, + template: bridgeTemplate, + }); + const content = await generateObjectDeprecated({ + runtime, + context: bridgeContext, + modelClass: ModelClass.LARGE, + }); + + const bridgeOptions: BridgeParams = { + fromChain: content.fromChain, + toChain: content.toChain, + fromToken: content.token, + toToken: content.token, + toAddress: content.toAddress, + amount: content.amount, + }; + + try { + const bridgeResp = await action.bridge(bridgeOptions); + if (callback) { + callback({ + text: `Successfully bridge ${bridgeOptions.amount} ${bridgeOptions.fromToken} tokens from ${bridgeOptions.fromChain} to ${bridgeOptions.toChain}\nTransaction Hash: ${bridgeResp.hash}`, + content: { + success: true, + hash: bridgeResp.hash, + recipient: bridgeResp.to, + chain: bridgeOptions.fromChain, + }, + }); + } + return true; + } catch (error) { + console.error("Error in bridge handler:", error.message); + if (callback) { + callback({ text: `Error: ${error.message}` }); + } + return false; + } }, template: bridgeTemplate, validate: async (runtime: IAgentRuntime) => { diff --git a/packages/plugin-evm/src/actions/swap.ts b/packages/plugin-evm/src/actions/swap.ts index 2a5ef88c86..718be7edb9 100644 --- a/packages/plugin-evm/src/actions/swap.ts +++ b/packages/plugin-evm/src/actions/swap.ts @@ -1,13 +1,20 @@ import type { IAgentRuntime, Memory, State } from "@elizaos/core"; +import { + composeContext, + generateObjectDeprecated, + ModelClass, +} from "@elizaos/core"; import { createConfig, executeRoute, ExtendedChain, getRoutes, } from "@lifi/sdk"; -import { WalletProvider } from "../providers/wallet"; + +import { initWalletProvider, WalletProvider } from "../providers/wallet"; import { swapTemplate } from "../templates"; import type { SwapParams, Transaction } from "../types"; +import { parseEther } from "viem"; export { swapTemplate }; @@ -60,7 +67,7 @@ export class SwapAction { toChainId: this.walletProvider.getChainConfigs(params.chain).id, fromTokenAddress: params.fromToken, toTokenAddress: params.toToken, - fromAmount: params.amount, + fromAmount: parseEther(params.amount).toString(), fromAddress: fromAddress, options: { slippage: params.slippage || 0.5, @@ -82,7 +89,7 @@ export class SwapAction { from: fromAddress, to: routes.routes[0].steps[0].estimate .approvalAddress as `0x${string}`, - value: BigInt(params.amount), + value: 0n, data: process.data as `0x${string}`, chainId: this.walletProvider.getChainConfigs(params.chain).id, }; @@ -94,18 +101,48 @@ export const swapAction = { description: "Swap tokens on the same chain", handler: async ( runtime: IAgentRuntime, - message: Memory, + _message: Memory, state: State, - options: any, + _options: any, callback?: any ) => { + console.log("Swap action handler called"); + const walletProvider = initWalletProvider(runtime); + const action = new SwapAction(walletProvider); + + // Compose swap context + const swapContext = composeContext({ + state, + template: swapTemplate, + }); + const content = await generateObjectDeprecated({ + runtime, + context: swapContext, + modelClass: ModelClass.LARGE, + }); + + const swapOptions: SwapParams = { + chain: content.chain, + fromToken: content.inputToken, + toToken: content.outputToken, + amount: content.amount, + slippage: content.slippage, + }; + try { - const privateKey = runtime.getSetting( - "EVM_PRIVATE_KEY" - ) as `0x${string}`; - const walletProvider = new WalletProvider(privateKey); - const action = new SwapAction(walletProvider); - return await action.swap(options); + const swapResp = await action.swap(swapOptions); + if (callback) { + callback({ + text: `Successfully swap ${swapOptions.amount} ${swapOptions.fromToken} tokens to ${swapOptions.toToken}\nTransaction Hash: ${swapResp.hash}`, + content: { + success: true, + hash: swapResp.hash, + recipient: swapResp.to, + chain: content.chain, + }, + }); + } + return true; } catch (error) { console.error("Error in swap handler:", error.message); if (callback) { diff --git a/packages/plugin-evm/src/templates/index.ts b/packages/plugin-evm/src/templates/index.ts index d4dea3f9d2..18b440f2ce 100644 --- a/packages/plugin-evm/src/templates/index.ts +++ b/packages/plugin-evm/src/templates/index.ts @@ -32,7 +32,7 @@ Extract the following information about the requested token bridge: - Token symbol or address to bridge - Source chain - Destination chain -- Amount to bridge +- Amount to bridge: Must be a string representing the amount in ether (only number without coin symbol, e.g., "0.1") - Destination address (if specified) Respond with a JSON markdown block containing only the extracted values: @@ -57,7 +57,7 @@ export const swapTemplate = `Given the recent messages and wallet information be Extract the following information about the requested token swap: - Input token symbol or address (the token being sold) - Output token symbol or address (the token being bought) -- Amount to swap +- Amount to swap: Must be a string representing the amount in ether (only number without coin symbol, e.g., "0.1") - Chain to execute on Respond with a JSON markdown block containing only the extracted values. Use null for any values that cannot be determined: