UNPKG

@agentek/tools

Version:

Blockchain tools for AI agents

133 lines 5.22 kB
"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