
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
@halodao/protocol-js
Advanced tools
AAVE is a decentralized non-custodial liquidity market protocol where users can participate as depositors or borrowers. The AAVE Protocol is a set of open source smart contracts which facilitate the lending and borrowing of user funds. These contracts, and all user transactions/balances are stored on a public ledger called a blockchain, making them accessible to anyone.
The aave-js package gives developers access to methods for formatting data and executing transactions on the AAVE protocol.
This package uses ethers v5 as peer dependency, so make sure you have installed it in your project.
npm install --save ethers
npm install --save @aave/protocol-js
AAVE aggregates on-chain protocol data into a variety of different subgraphs on TheGraph which can be queried directly using the playground (links below) and integrated into applications directly via TheGraph API.
The aave-js data formatting methods are a layer beyond graphql which wraps protocol data into more usable formats. Each method will require inputs from AAVE subgraph queries, links to these queries in the source code are provided for each method below.
Check out this getting started guide to get your application integrated with the AAVE subgraphs
V1 GraphQL:
V2 GraphQL (V2 Market and AMM Market)
The V2 Subgraph contains data for both the V2 and AMM markets. The market which a reserve belongs to can be identified with the pool parameter (market address). The pool id for available markets are below:
import { v1, v2 } from '@aave/protocol-js';
// Fetch poolReservesData from GQL Subscription
// Fetch rawUserReserves from GQL Subscription
// Fetch ethPriceUSD from GQL Subscription
let userAddress = "0x..."
let userSummary = v2.formatUserSummaryData(poolReservesData, rawUserReserves, userAddress.toLowerCase(), Math.floor(Date.now() / 1000))
Returns formatted summary of AAVE user portfolio including: array of holdings, total liquidity, total collateral, total borrows, liquidation threshold, health factor, and available borrowing power
poolReservesData GraphQL input:
rawUserReserves GraphQL input, query can be found here:
userId Wallet address, MUST BE LOWERCASE!usdPriceEth Current price of USD in ETH in small units (10^18). For example, if ETH price in USD = $1900, usdPriceEth = (1 / 1900) * 10^18
: Can also be fetched using this subscription: /src/[v1 or v2]/graphql/subscriptions/usd-price-eth-update-subscription.graphqlcurrentTimestamp Current Unix timestamp in seconds: Math.floor(Date.now() / 1000)rewardsInfo Information used to compute aTokenRewards (deposit rewards), vTokenRewards (variable debt rewards), and sTokenRewards (stable debt rewards). Object with format:
{
rewardTokenAddress: string;
rewardTokenDecimals: number;
incentivePrecision: number;
rewardTokenPriceEth: string;
emissionEndTimestamp: number;
}
All fields can be fetched from the IncentivesController subgraph entity with the exception of rewardTokenPriceEth. Since reward tokens are not guaranteed to be Aave reserve tokens, the price feed for reward tokens is not directly attached to the controller. For stkAAVE, WMATIC, and WAVAX rewards the reveserve price feed from AAVE, MATIC, and AVAX repectively can be used.v1.formatUserSummaryData(
poolReservesData: ReserveData[],
rawUserReserves: UserReserveData[],
userId: string,
usdPriceEth: BigNumberValue,
currentTimestamp: number
);
v2.formatUserSummaryData(
poolReservesData: ReserveData[],
rawUserReserves: UserReserveData[],
userId: string,
usdPriceEth: BigNumberValue,
currentTimestamp: number,
rewardsInfo?: RewardInformation
);
Returns formatted summary of each AAVE reserve asset
Note: liquidityRate = deposit rate in the return object
reserves GraphQL input:
reservesIndexed30DaysAgo GraphQL input:
currentTimestamp Current Unix timestamp in seconds: Math.floor(Date.now() / 1000)rewardTokenPriceEth Price of reward token in market base currency. Can use the priceInEth from the reserve data if there is a corresponding reserve for the reward token (stkAave -> Aave reserve price, WMATIC -> MATIC reserve price, etc.)emissionEndTimestamp Timestamp of reward emission end. Can be fetched from IncentivesController subgraph entityv1.formatReserves(
reserves: ReserveData[]
reservesIndexed30DaysAgo?: ReserveRatesData[]
);
v2.formatReserves(
reserves: ReserveData[]
reservesIndexed30DaysAgo?: ReserveRatesData[],
currentTimestamp?: number,
rewardTokenPriceEth?: string,
emissionEndTimestamp?: number
);
The library exports the enabled networks and markets in the Aave protocol as the enums Network and Market
import { Network, Market } from '@aave/protocol-js';
import { TxBuilderV2, Network, Market } from '@aave/protocol-js'
const httpProvider = new Web3.providers.HttpProvider(
process.env.ETHEREUM_URL ||
"https://kovan.infura.io/v3/<project_id>"
);
const txBuilder = new TxBuilderV2(Network.main, httpProvider);
lendingPool = txBuilder.getLendingPool(Market.main); // get all lending pool methods
The library accepts 3 kinds of providers:
To learn more about supported providers, see the ethers documentation on providers.
Object that contains all the necessary methods to create Aave lending pool transactions.
The return object will be a Promise array of objects of type:
import { EthereumTransactionTypeExtended } from '@aave/protocol-js'
having {tx, txType}
Deposits the underlying asset into the reserve. A corresponding amount of the overlying asset (aTokens) is minted.
user The ethereum address that will make the depositreserve The ethereum address of the reserveamount The amount to be depositedonBehalfOf The ethereum address for which user is depositing. It will default to the user addressreferralCode Integrators are assigned a referral code and can potentially receive rewards. It defaults to 0 (no referrer)lendingPool.deposit({
user, // string,
reserve, // string,
amount, // string,
onBehalfOf, // ? string,
referralCode, // ? string,
});
If the user is not approved, an approval transaction will also be returned.
Borrow an amount of reserve asset.
User must have a collaterised position (i.e. aTokens in their wallet)
user The ethereum address that will receive the borrowed amountreserve The ethereum address of the reserve assetamount The amount to be borrowed, in human readable units (e.g. 2.5 ETH)interestRateMode Whether the borrow will incur a stable or variable interest rate (1 | 2)debtTokenAddress The ethereum address of the debt token of the asset you want to borrow. Only needed if the reserve is ETH mock addressonBehalfOf The ethereum address for which user is borrowing. It will default to the user addressrefferalCode Integrators are assigned a referral code and can potentially receive rewards. It defaults to 0 (no referrer)enum InterestRate {
None = 'None',
Stable = 'Stable',
Variable = 'Variable',
}
lendingPool.borrow({
user, // string,
reserve, // string,
amount, // string,
interestRateMode, // InterestRate;
debtTokenAddress, // ? string;
onBehalfOf, // ? string;
referralCode, // ? string;
});
Repays a borrow on the specific reserve, for the specified amount (or for the whole amount, if (-1) is specified).
the target user is defined by onBehalfOf. If there is no repayment on behalf of another account, onBehalfOf must be equal to user.
user The ethereum address that repaysreserve The ethereum address of the reserve on which the user borrowedamount The amount to repay, or (-1) if the user wants to repay everythinginterestRateMode Whether the borrow will incur a stable or variable interest rate (1 | 2)onBehalfOf The ethereum address for which user is repaying. It will default to the user addressenum InterestRate {
None = 'None',
Stable = 'Stable',
Variable = 'Variable',
}
lendingPool.repay({
user, // string,
reserve, // string,
amount, // string,
interestRateMode, // InterestRate;
onBehalfOf, // ? string
});
If the user is not approved, an approval transaction will also be returned.
Withdraws the underlying asset of an aToken asset.
user The ethereum address that will receive the aTokensreserve The ethereum address of the reserve assetamount The amount of aToken being redeemedaTokenAddress The ethereum address of the aToken. Only needed if the reserve is ETH mock addressonBehalfOf The amount of aToken being redeemed. It will default to the user addresslendingPool.withdraw({
user, // string,
reserve, // string,
amount, // string,
aTokenAddress, // ? string,
onBehalfOf, // ? string
});
Borrowers can use this function to swap between stable and variable borrow rate modes.
user The ethereum address that wants to swap rate modesreserve The address of the reserve on which the user borrowedinterestRateMode Whether the borrow will incur a stable or variable interest rate (1 | 2)enum InterestRate {
None = 'None',
Stable = 'Stable',
Variable = 'Variable',
}
lendingPool.swapBorrowRateMode({
user, // string,
reserve, // string,
interestRateMode, // InterestRate;
});
Allows depositors to enable or disable a specific deposit as collateral.
user The ethereum address that enables or disables the deposit as collateralreserve The ethereum address of the reserveuseAsCollateral True if the user wants to use the deposit as collateral, false otherwise.lendingPool.setUsageAsCollateral({
user, // string,
reserve, // string,
usageAsCollateral, // boolean
});
Users can invoke this function to liquidate an undercollateralized position.
liquidator The ethereum address that will liquidate the positionliquidatedUser The address of the borrowerdebtReserve The ethereum address of the principal reservecollateralReserve The address of the collateral to liquidatedpurchaseAmount The amount of principal that the liquidator wants to repaygetAToken Boolean to indicate if the user wants to receive the aToken instead of the asset. Defaults to falselendingPool.liquidationCall({
liquidator, // string;
liquidatedUser, // string;
debtReserve, // string;
collateralReserve, // string;
purchaseAmount, // string;
getAToken, // ? boolean;
});
Allows users to swap a collateral to another asset
user The ethereum address that will liquidate the positionflash If the transaction will be executed through a flasloan(true) or will be done directly through the adapters(false). Defaults to falsefromAsset The ethereum address of the asset you want to swapfromAToken The ethereum address of the aToken of the asset you want to swaptoAsset The ethereum address of the asset you want to swap to (get)fromAmount The amount you want to swaptoAmount The amount you want to get after the swapmaxSlippage The max slippage that the user accepts in the swappermitSignature A permit signature of the tx. Only needed when previously signed (Not needed at the moment).swapAll Bool indicating if the user wants to swap all the current collateralonBehalfOf The ethereum address for which user is swaping. It will default to the user addressreferralCode Integrators are assigned a referral code and can potentially receive rewards. It defaults to 0 (no referrer)useEthPath Boolean to indicate if the swap will use an ETH path. Defaults to falsetype PermitSignature = {
amount: tStringCurrencyUnits;
deadline: string;
v: number;
r: BytesLike;
s: BytesLike;
};
await lendingPool.swapCollateral({
user, // string;
flash, // ? boolean;
fromAsset, // string;
fromAToken, // string;
toAsset, // string;
fromAmount, // string;
toAmount, // string;
maxSlippage, // string;
permitSignature, // ? PermitSignature;
swapAll, // boolean;
onBehalfOf, // ? string;
referralCode, // ? string;
useEthPath, // ? boolean;
});
Allows a borrower to repay the open debt with the borrower collateral
user The ethereum address that will liquidate the positionfromAsset The ethereum address of the asset you want to repay with (collateral)fromAToken The ethereum address of the aToken of the asset you want to repay with (collateral)assetToRepay The ethereum address of the asset you want to repayrepayWithAmount The amount of collateral you want to repay the debt withrepayAmount The amount of debt you want to repaypermitSignature A permit signature of the tx. OptionalrepayAllDebt Bool indicating if the user wants to repay all current debt. Defaults to falserateMode Enum indicating the type of the interest rate of the collateralonBehalfOf The ethereum address for which user is swaping. It will default to the user addressreferralCode Integrators are assigned a referral code and can potentially receive rewards. It defaults to 0 (no referrer)flash If the transaction will be executed through a flasloan(true) or will be done directly through the adapters(false). Defaults to falseuseEthPath Boolean to indicate if the swap will use an ETH path. Defaults to falseenum InterestRate {
None = 'None',
Stable = 'Stable',
Variable = 'Variable',
}
await lendingPool.repayWithCollateral({
user, // string;
fromAsset, // string;
fromAToken, // string;
assetToRepay, // string
repayWithAmount, // string;
repayAmount, // string;
permitSignature, // ? PermitSignature;
repayAllDebt, // ? boolean;
rateMode, // InterestRate;
onBehalfOf, // ? string;
referralCode, // ? string;
flash, // ? boolean;
useEthPath, // ? boolean;
});
Example of how to use the governance service
import {
TxBuilderV2,
AaveGovernanceV2Interface,
GovernanceDelegationTokenInterface,
} from '@aave/protocol-js';
const httpProvider = new Web3.providers.HttpProvider(
process.env.ETHEREUM_URL ||
"https://kovan.infura.io/v3/<project_id>"
);
const txBuilder = new TxBuilderV2(Network.main, httpProvider);
const gov2 = txBuilder.aaveGovernanceV2Service;
const powerDelegation = txBuilder.governanceDelegationTokenService;
Creates a Proposal (needs to be validated by the Proposal Validator)
user The ethereum address that will create the proposaltargets list of contracts called by proposal's associated transactionsvalues list of value in wei for each propoposal's associated transactionsignatures list of function signatures (can be empty) to be used when created the callDatacalldatas list of calldatas: if associated signature empty, calldata ready, else calldata is argumentswithDelegatecalls boolean, true = transaction delegatecalls the taget, else calls the targetipfsHash IPFS hash of the proposalexecutor The ExecutorWithTimelock contract that will execute the proposalenum ExecutorType {
Short,
Long,
}
--------
gov2.create({
user. // string;
targets, //string[];
values, // string[];
signatures, // string[];
calldatas, // BytesLike[];
withDelegateCalls, // boolean[];
ipfsHash, // BytesLike;
executor, // ExecutorType;
});
Cancels a Proposal. Callable by the _guardian with relaxed conditions, or by anybody if the conditions of cancellation on the executor are fulfilled
user The ethereum address that will create the proposalproposalId Id of the proposal we want to cancelgov2.cancel({
user, // string
proposalId, // number
})
Queue the proposal (If Proposal Succeeded)
user The ethereum address that will create the proposalproposalId Id of the proposal we want to queuegov2.queue({
user, // string
proposalId, // number
})
Execute the proposal (If Proposal Queued)
user The ethereum address that will create the proposalproposalId Id of the proposal we want to executegov2.execute({
user, // string
proposalId, // number
})
Function allowing msg.sender to vote for/against a proposal
user The ethereum address that will create the proposalproposalId Id of the proposal we want to votesupport Bool indicating if you are voting in favor (true) or against (false)gov2.submitVote({
user, // string
proposalId, // number
support, // boolean
})
Method for the user to delegate voting and proposition power to the chosen address
user The ethereum address that will create the proposaldelegatee The ethereum address to which the user wants to delegate proposition power and voting powergovernanceToken The ethereum address of the governance tokenpowerDelegation.delegate({
user, // string
delegatee, // string
governanceToken // string
});
Method for the user to delegate voting or proposition power to the chosen address
user The ethereum address that will create the proposaldelegatee The ethereum address to which the user wants to delegate proposition power and voting powerdelegationType The type of the delegation the user wants to do: voting power ('0') or proposition power ('1')governanceToken The ethereum address of the governance tokenpowerDelegation.delegateByType({
user, // string
delegatee, // string
delegationType, // string
governanceToken // string
});
To use the testnet faucets which are compatible with Aave:
import { TxBuilderV2, Network, Market } from '@aave/protocol-js'
const httpProvider = new Web3.providers.HttpProvider(
process.env.ETHEREUM_URL ||
"https://kovan.infura.io/v3/<project_id>"
);
const txBuilder = new TxBuilderV2(Network.main, httpProvider);
const faucet = txBuilder.faucetService;
Mint tokens for the usage on the Aave protocol on the Kovan network. The amount of minted tokens is fixed and depends on the token
userAddress The ethereum address of the wallet the minted tokens will goreserve The ethereum address of the token you want to minttokenSymbol The symbol of the token you want to mintfaucet.mint({
userAddress, // string
reserve, // string
tokenSymbol, // string
});
To lint we use EsLint with typescript plugins and extending Airbnb
npm run lint
To build run:
npm run build // builds with tsdx
npm run build:tsc // builds with tsc
FAQs
HaloDAO protocol data aggregation tool
We found that @halodao/protocol-js demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.