Skip to content

Commit ab20cad

Browse files
committed
fix: error logging and remove unused import
1 parent 60628ef commit ab20cad

File tree

1 file changed

+155
-82
lines changed
  • packages/plugin-evm/src/actions

1 file changed

+155
-82
lines changed

packages/plugin-evm/src/actions/swap.ts

+155-82
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
composeContext,
44
generateObjectDeprecated,
55
ModelClass,
6+
elizaLogger,
67
} from "@elizaos/core";
78
import {
89
createConfig,
@@ -15,8 +16,15 @@ import {
1516
import { initWalletProvider, WalletProvider } from "../providers/wallet";
1617
import { swapTemplate } from "../templates";
1718
import type { SwapParams, SwapQuote, Transaction } from "../types";
18-
import { Address, ByteArray, encodeFunctionData, Hex, parseAbi, parseEther, parseUnits } from "viem";
19-
import { BebopRoute } from '../types/index';
19+
import {
20+
Address,
21+
ByteArray,
22+
encodeFunctionData,
23+
Hex,
24+
parseAbi,
25+
parseUnits,
26+
} from "viem";
27+
import { BebopRoute } from "../types/index";
2028

2129
export { swapTemplate };
2230

@@ -26,7 +34,7 @@ export class SwapAction {
2634

2735
constructor(private walletProvider: WalletProvider) {
2836
this.walletProvider = walletProvider;
29-
let lifiChains: ExtendedChain[] = [];
37+
const lifiChains: ExtendedChain[] = [];
3038
for (const config of Object.values(this.walletProvider.chains)) {
3139
try {
3240
lifiChains.push({
@@ -58,27 +66,31 @@ export class SwapAction {
5866
},
5967
coin: config.nativeCurrency.symbol,
6068
mainnet: true,
61-
diamondAddress: "0x0000000000000000000000000000000000000000",
69+
diamondAddress:
70+
"0x0000000000000000000000000000000000000000",
6271
} as ExtendedChain);
6372
} catch {
6473
// Skip chains with missing config in viem
6574
}
6675
}
6776
this.lifiConfig = createConfig({
6877
integrator: "eliza",
69-
chains: lifiChains
70-
})
78+
chains: lifiChains,
79+
});
7180
this.bebopChainsMap = {
72-
'mainnet': 'ethereum'
73-
}
81+
mainnet: "ethereum",
82+
};
7483
}
7584

