@coinbase/agentkit
Version:
Coinbase AgentKit core primitives
330 lines (326 loc) • 14.2 kB
JavaScript
;
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;