### Install @aave/contract-helpers with yarn Source: https://github.com/aave/aave-utilities/blob/master/packages/contract-helpers/README.md Use this command to install the package using yarn. ```sh yarn add @aave/contract-helpers ``` -------------------------------- ### Install @aave/math-utils with npm Source: https://github.com/aave/aave-utilities/blob/master/packages/math-utils/README.md Install the package using npm. This is the standard method for Node.js projects. ```sh npm install @aave/math-utils ``` -------------------------------- ### Installation Source: https://github.com/aave/aave-utilities/blob/master/README.md Instructions for installing the Aave Utilities npm packages and the required ethers.js version. ```APIDOC ## Installation Aave utilities are available as npm packages: - `@aave/math-utils`: Contains methods for formatting raw contract data. - `@aave/contract-helpers`: Contains methods for generating transactions. ```sh # with npm npm install @aave/contract-helpers @aave/math-utils # with yarn yarn add @aave/contract-helpers @aave/math-utils ``` ### Compatibility This library has a peer dependency of [ethers v5](https://docs.ethers.org/v5/), and will not work with v6. To install the correct version, run: ```sh npm install ethers@5 ``` ``` -------------------------------- ### Complete Data Fetching and Formatting Example Source: https://context7.com/aave/aave-utilities/llms.txt This example demonstrates fetching all protocol and user data, then formatting it into human-readable values. It requires initializing data providers and uses utility functions for data transformation. Ensure necessary imports are included. ```typescript import { ethers } from 'ethers'; import { UiPoolDataProvider, UiIncentiveDataProvider, ChainId, } from '@aave/contract-helpers'; import { formatReservesAndIncentives, formatUserSummaryAndIncentives, } from '@aave/math-utils'; import * as markets from '@bgd-labs/aave-address-book'; import dayjs from 'dayjs'; const provider = new ethers.providers.JsonRpcProvider( 'https://eth-mainnet.public.blastapi.io' ); const currentAccount = '0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c'; // Initialize data providers const poolDataProvider = new UiPoolDataProvider({ uiPoolDataProviderAddress: markets.AaveV3Ethereum.UI_POOL_DATA_PROVIDER, provider, chainId: ChainId.mainnet, }); const incentiveDataProvider = new UiIncentiveDataProvider({ uiIncentiveDataProviderAddress: markets.AaveV3Ethereum.UI_INCENTIVE_DATA_PROVIDER, provider, chainId: ChainId.mainnet, }); // Fetch raw data const [reserves, userReserves, reserveIncentives, userIncentives] = await Promise.all([ poolDataProvider.getReservesHumanized({ lendingPoolAddressProvider: markets.AaveV3Ethereum.POOL_ADDRESSES_PROVIDER, }), poolDataProvider.getUserReservesHumanized({ lendingPoolAddressProvider: markets.AaveV3Ethereum.POOL_ADDRESSES_PROVIDER, user: currentAccount, }), incentiveDataProvider.getReservesIncentivesDataHumanized({ lendingPoolAddressProvider: markets.AaveV3Ethereum.POOL_ADDRESSES_PROVIDER, }), incentiveDataProvider.getUserReservesIncentivesDataHumanized({ lendingPoolAddressProvider: markets.AaveV3Ethereum.POOL_ADDRESSES_PROVIDER, user: currentAccount, }), ]); const currentTimestamp = dayjs().unix(); // Format reserve data with incentives const formattedReserves = formatReservesAndIncentives({ reserves: reserves.reservesData, currentTimestamp, marketReferenceCurrencyDecimals: reserves.baseCurrencyData.marketReferenceCurrencyDecimals, marketReferencePriceInUsd: reserves.baseCurrencyData.marketReferenceCurrencyPriceInUsd, reserveIncentives, }); // Format user data with incentives const userSummary = formatUserSummaryAndIncentives({ currentTimestamp, marketReferencePriceInUsd: reserves.baseCurrencyData.marketReferenceCurrencyPriceInUsd, marketReferenceCurrencyDecimals: reserves.baseCurrencyData.marketReferenceCurrencyDecimals, userReserves: userReserves.userReserves, formattedReserves, userEmodeCategoryId: userReserves.userEmodeCategoryId, reserveIncentives, userIncentives, }); console.log('Formatted Reserves:', formattedReserves); console.log('User Summary:', userSummary); console.log('User Claimable Incentives:', userSummary.calculatedUserIncentives); ``` -------------------------------- ### Install @aave/contract-helpers with npm Source: https://github.com/aave/aave-utilities/blob/master/packages/contract-helpers/README.md Use this command to install the package using npm. ```sh npm install @aave/contract-helpers ``` -------------------------------- ### Install Aave Utilities Packages Source: https://context7.com/aave/aave-utilities/llms.txt Install the required packages and peer dependencies using npm or yarn. ```bash npm install @aave/contract-helpers @aave/math-utils ethers@5 ``` ```bash yarn add @aave/contract-helpers @aave/math-utils ethers@5 ``` -------------------------------- ### Install Aave Contract Helpers and Math Utils Source: https://github.com/aave/aave-utilities/blob/master/README.md Install the necessary packages for Aave utilities using npm or yarn. ```sh // with npm npm install @aave/contract-helpers @aave/math-utils ``` ```sh // with yarn yarn add @aave/contract-helpers @aave/math-utils ``` -------------------------------- ### Install @aave/math-utils with yarn Source: https://github.com/aave/aave-utilities/blob/master/packages/math-utils/README.md Install the package using yarn. This is an alternative package manager for Node.js projects. ```sh yarn add @aave/math-utils ``` -------------------------------- ### Install Ethers v5 Source: https://github.com/aave/aave-utilities/blob/master/README.md Install the compatible version of ethers.js, which is v5. This library does not support ethers v6. ```sh npm install ethers@5 ``` -------------------------------- ### Format Aave User Portfolio Summary and Incentives Source: https://github.com/aave/aave-utilities/blob/master/README.md Use this function to get a formatted summary of a user's Aave portfolio, including claimable incentives. Ensure all required inputs from fetching protocol data are provided. ```typescript import { formatUserSummaryAndIncentives } from '@aave/math-utils'; import dayjs from 'dayjs'; // 'reserves', 'userReserves', 'reserveIncentives', and 'userIncentives' inputs from Setup section const reservesArray = reserves.reservesData; const baseCurrencyData = reserves.baseCurrencyData; const userReservesArray = userReserves.userReserves; const currentTimestamp = dayjs().unix(); const formattedReserves = formatReserves({ reserves: reservesArray, currentTimestamp, marketReferenceCurrencyDecimals: baseCurrencyData.marketReferenceCurrencyDecimals, marketReferencePriceInUsd: baseCurrencyData.marketReferenceCurrencyPriceInUsd, }); /* - @param `currentTimestamp` Current UNIX timestamp in seconds, Math.floor(Date.now() / 1000) - @param `marketReferencePriceInUsd` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserves.baseCurrencyData.marketReferencePriceInUsd` - @param `marketReferenceCurrencyDecimals` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserves.baseCurrencyData.marketReferenceCurrencyDecimals` - @param `userReserves` Input from [Fetching Protocol Data](#fetching-protocol-data), combination of `userReserves.userReserves` and `reserves.reservesArray` - @param `userEmodeCategoryId` Input from [Fetching Protocol Data](#fetching-protocol-data), `userReserves.userEmodeCategoryId` - @param `reserveIncentives` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserveIncentives` - @param `userIncentives` Input from [Fetching Protocol Data](#fetching-protocol-data), `userIncentives` */ const userSummary = formatUserSummaryAndIncentives({ currentTimestamp, marketReferencePriceInUsd: baseCurrencyData.marketReferenceCurrencyPriceInUsd, marketReferenceCurrencyDecimals: baseCurrencyData.marketReferenceCurrencyDecimals, userReserves: userReservesArray, formattedReserves, userEmodeCategoryId: userReserves.userEmodeCategoryId, reserveIncentives, userIncentives, }); ``` -------------------------------- ### Format Aave User Portfolio Summary Source: https://github.com/aave/aave-utilities/blob/master/README.md Use this function to get a formatted summary of a user's Aave portfolio. Ensure you have the necessary inputs from fetching protocol data, including reserves and user reserves. ```typescript import { formatUserSummary } from '@aave/math-utils'; import dayjs from 'dayjs'; // 'reserves' and 'userReserves' inputs from Setup section const reservesArray = reserves.reservesData; const baseCurrencyData = reserves.baseCurrencyData; const userReservesArray = userReserves.userReserves; const currentTimestamp = dayjs().unix(); const formattedReserves = formatReserves({ reserves: reservesArray, currentTimestamp, marketReferenceCurrencyDecimals: baseCurrencyData.marketReferenceCurrencyDecimals, marketReferencePriceInUsd: baseCurrencyData.marketReferenceCurrencyPriceInUsd, }); /* - @param `currentTimestamp` Current UNIX timestamp in seconds, Math.floor(Date.now() / 1000) - @param `marketReferencePriceInUsd` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserves.baseCurrencyData.marketReferencePriceInUsd` - @param `marketReferenceCurrencyDecimals` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserves.baseCurrencyData.marketReferenceCurrencyDecimals` - @param `userReserves` Input from [Fetching Protocol Data](#fetching-protocol-data), combination of `userReserves.userReserves` and `reserves.reservesArray` - @param `userEmodeCategoryId` Input from [Fetching Protocol Data](#fetching-protocol-data), `userReserves.userEmodeCategoryId` */ const userSummary = formatUserSummary({ currentTimestamp, marketReferencePriceInUsd: baseCurrencyData.marketReferenceCurrencyPriceInUsd, marketReferenceCurrencyDecimals: baseCurrencyData.marketReferenceCurrencyDecimals, userReserves: userReservesArray, formattedReserves, userEmodeCategoryId: userReserves.userEmodeCategoryId, }); ``` -------------------------------- ### Get Approved Amount for V2 and V3 Source: https://github.com/aave/aave-utilities/blob/master/README.md Fetches the currently approved amount for a given token for a user in either V2 or V3 markets. Handles potential errors during the fetch operation. ```javascript async function getApprovedAmount(v2, marketKey, user, token) { const poolBundle = getPoolBundle(v2, marketKey); if (v2) { try { const approvedAmount = await poolBundle.depositTxBuilder.getApprovedAmount({ user, token, }); return approvedAmount; } catch (error) { console.error("Error fetching approved amount", error); } } else { try { const approvedAmount = await poolBundle.supplyTxBuilder.getApprovedAmount( { user, token, } ); return approvedAmount; } catch (error) { console.error("Error fetching approved amount", error); } } } ``` -------------------------------- ### Welcome Message and Initialization Source: https://github.com/aave/aave-utilities/blob/master/README.md Displays a welcome message with an ASCII art logo and prompts the user to press Enter to begin. Initializes the user interaction by calling promptUser() after the first line input. ```javascript function welcome() { console.log("Welcome to"); console.log("\n"); console.log( " ###### ## ## ####### ###### ######## ###### ## ####\n ## ## ## ## ## ## ## ## ## ## ## ## ##\n ## ## ## ## ## ## ## ## ## ##\n ## #### ######### ## ## ###### ## ## ## ##\n ## ## ## ## ## ## ## ## ## ## ##\n ## ## ## ## ## ## ## ## ## ## ## ## ##\n ###### ## ## ####### ###### ## ###### ######## ####\n\n "); console.log("Press enter to begin"); let load = true; rl.on("line", () => { if (load) { promptUser(); load = false; } }); } welcome(); ``` -------------------------------- ### Initialize Aave Governance Service V2 Source: https://github.com/aave/aave-utilities/blob/master/README.md Set up the AaveGovernanceService for interacting with Aave governance V2. Requires a Web3 provider and addresses for governance contracts. ```typescript import { AaveGovernanceService } from '@aave/contract-helpers'; const httpProvider = new Web3.providers.HttpProvider( process.env.ETHEREUM_URL || 'https://kovan.infura.io/v3/', ); const governanceService = new AaveGovernanceService(httpProvider, { GOVERNANCE_ADDRESS: aaveGovernanceV2Address, GOVERNANCE_HELPER_ADDRESS: aaveGovernanceV2HelperAddress, ipfsGateway: IPFS_ENDPOINT, }); ``` -------------------------------- ### Set Efficiency Mode (eMode) Source: https://context7.com/aave/aave-utilities/llms.txt Enable efficiency mode to get higher LTV when borrowing assets in the same category. Use `categoryId: 1` for stablecoins, `0` to disable. ```typescript import { Pool } from '@aave/contract-helpers'; const pool = new Pool(provider, { POOL: markets.AaveV3Ethereum.POOL, }); // Enable stablecoin eMode (categoryId: 1) const txs = pool.setUserEMode({ user: '0xUserAddress', categoryId: 1, // 0 = disable, 1 = stablecoins, etc. }); const tx = txs[0]; const extendedTxData = await tx.tx(); const signer = provider.getSigner(); await signer.sendTransaction(extendedTxData); ``` -------------------------------- ### Initialize Aave PoolBundle and LendingPoolBundle Source: https://github.com/aave/aave-utilities/blob/master/README.md Initializes PoolBundle for V3 or LendingPoolBundle for V2 using the provided provider and market configuration. Ensure the correct market key is used for your desired network. ```javascript const ethers = require("ethers"); const markets = require("@bgd-labs/aave-address-book"); const { PoolBundle, LendingPoolBundle } = require("@aave/contract-helpers"); // Create provider // Can use custom RPC or a local fork network from tenderly, ganache, foundry, hardhat, etc. for testing const provider = ethers.getDefaultProvider("homestead"); function getPoolBundle(v2, marketKey) { if (v2) { return new LendingPoolBundle(provider, { LENDING_POOL: markets[marketKey].POOL, WETH_GATEWAY: markets[marketKey].WETH_GATEWAY, }); } else { return new PoolBundle(provider, { POOL: markets[marketKey].POOL, WETH_GATEWAY: markets[marketKey].WETH_GATEWAY, }); } } console.log("Available markets", markets); ``` -------------------------------- ### Import and Initialize Pool Source: https://github.com/aave/aave-utilities/blob/master/README.md Instantiate the Pool contract helper for V3 Pool interactions, requiring a provider and contract addresses. ```typescript import { Pool } from '@aave/contract-helpers'; const pool = new Pool(provider, { POOL: poolAddress, WETH_GATEWAY: wethGatewayAddress, }); ``` -------------------------------- ### Import and Initialize PoolBundle Source: https://github.com/aave/aave-utilities/blob/master/README.md Instantiate the PoolBundle for V3 Pool contract interactions, requiring a provider and contract addresses. ```typescript import { PoolBundle } from '@aave/contract-helpers'; const poolBundle = new PoolBundle(provider, { POOL: poolAddress, WETH_GATEWAY: wethGatewayAddress, }); ``` -------------------------------- ### Package.json Scripts for New Package Source: https://github.com/aave/aave-utilities/blob/master/CONTRIBUTING.md These scripts should be included in the package.json for a new package. They define tasks like cleaning, linting, building, testing, and committing, utilizing project-wide commands. ```json "scripts": { "clean": "cd ../.. && npx rimraf packages/YOUR_PACKAGE_NAME/dist packages/math-utils/*.log*", "lint": "cd ../.. && eslint packages/YOUR_PACKAGE_NAME/src/**/*.ts", "check-types": "yarn build -- --noEmit", "prebuild": "yarn clean", "build": "cd ../.. && tsc -p packages/YOUR_PACKAGE_NAME/tsconfig.json && tsc -p packages/YOUR_PACKAGE_NAME/tsconfig.json --module commonjs --outDir ./packages/YOUR_PACKAGE_NAME/dist/cjs", "test": "cd ../.. && yarn test packages/YOUR_PACKAGE_NAME", "cover": "cd ../.. && yarn cover packages/YOUR_PACKAGE_NAME", "commit": "cd ../.. && yarn commit", "prepublishOnly": "yarn build" }, ``` -------------------------------- ### Initialize Aave Data Services and Fetch Data Source: https://github.com/aave/aave-utilities/blob/master/README.md Initializes UiPoolDataProvider and UiIncentiveDataProvider to fetch Aave protocol data. Requires an ethers provider and an account address. Ensure the correct chain ID and market addresses are used. ```javascript import { ethers } from 'ethers'; import { UiPoolDataProvider, UiIncentiveDataProvider, ChainId, } from '@aave/contract-helpers'; import * as markets from '@bgd-labs/aave-address-book'; // ES5 Alternative imports // const { // ChainId, // UiIncentiveDataProvider, // UiPoolDataProvider, // } = require('@aave/contract-helpers'); // const markets = require('@bgd-labs/aave-address-book'); // const ethers = require('ethers'); // Sample RPC address for querying ETH mainnet const provider = new ethers.providers.JsonRpcProvider( 'https://eth-mainnet.public.blastapi.io', ); // User address to fetch data for, insert address here const currentAccount = '0x464C71f6c2F760DdA6093dCB91C24c39e5d6e18c'; // View contract used to fetch all reserves data (including market base currency data), and user reserves // Using Aave V3 Eth Mainnet address for demo const poolDataProviderContract = new UiPoolDataProvider({ uiPoolDataProviderAddress: markets.AaveV3Ethereum.UI_POOL_DATA_PROVIDER, provider, chainId: ChainId.mainnet, }); // View contract used to fetch all reserve incentives (APRs), and user incentives // Using Aave V3 Eth Mainnet address for demo const incentiveDataProviderContract = new UiIncentiveDataProvider({ uiIncentiveDataProviderAddress: markets.AaveV3Ethereum.UI_INCENTIVE_DATA_PROVIDER, provider, chainId: ChainId.mainnet, }); async function fetchContractData() { // Object containing array of pool reserves and market base currency data // { reservesArray, baseCurrencyData } const reserves = await poolDataProviderContract.getReservesHumanized({ lendingPoolAddressProvider: markets.AaveV3Ethereum.POOL_ADDRESSES_PROVIDER, }); // Object containing array of users aave positions and active eMode category // { userReserves, userEmodeCategoryId } const userReserves = await poolDataProviderContract.getUserReservesHumanized({ lendingPoolAddressProvider: markets.AaveV3Ethereum.POOL_ADDRESSES_PROVIDER, user: currentAccount, }); // Array of incentive tokens with price feed and emission APR const reserveIncentives = await incentiveDataProviderContract.getReservesIncentivesDataHumanized({ lendingPoolAddressProvider: markets.AaveV3Ethereum.POOL_ADDRESSES_PROVIDER, }); // Dictionary of claimable user incentives const userIncentives = await incentiveDataProviderContract.getUserReservesIncentivesDataHumanized({ lendingPoolAddressProvider: markets.AaveV3Ethereum.POOL_ADDRESSES_PROVIDER, user: currentAccount, }); console.log({ reserves, userReserves, reserveIncentives, userIncentives }); } fetchContractData(); ``` -------------------------------- ### Repay with Collateral (V3) Source: https://github.com/aave/aave-utilities/blob/master/README.md Allows a borrower to repay their open debt using their collateral. This method handles the complexities of swapping collateral to repay the debt. ```APIDOC ## POST /repayWithCollateral (V3) ### Description Allows a borrower to repay the open debt with their collateral. ### Method POST ### Endpoint /repayWithCollateral ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **user** (string) - Required - The ethereum address that will repay the debt. - **fromAsset** (string) - Required - The ethereum address of the asset you want to repay with (collateral). - **fromAToken** (string) - Required - The ethereum address of the aToken of the asset you want to repay with (collateral). - **assetToRepay** (string) - Required - The ethereum address of the asset you want to repay. - **repayWithAmount** (string) - Required - The amount of collateral you want to repay the debt with. - **repayAmount** (string) - Required - The amount of debt you want to repay. - **permitSignature** (string) - Optional - A permit signature of the tx. - **repayAllDebt** (boolean) - Optional - Bool indicating if the user wants to repay all current debt. Defaults to false. - **rateMode** (number) - Required - Enum indicating the type of the interest rate of the collateral. - **onBehalfOf** (string) - Optional - The ethereum address for which user is swapping. It will default to the user address. - **referralCode** (number) - Optional - Integrators are assigned a referral code and can potentially receive rewards. It defaults to 0 (no referrer). - **flash** (boolean) - Optional - If the transaction will be executed through a flashloan(true) or will be done directly through the adapters(false). Defaults to false. - **useEthPath** (boolean) - Optional - Boolean to indicate if the swap will use an ETH path. Defaults to false. ### Request Example ```json { "user": "0x...", "fromAsset": "0x...", "fromAToken": "0x...", "assetToRepay": "0x...", "repayWithAmount": "1000000000000000000", "repayAmount": "500000000000000000", "rateMode": 1, "onBehalfOf": "0x...", "referralCode": 10, "flash": false, "useEthPath": false } ``` ### Response #### Success Response (200) - **txs** (Array) - An array of transaction objects to be submitted. #### Response Example ```json [ { "tx": { "to": "0x...", "from": "0x...", "data": "0x...", "value": "0x..." }, "txType": "..." } ] ``` ``` -------------------------------- ### POST /repayWithPermit Source: https://github.com/aave/aave-utilities/blob/master/README.md Repays a debt using a signature-based approval. This method is similar to `repay` but utilizes a permit for approval. ```APIDOC ## POST /repayWithPermit ### Description Repays a debt using a signature-based approval. This method is similar to `repay` but utilizes a permit for approval. ### Method POST ### Endpoint /repayWithPermit ### Parameters #### Request Body - **user** (string) - Required - The ethereum address that will make the repayment. - **reserve** (string) - Required - The ethereum address of the reserve. - **amount** (string) - Required - The amount to be repaid. - **signature** (string) - Required - Signature approving Pool to spend user funds, from signERC20Approval(). - **onBehalfOf** (string) - Optional - The ethereum address for which the user is repaying. It will default to the user address. ### Request Example ```json { "user": "0x...", "reserve": "0x...", "amount": "1000000000000000000", "signature": "0x...", "onBehalfOf": "0x..." } ``` ### Response #### Success Response (200) - **txs** (Array) - An array of extended Ethereum transactions. #### Response Example ```json { "txs": [ { "tx": { "to": "0x...", "from": "0x...", "data": "0x..." }, "txType": "..." } ] } ``` ``` -------------------------------- ### Package.json Module and Types Configuration Source: https://github.com/aave/aave-utilities/blob/master/CONTRIBUTING.md Include these fields in the package.json for a new package to specify the main entry point, ES module entry point, and TypeScript declaration file location. ```json "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", "types": "./dist/esm/index.d.ts", ``` -------------------------------- ### POST /repayWithATokens Source: https://github.com/aave/aave-utilities/blob/master/README.md Repays a borrow using a user's aToken balance. To repay the maximum possible amount, set the amount to -1. ```APIDOC ## POST /repayWithATokens ### Description Repays a borrow on the specific reserve, for the specified amount, deducting funds from a users aToken balance instead of the underlying balance. To repay the max debt amount or max aToken balance without dust (whichever is lowest), set the amount to -1. There is no need for an approval or signature when repaying with aTokens. ### Method POST ### Endpoint /repayWithATokens ### Parameters #### Request Body - **user** (string) - Required - The ethereum address that will make the repayment. - **amount** (string) - Required - The amount to be repaid, -1 to repay max aToken balance or max debt balance without dust (whichever is lowest). - **reserve** (string) - Required - The ethereum address of the reserve. - **rateMode** (InterestRate) - Required - The debt type to repay, stable or variable. ### Request Example ```json { "user": "0x...", "amount": "-1", "reserve": "0x...", "rateMode": "InterestRate.Variable" } ``` ### Response #### Success Response (200) - **txs** (Array) - An array of extended Ethereum transactions. #### Response Example ```json { "txs": [ { "tx": { "to": "0x...", "from": "0x...", "data": "0x..." }, "txType": "..." } ] } ``` ``` -------------------------------- ### Initialize Aave PoolBundle Source: https://github.com/aave/aave-utilities/blob/master/README.md Initializes a PoolBundle or LendingPoolBundle based on the specified Aave version (V2 or V3). Requires an ethers provider and market key. ```javascript const ethers = require("ethers"); const markets = require("@bgd-labs/aave-address-book"); const { PoolBundle, LendingPoolBundle, } = require("@aave/contract-helpers"); // Create provider and connect wallet // Can use a local fork network from tenderly, ganache, foundry, hardhat, etc. for testing const provider = ethers.getDefaultProvider("homestead"); function getPoolBundle(v2, marketKey) { if (v2) { return new LendingPoolBundle(provider, { LENDING_POOL: markets[marketKey].POOL, WETH_GATEWAY: markets[marketKey].WETH_GATEWAY, }); } else { return new PoolBundle(provider, { POOL: markets[marketKey].POOL, WETH_GATEWAY: markets[marketKey].WETH_GATEWAY, }); } } ``` -------------------------------- ### StakingService - Initiate Cooldown and Redeem Source: https://context7.com/aave/aave-utilities/llms.txt Initiate the cooldown period before unstaking, followed by redeeming staked tokens. The cooldown period has a 10-day waiting time. Use '-1' to redeem the entire balance. ```typescript import { StakingService } from '@aave/contract-helpers'; const stakingService = new StakingService(provider, { TOKEN_STAKING_ADDRESS: '0xStkAAVEAddress', }); // Step 1: Activate cooldown (10-day waiting period) const cooldownTxs = stakingService.cooldown('0xUserAddress'); const cooldownTx = cooldownTxs[0]; await signer.sendTransaction(await cooldownTx.tx()); // Step 2: After cooldown period ends, redeem tokens // Use '-1' to redeem entire balance const redeemTxs = await stakingService.redeem( '0xUserAddress', '-1' // or specific amount like '50' ); const redeemTx = redeemTxs[0]; await signer.sendTransaction(await redeemTx.tx()); ``` -------------------------------- ### New Transaction Methods (Experimental) Source: https://github.com/aave/aave-utilities/blob/master/README.md Experimental methods for building transactions. ```APIDOC ## New Transaction Methods (Experimental) ### `supplyTxBuilder` **Description**: Builds a supply transaction. ### `depositTxBuilder` **Description**: Builds a deposit transaction. ``` -------------------------------- ### Format Aave Market Reserves and Incentives with @aave/math-utils Source: https://github.com/aave/aave-utilities/blob/master/README.md This function formats reserve data along with supply, variable borrow, and stable borrow incentives. It requires reserve data, incentive data, and market reference information. ```typescript import { formatReservesAndIncentives } from '@aave/math-utils'; import dayjs from 'dayjs'; // 'reserves' and 'reserveIncentives' inputs from Fetching Protocol Data section const reservesArray = reserves.reservesData; const baseCurrencyData = reserves.baseCurrencyData; const currentTimestamp = dayjs().unix(); /* - @param `reserves` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserves.reservesArray` - @param `currentTimestamp` Current UNIX timestamp in seconds, Math.floor(Date.now() / 1000) - @param `marketReferencePriceInUsd` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserves.baseCurrencyData.marketReferencePriceInUsd` - @param `marketReferenceCurrencyDecimals` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserves.baseCurrencyData.marketReferenceCurrencyDecimals` - @param `reserveIncentives` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserveIncentives` */ const formattedPoolReserves = formatReservesAndIncentives({ reserves: reservesArray, currentTimestamp, marketReferenceCurrencyDecimals: baseCurrencyData.marketReferenceCurrencyDecimals, marketReferencePriceInUsd: baseCurrencyData.marketReferenceCurrencyPriceInUsd, reserveIncentives, }); ``` -------------------------------- ### Swap Collateral (V3) Source: https://github.com/aave/aave-utilities/blob/master/README.md Utilizes flashloan to swap to a different collateral asset. Specify user, assets to swap from and to, amounts, and slippage tolerance. Can be executed directly or via flashloan. ```typescript import { Pool } from '@aave/contract-helpers'; const pool = new Pool(provider, { POOL: poolAddress, SWAP_COLLATERAL_ADAPTER: swapCollateralAdapterAddress, WETH_GATEWAY: wethGatewayAddress, }); /* - @param `user` The ethereum address that will liquidate the position - @param @optional `flash` If the transaction will be executed through a flashloan(true) or will be done directly through the adapters(false). Defaults to false - @param `fromAsset` The ethereum address of the asset you want to swap - @param `fromAToken` The ethereum address of the aToken of the asset you want to swap - @param `toAsset` The ethereum address of the asset you want to swap to (get) - @param `fromAmount` The amount you want to swap - @param `toAmount` The amount you want to get after the swap - @param `maxSlippage` The max slippage that the user accepts in the swap - @param @optional `permitSignature` A permit signature of the tx. Only needed when previously signed (Not needed at the moment). - @param `swapAll` Bool indicating if the user wants to swap all the current collateral - @param @optional `onBehalfOf` The ethereum address for which user is swapping. It will default to the user address - @param @optional `referralCode` Integrators are assigned a referral code and can potentially receive rewards. It defaults to 0 (no referrer) - @param @optional `useEthPath` Boolean to indicate if the swap will use an ETH path. Defaults to false */ const txs: EthereumTransactionTypeExtended[] = await lendingPool.swapCollateral( { user, flash, fromAsset, fromAToken, toAsset, fromAmount, toAmount, maxSlippage, permitSignature, swapAll, onBehalfOf, referralCode, useEthPath, }, ); ``` -------------------------------- ### Repay Debt with Collateral using LendingPool Source: https://github.com/aave/aave-utilities/blob/master/README.md Use this function to repay open debt by using your collateral. Ensure you have the necessary provider and contract addresses configured. ```typescript import { LendingPool, InterestRate, PermitSignature, } from '@aave/contract-helpers'; const lendingPool = new LendingPool(provider, { LENDING_POOL: lendingPoolAddress, REPAY_WITH_COLLATERAL_ADAPTER: repayWithCollateralAddress, WETH_GATEWAY: wethGatewayAddress, }); /* - @param `user` The ethereum address that will liquidate the position - @param `fromAsset` The ethereum address of the asset you want to repay with (collateral) - @param `fromAToken` The ethereum address of the aToken of the asset you want to repay with (collateral) - @param `assetToRepay` The ethereum address of the asset you want to repay - @param `repayWithAmount` The amount of collateral you want to repay the debt with - @param `repayAmount` The amount of debt you want to repay - @param `permitSignature` A permit signature of the tx. Optional - @param @optional `repayAllDebt` Bool indicating if the user wants to repay all current debt. Defaults to false - @param `rateMode` //Enum indicating the type of the interest rate of the collateral - @param @optional `onBehalfOf` The ethereum address for which user is swapping. It will default to the user address - @param @optional `referralCode` Integrators are assigned a referral code and can potentially receive rewards. It defaults to 0 (no referrer) - @param @optional `flash` If the transaction will be executed through a flashloan(true) or will be done directly through the adapters(false). Defaults to false - @param @optional `useEthPath` Boolean to indicate if the swap will use an ETH path. Defaults to false */ const txs: EthereumTransactionTypeExtended[] = await lendingPool.repayWithCollateral({ user, fromAsset, fromAToken, assetToRepay, repayWithAmount, repayAmount, permitSignature, repayAllDebt, rateMode, onBehalfOf, referralCode, flash, useEthPath, }); ``` -------------------------------- ### StakingService - Stake with Permit (Gasless) Source: https://context7.com/aave/aave-utilities/llms.txt Stake tokens using a gasless permit signature approval. This method requires generating signature data, obtaining a signature from the wallet, and then staking with the permit. ```typescript import { StakingService } from '@aave/contract-helpers'; const stakingService = new StakingService(provider, { TOKEN_STAKING_ADDRESS: '0xStkAAVEAddress', }); const deadline = Math.floor(Date.now() / 1000 + 3600).toString(); // Generate signature data const dataToSign = await stakingService.signStaking( '0xUserAddress', '100', deadline ); // Get signature from wallet const signature = await provider.send('eth_signTypedData_v4', [ '0xUserAddress', dataToSign, ]); // Stake with permit const txs = await stakingService.stakeWithPermit( '0xUserAddress', '100', signature, deadline ); const tx = txs[0]; const extendedTxData = await tx.tx(); const signer = provider.getSigner(); await signer.sendTransaction(extendedTxData); ``` -------------------------------- ### Market Options Menu Source: https://github.com/aave/aave-utilities/blob/master/README.md Displays a menu of available actions for interacting with an Aave market. The options presented dynamically adjust based on whether the market is V2 or V3. ```typescript console.log("Type the number of action to perform and press Enter"); console.log("1. Print market addresses"); console.log("2. Print reserves info"); console.log("3. Print user info"); console.log("4. Check approved amount to supply"); console.log("5. Build approval tx"); if (v2) { console.log("6. Build deposit tx"); } else { console.log("6. Build supply tx"); console.log("7. Build signature request"); console.log("8. Build supplyWithPermit tx data"); } console.log(`${v2 ? "7" : "9"}. <- Back`); console.log("\n"); ``` -------------------------------- ### Mint Test Tokens with FaucetService Source: https://context7.com/aave/aave-utilities/llms.txt Obtain test tokens on Aave testnets for development. Ensure the `FaucetAddress` and `TestDAIAddress` are correct for the testnet environment. ```typescript import { FaucetService } from '@aave/contract-helpers'; const faucetService = new FaucetService(provider, '0xFaucetAddress'); const mintTx = faucetService.mint({ userAddress: '0xUserAddress', reserve: '0xTestDAIAddress', tokenSymbol: 'DAI', }); const signer = provider.getSigner(); await signer.sendTransaction(await mintTx.tx()); ``` -------------------------------- ### Format User Portfolio Summary Source: https://context7.com/aave/aave-utilities/llms.txt Calculates a comprehensive user portfolio summary, including health factor, total collateral, and available borrowing power. Requires current timestamp, market reference data, user reserves, formatted reserve data, and user's eMode category ID. ```typescript import { formatUserSummary } from '@aave/math-utils'; import dayjs from 'dayjs'; const userSummary = formatUserSummary({ currentTimestamp: dayjs().unix(), marketReferencePriceInUsd: baseCurrencyData.marketReferenceCurrencyPriceInUsd, marketReferenceCurrencyDecimals: baseCurrencyData.marketReferenceCurrencyDecimals, userReserves: userReserves.userReserves, formattedReserves: formattedReserves, userEmodeCategoryId: userReserves.userEmodeCategoryId, }); console.log('Health Factor:', userSummary.healthFactor); console.log('Total Collateral USD:', userSummary.totalCollateralUSD); console.log('Total Borrows USD:', userSummary.totalBorrowsUSD); console.log('Available to Borrow USD:', userSummary.availableBorrowsUSD); console.log('Net Worth USD:', userSummary.netWorthUSD); console.log('Current LTV:', userSummary.currentLoanToValue); console.log('Liquidation Threshold:', userSummary.currentLiquidationThreshold); ``` -------------------------------- ### TypeScript Configuration for New Package Source: https://github.com/aave/aave-utilities/blob/master/CONTRIBUTING.md Use this tsconfig.json configuration when setting up a new package. It extends the root tsconfig and specifies output directories for ES modules and source directory. ```json { "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "./dist/esm", "rootDir": "src" } } ``` -------------------------------- ### Mint Testnet Tokens with Faucet Service Source: https://github.com/aave/aave-utilities/blob/master/README.md Use the FaucetService to mint a fixed amount of tokens on a test network for Aave protocol usage. Requires the provider, faucet address, user's address, reserve address, and token symbol. ```typescript import { FaucetService } from '@aave/contract-helpers'; const faucetService = new FaucetService(provider, faucetAddress); /* - @param `userAddress` The ethereum address of the wallet the minted tokens will go - @param `reserve` The ethereum address of the token you want to mint - @param `tokenSymbol` The symbol of the token you want to mint */ const tx = faucet.mint({ userAddress, reserve, tokenSymbol }); ``` -------------------------------- ### Swap Collateral Source: https://github.com/aave/aave-utilities/blob/master/README.md Allows users to swap a collateral to another asset. ```APIDOC ## POST /api/swapCollateral ### Description Allows users to swap a collateral to another asset. ### Method POST ### Endpoint /api/swapCollateral ### Parameters #### Request Body - **user** (string) - Required - The ethereum address that will liquidate the position - **flash** (boolean) - Optional - If the transaction will be executed through a flashloan(true) or will be done directly through the adapters(false). Defaults to false - **fromAsset** (string) - Required - The ethereum address of the asset you want to swap - **fromAToken** (string) - Required - The ethereum address of the aToken of the asset you want to swap - **toAsset** (string) - Required - The ethereum address of the asset you want to swap to (get) - **fromAmount** (string) - Required - The amount you want to swap - **toAmount** (string) - Required - The amount you want to get after the swap - **maxSlippage** (number) - Required - The max slippage that the user accepts in the swap - **permitSignature** (object) - Optional - A permit signature of the tx. Only needed when previously signed (Not needed at the moment). - **swapAll** (boolean) - Required - Bool indicating if the user wants to swap all the current collateral - **onBehalfOf** (string) - Optional - The ethereum address for which user is swapping. It will default to the user address - **referralCode** (number) - Optional - Integrators are assigned a referral code and can potentially receive rewards. It defaults to 0 (no referrer) - **useEthPath** (boolean) - Optional - Boolean to indicate if the swap will use an ETH path. Defaults to false ### Request Example { "user": "0x...", "flash": false, "fromAsset": "0x...", "fromAToken": "0x...", "toAsset": "0x...", "fromAmount": "1000000000000000000", "toAmount": "950000000000000000", "maxSlippage": 0.01, "swapAll": false, "onBehalfOf": "0x...", "referralCode": 10, "useEthPath": false } ### Response #### Success Response (200) - **transactionHash** (string) - The hash of the transaction submitted. #### Response Example { "transactionHash": "0x..." } ``` -------------------------------- ### POST /swapBorrowRateMode Source: https://github.com/aave/aave-utilities/blob/master/README.md Allows borrowers to swap between stable and variable borrow rate modes. ```APIDOC ## POST /swapBorrowRateMode (V3) ### Description Borrowers can use this function to swap between stable and variable borrow rate modes. ### Method POST ### Endpoint /swapBorrowRateMode ### Parameters #### Request Body - **user** (string) - Required - The ethereum address that will make the swap. - **reserve** (string) - Required - The ethereum address of the reserve. - **interestRateMode** (InterestRate) - Required - The rate mode to swap to, stable or variable. - **amount** (string) - Required - The amount to swap. - **onBehalfOf** (string) - Optional - The ethereum address for which the user is swapping. It will default to the user address. ### Request Example ```json { "user": "0x...", "reserve": "0x...", "interestRateMode": "InterestRate.Stable", "amount": "1000000000000000000", "onBehalfOf": "0x..." } ``` ### Response #### Success Response (200) - **txs** (Array) - An array of extended Ethereum transactions. #### Response Example ```json { "txs": [ { "tx": { "to": "0x...", "from": "0x...", "data": "0x..." }, "txType": "..." } ] } ``` ``` -------------------------------- ### Format Aave Market Reserves with @aave/math-utils Source: https://github.com/aave/aave-utilities/blob/master/README.md Use this function to format configuration and live usage data for each reserve in an Aave market. Ensure you have the necessary reserve data and base currency information. ```javascript import { formatReserves } from '@aave/math-utils'; import dayjs from 'dayjs'; // `reserves` variable here is input from Setup section const reservesArray = reserves.reservesData; const baseCurrencyData = reserves.baseCurrencyData; const currentTimestamp = dayjs().unix(); /* - @param `reserves` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserves.reservesArray` - @param `currentTimestamp` Current UNIX timestamp in seconds - @param `marketReferencePriceInUsd` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserves.baseCurrencyData.marketReferencePriceInUsd` - @param `marketReferenceCurrencyDecimals` Input from [Fetching Protocol Data](#fetching-protocol-data), `reserves.baseCurrencyData.marketReferenceCurrencyDecimals` */ const formattedPoolReserves = formatReserves({ reserves: reservesArray, currentTimestamp, marketReferenceCurrencyDecimals: baseCurrencyData.marketReferenceCurrencyDecimals, marketReferencePriceInUsd: baseCurrencyData.marketReferenceCurrencyPriceInUsd, }); ```