Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: swap and bridge actions of plugin-evm #1456

Merged
merged 2 commits into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading