Skip to content

Commit

Permalink
fix: swap and bridge actions of plugin-evm
Browse files Browse the repository at this point in the history
  • Loading branch information
pythonberg1997 committed Dec 27, 2024
1 parent c9be71e commit 563f2f0
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 22 deletions.
65 changes: 56 additions & 9 deletions packages/plugin-evm/src/actions/bridge.ts
Original file line number Diff line number Diff line change
@@ -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 };

Expand Down Expand Up @@ -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,
});
Expand Down Expand Up @@ -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) => {
Expand Down
59 changes: 48 additions & 11 deletions packages/plugin-evm/src/actions/swap.ts
Original file line number Diff line number Diff line change
@@ -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 };

Expand Down Expand Up @@ -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,
Expand All @@ -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,
};
Expand All @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-evm/src/templates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down

0 comments on commit 563f2f0

Please sign in to comment.