GET_POSITIONS
Retrieve all active positions from the Borrow Automated Market Maker (BAMM) contracts on the Fraxtal blockchain, enabling users to manage and monitor their borrowing activities efficiently.
Instructions
Get all your active BAMM positions
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/tools/get-positions.ts:4-29 (handler)The main handler for the GET_POSITIONS tool. It initializes the wallet and positions service, fetches positions, formats them, and handles errors.export const getPositionsTool = { name: "GET_POSITIONS", description: "Get all your active BAMM positions", // biome-ignore lint/suspicious/noExplicitAny: <these are not used anyways> execute: async (_params: any, _context: any) => { try { const privateKey = process.env.WALLET_PRIVATE_KEY; if (!privateKey) { return "Error: WALLET_PRIVATE_KEY environment variable is not set. Please set it with your wallet's private key (without 0x prefix)."; } const walletService = new WalletService(privateKey); const positionsService = new BammPositionsService(walletService); const positions = await positionsService.getPositions(); const formattedPositions = positionsService.formatPositions(positions); return formattedPositions; } catch (error) { if (error instanceof Error) { return `❌ Failed to retrieve positions: ${error.message}`; } return "❌ An unknown error occurred while retrieving positions"; } }, };
- src/services/get-positions.ts:9-21 (schema)Type definition for BammPosition, used to structure the data returned by getPositions.export interface BammPosition { bamm: Address; vault: { token0: bigint; token1: bigint; rented: bigint; } | null; // Additional Frax pool fields pairAddress: string; poolName: string; token0Symbol: string; token1Symbol: string; }
- src/index.ts:21-21 (registration)Registers the getPositionsTool with the FastMCP server.server.addTool(getPositionsTool);
- src/services/get-positions.ts:30-102 (helper)Fetches all active BAMM positions for the user by querying the BAMM factory, checking user registration in each BAMM, retrieving vault details, and enriching with pool info from Frax API.async getPositions(): Promise<BammPosition[]> { const publicClient = this.walletService.getPublicClient(); const walletClient = this.walletService.getWalletClient(); if (!walletClient || !walletClient.account) { throw new Error("Wallet client is not initialized"); } const userAddress = walletClient.account.address; // 1. Retrieve the list of all BAMM addresses from the factory const bammsArray = [ ...(await publicClient.readContract({ address: BAMM_ADDRESSES.FACTORY, abi: BAMM_FACTORY_ABI, functionName: "bammsArray", args: [], })), ]; const positions: BammPosition[] = []; // 2. Loop through each BAMM contract address for (const bamm of bammsArray) { // 3. Check if the user is registered in this BAMM using isUser const isUser: boolean = await publicClient.readContract({ address: bamm, abi: BAMM_ABI, functionName: "isUser", args: [userAddress], }); // 4. If the user is registered, get their vault details if (isUser) { const vault = await publicClient.readContract({ address: bamm, abi: BAMM_ABI, functionName: "getUserVault", args: [userAddress], }); // get pair address from the BAMM contract const pairAddress = await publicClient.readContract({ address: bamm, abi: BAMM_ABI, functionName: "pair", args: [], }); // call fraxswap API to get the pool details const response = await fetch( `https://api.frax.finance/v2/fraxswap/pools/${pairAddress}`, ); if (!response.ok) { throw new Error( `Failed to fetch pool details: ${response.statusText}`, ); } const poolData = await response.json(); const poolName = poolData.pools[0].poolName; const token0Symbol = poolData.pools[0].token0Symbol; const token1Symbol = poolData.pools[0].token1Symbol; positions.push({ bamm, vault, pairAddress, poolName, token0Symbol, token1Symbol, }); } } return positions; }
- Formats the list of BAMM positions into a human-readable string with details like balances and rented amounts.formatPositions(positions: BammPosition[]) { if (positions.length === 0 || positions.every((v) => !v)) { return "📊 No Active BAMM Positions Found"; } const formattedPositions = positions .map((pos) => { // Skip if vault is null if (!pos.vault) { return null; } // return if token0 and token1 is 0 if (pos.vault.token0 === 0n && pos.vault.token1 === 0n) { return null; } return dedent` **💰 BAMM Position** - bamm: ${pos.bamm} - Pair: ${pos.pairAddress} - ${pos.token0Symbol}: ${formatWeiToNumber(pos.vault.token0)} - ${pos.token1Symbol}: ${formatWeiToNumber(pos.vault.token1)} - rented: ${formatWeiToNumber(pos.vault.rented)} `; }) .filter(Boolean) .join("\n\n"); return `📊 *Your Active BAMM Positions*\n\n${formattedPositions}`; }