UNPKG

@coinbase/agentkit

Version:

Coinbase AgentKit core primitives

330 lines (326 loc) 14.2 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.yelayActionProvider = exports.YelayActionProvider = void 0; const zod_1 = require("zod"); const actionProvider_1 = require("../actionProvider"); const actionDecorator_1 = require("../actionDecorator"); const wallet_providers_1 = require("../../wallet-providers"); const schemas_1 = require("./schemas"); const constants_1 = require("./constants"); const viem_1 = require("viem"); const utils_1 = require("../../utils"); // Mainnet, Sonic, Base, Arbitrum, Avalanche const SUPPORTED_CHAIN_IDS = ["1", "146", "8453", "42161", "43114"]; /** * YelayActionProvider provides actions for yelay operations. * * @description * This provider is designed to work with EvmWalletProvider for blockchain interactions. * It supports all evm networks. */ class YelayActionProvider extends actionProvider_1.ActionProvider { /** * Constructor for the YelayActionProvider. */ constructor() { super("yelay", []); } /** * Gets the details of the Yelay vaults with their last week APY. * * @param wallet - The wallet instance to get chainId * @returns A formatted string containing the list of vaults with their APY. */ async getVaults(wallet) { let vaultsResponse; let vaultAPYsResponse; try { const chainId = wallet.getNetwork().chainId; [vaultsResponse, vaultAPYsResponse] = await Promise.all([ fetch(`${constants_1.YELAY_BACKEND_URL}/vaults?chainId=${chainId}`), fetch(`${constants_1.YELAY_BACKEND_URL}/interest/vaults?chainId=${chainId}`), ]); if (!vaultsResponse.ok || !vaultAPYsResponse.ok) { const errorMessage = !vaultsResponse.ok ? `Failed to fetch vaults: ${vaultsResponse.status} ${vaultsResponse.statusText}` : `Failed to fetch APYs: ${vaultAPYsResponse.status} ${vaultAPYsResponse.statusText}`; throw new Error(errorMessage); } const [vaults, vaultAPYs] = await Promise.all([ vaultsResponse.json(), vaultAPYsResponse.json(), ]); const vaultsDetails = vaults.map(vault => ({ ...vault, apy: vaultAPYs.find(apy => apy.vault === vault.address)?.apy, })); return vaultsDetails .map(vault => ` ${vault.name}: Address: ${vault.address} APY: ${vault.apy}% `) .join("----------------"); } catch (error) { return `Error fetching vault data: ${error}`; } } /** * Deposits assets into a Yelay Vault * * @param wallet - The wallet instance to execute the transaction * @param args - The input arguments for the action * @returns A success message with transaction details or an error message */ async deposit(wallet, args) { try { const chainId = wallet.getNetwork().chainId; const vaultsResponse = await fetch(`${constants_1.YELAY_BACKEND_URL}/vaults?chainId=${chainId}`); const vaults = (await vaultsResponse.json()); const vault = vaults.find(vault => vault.address === args.vaultAddress); if (!vault) { return "Error: Vault not found"; } const atomicAssets = (0, viem_1.parseUnits)(args.assets, vault.decimals); if (atomicAssets <= 0) { return "Error: Assets amount must be greater than 0"; } await (0, utils_1.approve)(wallet, vault.underlying, args.vaultAddress, atomicAssets); const data = (0, viem_1.encodeFunctionData)({ abi: constants_1.YELAY_VAULT_ABI, functionName: "deposit", args: [atomicAssets, constants_1.RETAIL_POOL_ID, wallet.getAddress()], }); const txHash = await wallet.sendTransaction({ to: args.vaultAddress, data }); await wallet.waitForTransactionReceipt(txHash); return `Deposited ${args.assets} to Yelay Vault ${args.vaultAddress} with transaction hash: ${txHash}`; } catch (error) { return `Error depositing to Yelay Vault: ${error}`; } } /** * Redeems assets from a Yelay Vault * * @param wallet - The wallet instance to execute the transaction * @param args - The input arguments for the action * @returns A success message with transaction details or an error message */ async redeem(wallet, args) { try { const chainId = wallet.getNetwork().chainId; const vaultsResponse = await fetch(`${constants_1.YELAY_BACKEND_URL}/vaults?chainId=${chainId}`); const vaults = (await vaultsResponse.json()); const vault = vaults.find(vault => vault.address === args.vaultAddress); if (!vault) { return "Error: Vault not found"; } const atomicAssets = (0, viem_1.parseUnits)(args.assets, vault.decimals); if (atomicAssets <= 0) { return "Error: Assets amount must be greater than 0"; } const data = (0, viem_1.encodeFunctionData)({ abi: constants_1.YELAY_VAULT_ABI, functionName: "redeem", args: [atomicAssets, constants_1.RETAIL_POOL_ID, wallet.getAddress()], }); const txHash = await wallet.sendTransaction({ to: args.vaultAddress, data }); await wallet.waitForTransactionReceipt(txHash); return `Redeemed ${args.assets} from Yelay Vault ${args.vaultAddress} with transaction hash: ${txHash}`; } catch (error) { return `Error redeeming from Yelay Vault: ${error}`; } } /** * Claims yield from Yelay * * @param wallet - The wallet instance to execute the transaction * @param args - The input arguments for the action * @returns A success message with transaction details or an error message */ async claim(wallet, args) { try { const chainId = wallet.getNetwork().chainId; const claimRequestResponse = await fetch(`${constants_1.YELAY_BACKEND_URL}/claim-proof?chainId=${chainId}&u=${wallet.getAddress()}&p=${constants_1.RETAIL_POOL_ID}&v=${args.vaultAddress}`); const claimRequests = await claimRequestResponse.json(); if (claimRequests.length === 0) { return "Error: No claim requests found"; } try { const data = (0, viem_1.encodeFunctionData)({ abi: constants_1.YIELD_EXTRACTOR_ABI, functionName: "claim", args: [claimRequests], }); const txHash = await wallet.sendTransaction({ to: constants_1.CONTRACTS_BY_CHAIN[chainId].YieldExtractor, data, }); await wallet.waitForTransactionReceipt(txHash); return claimRequests .map(c => `Claimed ${c.yieldSharesTotal} from Yelay Vault ${args.vaultAddress} with transaction hash: ${txHash}`) .join("\n"); } catch (error) { return `Error claiming yield from Yelay Vault: ${error}`; } } catch (error) { return `Error obtaining proof for yield to claim from Yelay Vault: ${error}`; } } /** * Gets user balance from Yelay * * @param wallet - The wallet instance to execute the transaction * @param args - The input arguments for the action * @returns A success message with user postion, generated and claimedyield */ async getBalance(wallet, args) { try { const chainId = wallet.getNetwork().chainId; const vaultsResponse = await fetch(`${constants_1.YELAY_BACKEND_URL}/vaults?chainId=${chainId}`); const vaults = (await vaultsResponse.json()); const vault = vaults.find(vault => vault.address === args.vaultAddress); if (!vault) { return "Error: Vault not found"; } const balance = (await wallet.readContract({ address: args.vaultAddress, abi: constants_1.YELAY_VAULT_ABI, functionName: "balanceOf", args: [wallet.getAddress(), constants_1.RETAIL_POOL_ID], })); const balanceInWholeUnits = (0, viem_1.formatUnits)(balance, vault.decimals); const balanceResponse = await fetch(`${constants_1.YELAY_BACKEND_URL}/claim-proof?chainId=${chainId}&u=${wallet.getAddress()}&p=${constants_1.RETAIL_POOL_ID}&v=${args.vaultAddress}`); if (!balanceResponse.ok) { throw new Error("Claim proof failed"); } const claimRequests = await balanceResponse.json(); if (claimRequests.length === 0) { return `User balance from Yelay Vault ${args.vaultAddress}: ${balanceInWholeUnits}`; } const claimRequest = claimRequests[0]; const yieldSharesClaimed = (await wallet.readContract({ address: constants_1.CONTRACTS_BY_CHAIN[chainId].YieldExtractor, abi: constants_1.YIELD_EXTRACTOR_ABI, functionName: "yieldSharesClaimed", args: [wallet.getAddress(), args.vaultAddress, constants_1.RETAIL_POOL_ID], })); return ` User balance from Yelay Vault ${args.vaultAddress}: ${balanceInWholeUnits} Yield shares generated: ${claimRequest.yieldSharesTotal} Yield shares claimed: ${yieldSharesClaimed}`; } catch (error) { return `Error getting balance from Yelay Vault: ${error}`; } } /** * Checks if this provider supports the given network. * * @param network - The network to check support for * @returns True if the network is supported */ supportsNetwork(network) { return (network.protocolFamily === "evm" && (network.chainId ? SUPPORTED_CHAIN_IDS.includes(network.chainId) : false)); } } exports.YelayActionProvider = YelayActionProvider; __decorate([ (0, actionDecorator_1.CreateAction)({ name: "get_vaults", description: `Getting Yelay vaults for the base network`, schema: zod_1.z.object({}), }), __metadata("design:type", Function), __metadata("design:paramtypes", [wallet_providers_1.EvmWalletProvider]), __metadata("design:returntype", Promise) ], YelayActionProvider.prototype, "getVaults", null); __decorate([ (0, actionDecorator_1.CreateAction)({ name: "deposit", description: ` This action deposits assets into a specified Yelay Vault. It takes: - assets: The amount of assets to deposit in whole units Examples for WETH: - 1 WETH - 0.1 WETH - 0.01 WETH - vaultAddress: The address of the Yelay Vault to deposit to Important notes: - Make sure to use the exact amount provided. Do not convert units for assets for this action. `, schema: schemas_1.YelayDepositSchema, }), __metadata("design:type", Function), __metadata("design:paramtypes", [wallet_providers_1.EvmWalletProvider, void 0]), __metadata("design:returntype", Promise) ], YelayActionProvider.prototype, "deposit", null); __decorate([ (0, actionDecorator_1.CreateAction)({ name: "redeem", description: ` This tool allows redeeming assets from a Yelay Vault. It takes: - assets: The amount of assets to redeem in atomic units (wei) - vaultAddress: The address of the vault to redeem from Important notes: - Make sure to use the exact amount provided. Do not convert units for assets for this action. `, schema: schemas_1.YelayRedeemSchema, }), __metadata("design:type", Function), __metadata("design:paramtypes", [wallet_providers_1.EvmWalletProvider, void 0]), __metadata("design:returntype", Promise) ], YelayActionProvider.prototype, "redeem", null); __decorate([ (0, actionDecorator_1.CreateAction)({ name: "claim", description: ` This tool allows claiming yield from a Yelay Vault. It takes: - vaultAddress: The address of the Yelay Vault to claim yield from `, schema: schemas_1.YelayClaimSchema, }), __metadata("design:type", Function), __metadata("design:paramtypes", [wallet_providers_1.EvmWalletProvider, void 0]), __metadata("design:returntype", Promise) ], YelayActionProvider.prototype, "claim", null); __decorate([ (0, actionDecorator_1.CreateAction)({ name: "get_balance", description: ` This tool allows getting user balance from Yelay. It takes: - vaultAddress: The address of the Yelay Vault to get balance from `, schema: schemas_1.YelayBalanceSchema, }), __metadata("design:type", Function), __metadata("design:paramtypes", [wallet_providers_1.EvmWalletProvider, void 0]), __metadata("design:returntype", Promise) ], YelayActionProvider.prototype, "getBalance", null); /** * Creates a new YelayActionProvider instance * * @returns A new YelayActionProvider instance */ const yelayActionProvider = () => { return new YelayActionProvider(); }; exports.yelayActionProvider = yelayActionProvider;