7685
async swap(params: SwapParams): Promise<Transaction> {
7786
const walletClient = this.walletProvider.getWalletClient(params.chain);
7887
const [fromAddress] = await walletClient.getAddresses();
7988

8089
// Getting quotes from different aggregators and sorting them by minAmount (amount after slippage)
81-
const sortedQuotes: SwapQuote[] = await this.getSortedQuotes(fromAddress, params);
90+
const sortedQuotes: SwapQuote[] = await this.getSortedQuotes(
91+
fromAddress,
92+
params
93+
);
8294

8395
// Trying to execute the best quote by amount, fallback to the next one if it fails
8496
for (const quote of sortedQuotes) {
@@ -89,7 +101,7 @@ export class SwapAction {
89101
break;
90102
case "bebop":
91103
res = await this.executeBebopQuote(quote, params);
92-
break
104+
break;
93105
default:
94106
throw new Error("No aggregator found");
95107
}
@@ -98,31 +110,50 @@ export class SwapAction {
98110
throw new Error("Execution failed");
99111
}
100112

101-
private async getSortedQuotes(fromAddress: Address, params: SwapParams): Promise<SwapQuote[]> {
102-
const decimalsAbi = parseAbi(['function decimals() view returns (uint8)']);
103-
const decimals = await this.walletProvider.getPublicClient(params.chain).readContract({
104-
address: params.fromToken,
105-
abi: decimalsAbi,
106-
functionName: 'decimals',
107-
});
113+
private async getSortedQuotes(
114+
fromAddress: Address,
115+
params: SwapParams
116+
): Promise<SwapQuote[]> {
117+
const decimalsAbi = parseAbi([
118+
"function decimals() view returns (uint8)",
119+
]);
120+
const decimals = await this.walletProvider
121+
.getPublicClient(params.chain)
122+
.readContract({
123+
address: params.fromToken,
124+
abi: decimalsAbi,
125+
functionName: "decimals",
126+
});
108127
const quotes: SwapQuote[] | undefined = await Promise.all([
109128
this.getLifiQuote(fromAddress, params, decimals),
110-
this.getBebopQuote(fromAddress, params, decimals)
129+
this.getBebopQuote(fromAddress, params, decimals),
111130
]);
112-
const sortedQuotes: SwapQuote[] = quotes.filter((quote) => quote !== undefined) as SwapQuote[];
113-
sortedQuotes.sort((a, b) => BigInt(a.minOutputAmount) > BigInt(b.minOutputAmount) ? -1 : 1);
131+
const sortedQuotes: SwapQuote[] = quotes.filter(
132+
(quote) => quote !== undefined
133+
) as SwapQuote[];
134+
sortedQuotes.sort((a, b) =>
135+
BigInt(a.minOutputAmount) > BigInt(b.minOutputAmount) ? -1 : 1
136+
);
114137
if (sortedQuotes.length === 0) throw new Error("No routes found");
115138
return sortedQuotes;
116139
}
117140

118-
private async getLifiQuote(fromAddress: Address, params: SwapParams, fromTokenDecimals: number): Promise<SwapQuote | undefined> {
141+
private async getLifiQuote(
142+
fromAddress: Address,
143+
params: SwapParams,
144+
fromTokenDecimals: number
145+
): Promise<SwapQuote | undefined> {
119146
try {
120147
const routes = await getRoutes({
121-
fromChainId: this.walletProvider.getChainConfigs(params.chain).id,
148+
fromChainId: this.walletProvider.getChainConfigs(params.chain)
149+
.id,
122150
toChainId: this.walletProvider.getChainConfigs(params.chain).id,
123151
fromTokenAddress: params.fromToken,
124152
toTokenAddress: params.toToken,
125-
fromAmount: parseUnits(params.amount, fromTokenDecimals).toString(),
153+
fromAmount: parseUnits(
154+
params.amount,
155+
fromTokenDecimals
156+
).toString(),
126157
fromAddress: fromAddress,
127158
options: {
128159
slippage: params.slippage / 100 || 0.005,
@@ -133,61 +164,79 @@ export class SwapAction {
133164
return {
134165
aggregator: "lifi",
135166
minOutputAmount: routes.routes[0].steps[0].estimate.toAmountMin,
136-
swapData: routes.routes[0]
137-
}
167+
swapData: routes.routes[0],
168+
};
138169
} catch (error) {
139170
console.debug("Error in getLifiQuote:", error.message);
140171
return undefined;
141172
}
142173
}
143174

144-
private async getBebopQuote(fromAddress: Address, params: SwapParams, fromTokenDecimals: number): Promise<SwapQuote | undefined> {
175+
private async getBebopQuote(
176+
fromAddress: Address,
177+
params: SwapParams,
178+
fromTokenDecimals: number
179+
): Promise<SwapQuote | undefined> {
145180
try {
146181
const url = `https://api.bebop.xyz/router/${this.bebopChainsMap[params.chain] ?? params.chain}/v1/quote`;
147182
const reqParams = new URLSearchParams({
148183
sell_tokens: params.fromToken,
149184
buy_tokens: params.toToken,
150-
sell_amounts: parseUnits(params.amount, fromTokenDecimals).toString(),
185+
sell_amounts: parseUnits(
186+
params.amount,
187+
fromTokenDecimals
188+
).toString(),
151189
taker_address: fromAddress,
152-
approval_type: 'Standard',
153-
skip_validation: 'true',
154-
gasless: 'false',
155-
source: 'eliza'
190+
approval_type: "Standard",
191+
skip_validation: "true",
192+
gasless: "false",
193+
source: "eliza",
156194
});
157195
const response = await fetch(`${url}?${reqParams.toString()}`, {
158-
method: 'GET',
159-
headers: {'accept': 'application/json'},
196+
method: "GET",
197+
headers: { accept: "application/json" },
160198
});
161199
if (!response.ok) {
162200
throw Error(response.statusText);
163201
}
164202
const data = await response.json();
165203
const route: BebopRoute = {
166204
data: data.routes[0].quote.tx.data,
167-
sellAmount: parseUnits(params.amount, fromTokenDecimals).toString(),
168-
approvalTarget: data.routes[0].quote.approvalTarget as `0x${string}`,
205+
sellAmount: parseUnits(
206+
params.amount,
207+
fromTokenDecimals
208+
).toString(),
209+
approvalTarget: data.routes[0].quote
210+
.approvalTarget as `0x${string}`,
169211
from: data.routes[0].quote.tx.from as `0x${string}`,
170212
value: data.routes[0].quote.tx.value.toString(),
171213
to: data.routes[0].quote.tx.to as `0x${string}`,
172214
gas: data.routes[0].quote.tx.gas.toString(),
173-
gasPrice: data.routes[0].quote.tx.gasPrice.toString()
174-
}
215+
gasPrice: data.routes[0].quote.tx.gasPrice.toString(),
216+
};
175217
return {
176218
aggregator: "bebop",
177-
minOutputAmount: data.routes[0].quote.buyTokens[params.toToken].minimumAmount.toString(),
178-
swapData: route
179-
}
180-
219+
minOutputAmount:
220+
data.routes[0].quote.buyTokens[
221+
params.toToken
222+
].minimumAmount.toString(),
223+
swapData: route,
224+
};
181225
} catch (error) {
182226
console.debug("Error in getBebopQuote:", error.message);
183227
return undefined;
184228
}
185229
}
186230

187-
private async executeLifiQuote(quote: SwapQuote): Promise<Transaction | undefined> {
231+
private async executeLifiQuote(
232+
quote: SwapQuote
233+
): Promise<Transaction | undefined> {
188234
try {
189235
const route: Route = quote.swapData as Route;
190-
const execution = await executeRoute(quote.swapData as Route, this.lifiConfig);
236+
const execution = await executeRoute(
237+
quote.swapData as Route,
238+
this.lifiConfig
239+
);
191240
const process = execution.steps[0]?.execution?.process[0];
192241

193242
if (!process?.status || process.status === "FAILED") {
@@ -199,36 +248,77 @@ export class SwapAction {
199248
to: route.steps[0].estimate.approvalAddress as `0x${string}`,
200249
value: 0n,
201250
data: process.data as `0x${string}`,
202-
chainId: route.fromChainId
203-
}
251+
chainId: route.fromChainId,
252+
};
204253
} catch (error) {
254+
elizaLogger.error(`Failed to execute lifi quote: ${error}`);
205255
return undefined;
206256
}
207257
}
208258

209-
private async executeBebopQuote(quote: SwapQuote, params: SwapParams): Promise<Transaction | undefined> {
259+
private async executeBebopQuote(
260+
quote: SwapQuote,
261+
params: SwapParams
262+
): Promise<Transaction | undefined> {
210263
try {
211264
const bebopRoute: BebopRoute = quote.swapData as BebopRoute;
212-
const allowanceAbi = parseAbi(['function allowance(address,address) view returns (uint256)']);
213-
const allowance: bigint = await this.walletProvider.getPublicClient(params.chain).readContract({
214-
address: params.fromToken,
215-
abi: allowanceAbi,
216-
functionName: 'allowance',
217-
args: [bebopRoute.from, bebopRoute.approvalTarget]
218-
});
265+
const allowanceAbi = parseAbi([
266+
"function allowance(address,address) view returns (uint256)",
267+
]);
268+
const allowance: bigint = await this.walletProvider
269+
.getPublicClient(params.chain)
270+
.readContract({
271+
address: params.fromToken,
272+
abi: allowanceAbi,
273+
functionName: "allowance",
274+
args: [bebopRoute.from, bebopRoute.approvalTarget],
275+
});
219276
if (allowance < BigInt(bebopRoute.sellAmount)) {
220277
const approvalData = encodeFunctionData({
221-
abi: parseAbi(['function approve(address,uint256)']),
222-
functionName: 'approve',
223-
args: [bebopRoute.approvalTarget, BigInt(bebopRoute.sellAmount)],
278+
abi: parseAbi(["function approve(address,uint256)"]),
279+
functionName: "approve",
280+
args: [
281+
bebopRoute.approvalTarget,
282+
BigInt(bebopRoute.sellAmount),
283+
],
224284
});
225-
await this.walletProvider.getWalletClient(params.chain).sendTransaction({
226-
account: this.walletProvider.getWalletClient(params.chain).account,
227-
to: params.fromToken,
228-
value: 0n,
229-
data: approvalData,
285+
await this.walletProvider
286+
.getWalletClient(params.chain)
287+
.sendTransaction({
288+
account: this.walletProvider.getWalletClient(
289+
params.chain
290+
).account,
291+
to: params.fromToken,
292+
value: 0n,
293+
data: approvalData,
294+
kzg: {
295+
blobToKzgCommitment: function (
296+
_: ByteArray
297+
): ByteArray {
298+
throw new Error("Function not implemented.");
299+
},
300+
computeBlobKzgProof: function (
301+
_blob: ByteArray,
302+
_commitment: ByteArray
303+
): ByteArray {
304+
throw new Error("Function not implemented.");
305+
},
306+
},
307+
chain: undefined,
308+
});
309+
}
310+
const hash = await this.walletProvider
311+
.getWalletClient(params.chain)
312+
.sendTransaction({
313+
account: this.walletProvider.getWalletClient(params.chain)
314+
.account,
315+
to: bebopRoute.to,
316+
value: BigInt(bebopRoute.value),
317+
data: bebopRoute.data as Hex,
230318
kzg: {
231-
blobToKzgCommitment: function (_: ByteArray): ByteArray {
319+
blobToKzgCommitment: function (
320+
_: ByteArray
321+
): ByteArray {
232322
throw new Error("Function not implemented.");
233323
},
234324
computeBlobKzgProof: function (
@@ -240,33 +330,16 @@ export class SwapAction {
240330
},
241331
chain: undefined,
242332
});
243-
}
244-
const hash = await this.walletProvider.getWalletClient(params.chain).sendTransaction({
245-
account: this.walletProvider.getWalletClient(params.chain).account,
246-
to: bebopRoute.to,
247-
value: BigInt(bebopRoute.value),
248-
data: bebopRoute.data as Hex,
249-
kzg: {
250-
blobToKzgCommitment: function (_: ByteArray): ByteArray {
251-
throw new Error("Function not implemented.");
252-
},
253-
computeBlobKzgProof: function (
254-
_blob: ByteArray,
255-
_commitment: ByteArray
256-
): ByteArray {
257-
throw new Error("Function not implemented.");
258-
},
259-
},
260-
chain: undefined,
261-
});
262333
return {
263334
hash,
264-
from: this.walletProvider.getWalletClient(params.chain).account.address,
335+
from: this.walletProvider.getWalletClient(params.chain).account
336+
.address,
265337
to: bebopRoute.to,
266338
value: BigInt(bebopRoute.value),
267339
data: bebopRoute.data as Hex,
268340
};
269341
} catch (error) {
342+
elizaLogger.error(`Failed to execute bebop quote: ${error}`);
270343
return undefined;
271344
}
272345
}

0 commit comments

Comments
 (0)