total_deposited and total_withdrawn for a wallet. For all vault providers, Privy computes these totals from the deposits and withdrawals made through Privy Earn. Deposits and withdrawals made directly onchain are not counted.
This recipe shows how your app can read the same values directly from the vault contract for Morpho and Aave vaults. The onchain totals include every deposit and withdrawal for the wallet, no matter how it was sent.
Your app only needs this recipe if wallets interact with a vault outside the Privy Earn
deposit and withdraw endpoints.
For example, your app sends a vault
deposit call with sendTransaction, or users deposit from
another app. If all activity goes through Privy Earn, your app can use the endpoint totals.Resources
Get vault position
The Privy endpoint that returns a wallet’s vault position.
ERC-4626 standard
The tokenized vault standard that Morpho and Aave Earn vaults implement.
Field sources
The table maps each field of the get vault position response to its source in the endpoint and onchain.
The endpoint values for
shares_in_vault and assets_in_vault match the onchain reads. This recipe also shows how to read them onchain, so that your app reads all four values at the same block.
This recipe covers Morpho and Aave vaults.
Prerequisites
- A Privy app with an Earn vault. See Earn setup.
- Your app ID and app secret, for the Privy API.
- An RPC URL for the vault’s chain. The chain ID is the number after
eip155:in the vault’scaip2. - The block number at which the vault contract was deployed. Find the contract creation transaction for the vault address on a block explorer for the vault’s chain.
viem:
1. Get the vault and wallet addresses
The onchain reads need two addresses: the vault contract address and the wallet address. Get the vault address and chain with thevaultDetails method, which calls the get vault details endpoint. Get the wallet address with the get wallet method.
caip2, and asset decimals with the vault ID. These values do not change, so your app only needs to fetch them once per vault.
2. Read the position
The wallet’s position is its vault share balance.convertToAssets returns the value of these shares in the underlying asset, including accrued yield. These two reads return the same values as shares_in_vault and assets_in_vault.
blockNumber reads the position at a past block. Step 4 uses it to keep the position and the totals at the same block.
3. Compute the totals from vault events
Every ERC-4626 vault emits aDeposit event for each deposit and a Withdraw event for each withdrawal. Both events include assets, the amount of the underlying asset in the token’s smallest unit.
Depositindexesreceiver, the address that receives the vault shares.Withdrawindexesowner, the address whose vault shares are burned.
Deposit events by receiver and Withdraw events by owner, then sum assets. Most RPC providers limit the block range of one eth_getLogs request, so the function below scans the range in chunks.
4. Store a checkpoint and scan new blocks
Store the totals and the last scanned block for each wallet and vault. On each read, scan only the blocks after the checkpoint, and add the new amounts to the stored totals.number.
5. Calculate earned yield
Read the position at the checkpoint’slastScannedBlock. This keeps the position and the totals at the same block. If the position is read at the latest block, a deposit in the unscanned blocks increases assetsInVault before it increases totalDeposited, and the earned yield is too high.
10^decimals before your app shows them to users.
Key integration tips
- Read events from the vault address. Use the
vault_addressfrom get vault details. For Morpho, this is the Privy fee wrapper vault, not the underlying Morpho vault. - Share transfers are not deposits. If a wallet receives vault shares through an ERC-20
Transfer, noDepositevent names the wallet. The shares count inassets_in_vault, but not intotal_deposited. The same applies to shares that the wallet sends away. - Use archive access for past blocks. Reads at a past
blockNumberneed an RPC node that keeps historical state. Most hosted RPC providers support this. - Check the block range limit. If
eth_getLogsfails with a range error, lowerMAX_BLOCK_RANGEto your provider’s limit.
Next steps
Earn webhooks
Track Privy Earn deposits and withdrawals in real time.
Get vault details
Retrieve vault-level information like APY, TVL, and available liquidity.

