@agentek/tools
Version:
Blockchain tools for AI agents
133 lines • 5.22 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.intentDepositAcross = void 0;
const client_js_1 = require("../client.js");
const zod_1 = require("zod");
const chains_1 = require("viem/chains");
const viem_1 = require("viem");
const constants_js_1 = require("./constants.js");
const tools_js_1 = require("./tools.js");
const supportedChains = [chains_1.mainnet, chains_1.polygon, chains_1.arbitrum, chains_1.optimism, chains_1.base];
function getAcrossSpokePoolAddress(chainId) {
const address = constants_js_1.ACROSS_SPOKE_POOL_ADDRESS[chainId];
if (!address) {
throw new Error(`Across SpokePool address not found for chain ID ${chainId}`);
}
return address.toLowerCase();
}
// @TODO Make it work with Ether
exports.intentDepositAcross = (0, client_js_1.createTool)({
name: "intentDepositAcross",
description: "Deposits tokens into the Across Protocol bridge to initiate a cross-chain transfer.",
supportedChains,
parameters: zod_1.z.object({
originChainId: zod_1.z
.number()
.describe("Chain ID of the origin chain for the deposit."),
originToken: zod_1.z
.string()
.describe("Address of the token to bridge on the origin chain."),
amount: zod_1.z.string().describe("Amount of tokens to bridge (in ether)"),
destinationToken: zod_1.z
.string()
.describe("Address of the token to bridge on the destination chain."),
destinationChainId: zod_1.z
.number()
.describe("Chain ID of the destination chain for the transfer."),
recipient: zod_1.z
.string()
.describe("Recipient address on the destination chain."),
}),
async execute(client, args) {
const { originChainId, originToken, destinationToken, amount, destinationChainId, recipient, } = args;
const walletClient = client.getWalletClient(originChainId);
const publicClient = client.getPublicClient(originChainId);
const userAddress = await client.getAddress();
const [tokenSymbol, decimals, currentAllowance] = await Promise.all([
publicClient.readContract({
address: originToken,
abi: viem_1.erc20Abi,
functionName: "symbol",
}),
publicClient.readContract({
address: originToken,
abi: viem_1.erc20Abi,
functionName: "decimals",
}),
publicClient.readContract({
address: originToken,
abi: viem_1.erc20Abi,
functionName: "allowance",
args: [userAddress, getAcrossSpokePoolAddress(originChainId)],
}),
]);
const amountBigInt = (0, viem_1.parseUnits)(amount, decimals);
const spokePoolAddress = getAcrossSpokePoolAddress(originChainId);
let ops = [];
if (currentAllowance < amountBigInt) {
const approvalData = (0, viem_1.encodeFunctionData)({
abi: viem_1.erc20Abi,
functionName: "approve",
args: [spokePoolAddress, viem_1.maxUint256],
});
ops.push({
target: originToken,
value: "0",
data: approvalData,
});
}
const quote = await tools_js_1.getAcrossFeeQuote.execute(client, {
inputToken: originToken,
outputToken: destinationToken,
originChainId,
destinationChainId,
amount,
recipient,
});
const outputAmountBigInt = amountBigInt - BigInt(quote.relayFeeTotal);
// Encode deposit data
const depositData = (0, viem_1.encodeFunctionData)({
abi: constants_js_1.acrossSpokePoolAbi,
functionName: "depositV3",
args: [
userAddress,
recipient,
originToken,
destinationToken,
amountBigInt,
outputAmountBigInt,
BigInt(destinationChainId),
quote.exclusiveRelayer,
Number(quote.timestamp),
Number(quote.fillDeadline),
quote.exclusivityDeadline,
"0x",
],
});
ops.push({
target: spokePoolAddress,
value: "0",
data: depositData,
});
const destChainName = supportedChains.find((chain) => chain.id === destinationChainId)?.name ||
destinationChainId;
const intentDescription = `Bridge ${amount} ${tokenSymbol} to ${destChainName} using Across Protocol`;
if (!walletClient) {
return {
intent: intentDescription,
ops,
chain: originChainId,
};
}
else {
const hash = await client.executeOps(ops, originChainId);
return {
intent: intentDescription,
ops,
chain: originChainId,
hash,
};
}
},
});
//# sourceMappingURL=intents.js.map