@agentek/tools
Version:
Blockchain tools for AI agents
283 lines • 13 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.intentTransferPosition = exports.intentCollectFees = exports.intentDecreaseLiquidity = exports.intentIncreaseLiquidity = exports.intentMintPosition = void 0;
const zod_1 = require("zod");
const client_js_1 = require("../client.js");
const constants_js_1 = require("./constants.js");
const viem_1 = require("viem");
const constants_js_2 = require("./constants.js");
const intentMintPosition = (0, client_js_1.createTool)({
name: "intentMintPosition",
description: "Creates a new Uniswap V3 liquidity position by minting an LP NFT. Requires both tokens to be approved for the Position Manager contract beforehand.",
supportedChains: constants_js_1.supportedChains,
parameters: zod_1.z.object({
token0: zod_1.z.string().describe("Address of the first token in the pair (0x...). Must be the lower-sorted address."),
token1: zod_1.z.string().describe("Address of the second token in the pair (0x...). Must be the higher-sorted address."),
fee: zod_1.z.number().describe("Pool fee tier in hundredths of a bip (e.g. 500 for 0.05%, 3000 for 0.3%, 10000 for 1%)"),
tickLower: zod_1.z.number().describe("Lower tick boundary of the position's price range"),
tickUpper: zod_1.z.number().describe("Upper tick boundary of the position's price range"),
amount0Desired: zod_1.z.string().describe("Desired amount of token0 to deposit in wei as a decimal string"),
amount1Desired: zod_1.z.string().describe("Desired amount of token1 to deposit in wei as a decimal string"),
slippageTolerance: zod_1.z.number().default(0.5).describe("Max slippage as a percentage (e.g. 0.5 for 0.5%). Default: 0.5"),
recipient: zod_1.z.string().optional().describe("Address to receive the LP NFT (0x...). Defaults to the connected wallet."),
deadline: zod_1.z.number().optional().describe("Unix timestamp deadline for the transaction. Defaults to 20 minutes from now."),
chainId: zod_1.z.number().describe("Chain ID where the pool exists (e.g. 1, 8453, 42161)"),
}),
execute: async (client, args) => {
const user = await client.getAddress();
const deadline = args.deadline || Math.floor(Date.now() / 1000) + 1200;
const amount0Desired = BigInt(args.amount0Desired);
const amount1Desired = BigInt(args.amount1Desired);
const amount0Min = (amount0Desired * (10000n - BigInt(args.slippageTolerance * 100))) /
10000n;
const amount1Min = (amount1Desired * (10000n - BigInt(args.slippageTolerance * 100))) /
10000n;
const data = (0, viem_1.encodeFunctionData)({
abi: constants_js_2.nonfungiblePositionManagerAbi,
functionName: "mint",
args: [
{
token0: args.token0,
token1: args.token1,
fee: args.fee,
tickLower: args.tickLower,
tickUpper: args.tickUpper,
amount0Desired,
amount1Desired,
amount0Min,
amount1Min,
recipient: args.recipient || user,
deadline: BigInt(deadline),
},
],
});
const ops = [
{
target: (0, constants_js_1.getPositionManagerAddress)(args.chainId),
value: "0",
data,
},
];
const walletClient = client.getWalletClient(args.chainId);
if (!walletClient) {
return {
intent: `Mint Uniswap V3 position for ${args.token0}/${args.token1}`,
ops,
chain: args.chainId,
};
}
const hash = await client.executeOps(ops, args.chainId);
return {
intent: `Mint Uniswap V3 position for ${args.token0}/${args.token1}`,
ops,
chain: args.chainId,
hash,
};
},
});
exports.intentMintPosition = intentMintPosition;
const intentIncreaseLiquidity = (0, client_js_1.createTool)({
name: "intentIncreaseLiquidity",
description: "Adds more liquidity to an existing Uniswap V3 LP position identified by its NFT token ID.",
supportedChains: constants_js_1.supportedChains,
parameters: zod_1.z.object({
tokenId: zod_1.z.string().describe("The NFT token ID of the existing LP position"),
amount0Desired: zod_1.z.string().describe("Desired amount of token0 to add in wei as a decimal string"),
amount1Desired: zod_1.z.string().describe("Desired amount of token1 to add in wei as a decimal string"),
slippageTolerance: zod_1.z.number().default(0.5).describe("Max slippage as a percentage (e.g. 0.5 for 0.5%). Default: 0.5"),
deadline: zod_1.z.number().optional().describe("Unix timestamp deadline for the transaction. Defaults to 20 minutes from now."),
chainId: zod_1.z.number().describe("Chain ID where the position exists (e.g. 1, 8453, 42161)"),
}),
execute: async (client, args) => {
const deadline = args.deadline || Math.floor(Date.now() / 1000) + 1200;
const amount0Desired = BigInt(args.amount0Desired);
const amount1Desired = BigInt(args.amount1Desired);
const amount0Min = (amount0Desired * (10000n - BigInt(args.slippageTolerance * 100))) /
10000n;
const amount1Min = (amount1Desired * (10000n - BigInt(args.slippageTolerance * 100))) /
10000n;
const data = (0, viem_1.encodeFunctionData)({
abi: constants_js_2.nonfungiblePositionManagerAbi,
functionName: "increaseLiquidity",
args: [
{
tokenId: BigInt(args.tokenId),
amount0Desired,
amount1Desired,
amount0Min,
amount1Min,
deadline: BigInt(deadline),
},
],
});
const ops = [
{
target: (0, constants_js_1.getPositionManagerAddress)(args.chainId),
value: "0",
data,
},
];
const walletClient = client.getWalletClient(args.chainId);
if (!walletClient) {
return {
intent: `Increase liquidity for position #${args.tokenId}`,
ops,
chain: args.chainId,
};
}
const hash = await client.executeOps(ops, args.chainId);
return {
intent: `Increase liquidity for position #${args.tokenId}`,
ops,
chain: args.chainId,
hash,
};
},
});
exports.intentIncreaseLiquidity = intentIncreaseLiquidity;
const intentDecreaseLiquidity = (0, client_js_1.createTool)({
name: "intentDecreaseLiquidity",
description: "Removes liquidity from a Uniswap V3 LP position. The removed tokens are not automatically collected — use intentCollectFees afterwards to withdraw them.",
supportedChains: constants_js_1.supportedChains,
parameters: zod_1.z.object({
tokenId: zod_1.z.string().describe("The NFT token ID of the LP position to remove liquidity from"),
liquidity: zod_1.z.string().describe("Amount of liquidity to remove as a decimal string (get this from getPositionDetails)"),
slippageTolerance: zod_1.z.number().default(0.5).describe("Max slippage as a percentage (e.g. 0.5 for 0.5%). Default: 0.5"),
deadline: zod_1.z.number().optional().describe("Unix timestamp deadline for the transaction. Defaults to 20 minutes from now."),
chainId: zod_1.z.number().describe("Chain ID where the position exists (e.g. 1, 8453, 42161)"),
}),
execute: async (client, args) => {
const deadline = args.deadline || Math.floor(Date.now() / 1000) + 1200;
const liquidity = BigInt(args.liquidity);
const amountMin = (liquidity * (10000n - BigInt(args.slippageTolerance * 100))) / 10000n;
const data = (0, viem_1.encodeFunctionData)({
abi: constants_js_2.nonfungiblePositionManagerAbi,
functionName: "decreaseLiquidity",
args: [
{
tokenId: BigInt(args.tokenId),
liquidity,
amount0Min: amountMin,
amount1Min: amountMin,
deadline: BigInt(deadline),
},
],
});
const ops = [
{
target: (0, constants_js_1.getPositionManagerAddress)(args.chainId),
value: "0",
data,
},
];
const walletClient = client.getWalletClient(args.chainId);
if (!walletClient) {
return {
intent: `Decrease liquidity for position #${args.tokenId}`,
ops,
chain: args.chainId,
};
}
const hash = await client.executeOps(ops, args.chainId);
return {
intent: `Decrease liquidity for position #${args.tokenId}`,
ops,
chain: args.chainId,
hash,
};
},
});
exports.intentDecreaseLiquidity = intentDecreaseLiquidity;
const intentCollectFees = (0, client_js_1.createTool)({
name: "intentCollectFees",
description: "Collects all accumulated trading fees and any tokens from decreased liquidity for a Uniswap V3 LP position.",
supportedChains: constants_js_1.supportedChains,
parameters: zod_1.z.object({
tokenId: zod_1.z.string().describe("The NFT token ID of the LP position to collect fees from"),
recipient: zod_1.z.string().optional().describe("Address to receive the collected tokens (0x...). Defaults to the connected wallet."),
chainId: zod_1.z.number().describe("Chain ID where the position exists (e.g. 1, 8453, 42161)"),
}),
execute: async (client, args) => {
const user = await client.getAddress();
const data = (0, viem_1.encodeFunctionData)({
abi: constants_js_2.nonfungiblePositionManagerAbi,
functionName: "collect",
args: [
{
tokenId: BigInt(args.tokenId),
recipient: args.recipient || user,
amount0Max: viem_1.maxUint128,
amount1Max: viem_1.maxUint128,
},
],
});
const ops = [
{
target: (0, constants_js_1.getPositionManagerAddress)(args.chainId),
value: "0",
data,
},
];
const walletClient = client.getWalletClient(args.chainId);
if (!walletClient) {
return {
intent: `Collect fees from position #${args.tokenId}`,
ops,
chain: args.chainId,
};
}
const hash = await client.executeOps(ops, args.chainId);
return {
intent: `Collect fees from position #${args.tokenId}`,
ops,
chain: args.chainId,
hash,
};
},
});
exports.intentCollectFees = intentCollectFees;
const intentTransferPosition = (0, client_js_1.createTool)({
name: "intentTransferPosition",
description: "Transfers ownership of a Uniswap V3 LP NFT to another address using safeTransferFrom.",
supportedChains: constants_js_1.supportedChains,
parameters: zod_1.z.object({
tokenId: zod_1.z.string().describe("The NFT token ID of the LP position to transfer"),
to: zod_1.z.string().describe("The recipient address to transfer the LP NFT to (0x...)"),
chainId: zod_1.z.number().describe("Chain ID where the position exists (e.g. 1, 8453, 42161)"),
}),
execute: async (client, args) => {
const data = (0, viem_1.encodeFunctionData)({
abi: viem_1.erc721Abi,
functionName: "safeTransferFrom",
args: [
await client.getAddress(),
args.to,
BigInt(args.tokenId),
],
});
const ops = [
{
target: (0, constants_js_1.getPositionManagerAddress)(args.chainId),
value: "0",
data,
},
];
const walletClient = client.getWalletClient(args.chainId);
if (!walletClient) {
return {
intent: `Transfer position #${args.tokenId} to ${args.to}`,
ops,
chain: args.chainId,
};
}
const hash = await client.executeOps(ops, args.chainId);
return {
intent: `Transfer position #${args.tokenId} to ${args.to}`,
ops,
chain: args.chainId,
hash,
};
},
});
exports.intentTransferPosition = intentTransferPosition;
//# sourceMappingURL=intents.js.map