UNPKG

tensaikit

Version:

An autonomous DeFi AI Agent Kit on Katana enabling AI agents to plan and execute on-chain financial operations.

118 lines (117 loc) 4.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isNativeToken = exports.allowance = exports.applyGasMultiplier = exports.approve = void 0; const viem_1 = require("viem"); const errors_1 = require("./common/errors"); const ERC20_ABI = [ { inputs: [ { name: "spender", type: "address" }, { name: "amount", type: "uint256" }, ], name: "approve", outputs: [{ name: "", type: "bool" }], stateMutability: "nonpayable", type: "function", }, { inputs: [ { name: "owner", type: "address" }, { name: "spender", type: "address" }, ], name: "allowance", outputs: [{ name: "", type: "uint256" }], stateMutability: "view", type: "function", }, ]; /** * Approves a spender to spend tokens on behalf of the owner. * * Encodes and sends an ERC-20 `approve` transaction using the provided wallet, * allowing the specified spender to spend a given amount of tokens. * * @param wallet - The EVM wallet provider used to sign and send the transaction. * @param tokenAddress - The ERC-20 token contract address. * @param spenderAddress - The address being approved to spend tokens. * @param amount - The amount of tokens to approve (in atomic units, e.g., wei). * @returns A promise that resolves to a success or error message string. */ const approve = async (wallet, tokenAddress, spenderAddress, amount) => { try { const data = (0, viem_1.encodeFunctionData)({ abi: ERC20_ABI, functionName: "approve", args: [spenderAddress, amount], }); const txHash = await wallet.sendTransaction({ to: tokenAddress, data, }); await wallet.waitForTransactionReceipt(txHash); return `Approval successful: ${spenderAddress} is now allowed to spend up to ${amount.toString()} tokens.`; } catch (error) { return `Error approving tokens for ${spenderAddress}: ${error.message || error}`; } }; exports.approve = approve; /** * Scales a gas estimate by a given multiplier. * * This function converts the gas estimate to a number, applies the multiplier, * rounds the result to the nearest integer, and returns it as a bigint. * * @param gas - The original gas estimate as a bigint. * @param multiplier - The factor by which to scale the estimate. * @returns The adjusted gas estimate as a bigint. */ const applyGasMultiplier = (gas, multiplier) => { return BigInt(Math.round(Number(gas) * multiplier)); }; exports.applyGasMultiplier = applyGasMultiplier; /** * Fetches the current token allowance for a spender set by the connected wallet. * * Calls the ERC-20 `allowance` function to determine how many tokens the * `spenderAddress` is allowed to spend on behalf of the wallet's address. * * @param wallet - The EVM wallet provider used to get the owner's address and read from the contract * @param tokenAddress - The address of the ERC-20 token contract * @param spenderAddress - The address of the spender whose allowance is being queried * @returns A promise that resolves to the allowance amount as a bigint * @throws CONTRACT_ERROR if the read call fails */ const allowance = async (wallet, tokenAddress, spenderAddress) => { try { const ownerAddress = wallet.getAddress(); const allowanceAmount = await wallet.readContract({ address: tokenAddress, abi: ERC20_ABI, functionName: "allowance", args: [ownerAddress, spenderAddress], }); console.log(`[Token Allowance] Spender: ${spenderAddress} | Owner: ${ownerAddress} | Allowance: ${allowanceAmount.toString()}`); return allowanceAmount; } catch (error) { throw (0, errors_1.createError)(`Failed to fetch allowance from contract: ${error}`, errors_1.ErrorCode.CONTRACT_ERROR); } }; exports.allowance = allowance; /** * Checks if the provided token address represents a native token (e.g., ETH, MATIC). * * Considers two common placeholders used to represent native tokens: * - `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` (commonly used in DeFi protocols) * - `0x0000000000000000000000000000000000000000` (null address) * * @param tokenAddress - The token address to check * @returns `true` if the address is a known native token placeholder, otherwise `false` */ const isNativeToken = (tokenAddress) => { const normalized = tokenAddress.toLowerCase(); return (normalized === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" || normalized === "0x0000000000000000000000000000000000000000"); }; exports.isNativeToken = isNativeToken;