Overview
Morpho vaults pool deposited assets into lending markets where borrowers pay interest. That interest flows back to depositors automatically. This guide walks through integrating Morpho vaults into a Next.js app with Dynamic embedded wallets. For the final code, see the GitHub repository.How it works
When a user deposits, they receive vault tokens representing their share of the pool. As borrowers pay interest, each vault token becomes redeemable for more of the underlying asset. When the user withdraws, they get back their original deposit plus accrued yield. No claiming or compounding is required. Example: A user deposits 1,000 USDC when each vault token is worth 1.00 USDC. When the token value rises to 1.05 USDC, those tokens are worth 1,050 USDC. APY is variable and adjusts based on borrower demand and the curator’s allocation strategy.Setup
Project setup
Follow the React Quickstart using the Custom setup path: Ethereum (EVM) with Wagmi and viem. Scaffold a Next.js app withcreate-next-app and mirror the provider wiring from the quickstart or the GitHub repository linked above.
In the Dynamic dashboard, enable Ethereum under Chains & Networks, enable Embedded wallets under Wallets, and add your app’s origin under Security → Allowed Origins.
Environment variables
.env.local
Configure networks and constants
The example uses a per-chain network config to support Base, Ethereum mainnet, Arbitrum, Optimism, and Polygon. Createsrc/lib/networks.ts:
src/lib/networks.ts
src/lib/constants.ts which re-exports the legacy values and adds the getApiForChain helper used by the hooks:
src/lib/constants.ts
Set up contract ABIs
Create the ABI files insrc/lib/ABIs/:
- ERC20_ABI.ts — standard token interface (
balanceOf,approve,allowance) - ERC4626_ABI.ts — vault interface (
deposit,withdraw,balanceOf,convertToAssets) - REWARDS_ABI.ts — Morpho rewards distributor (
getUserRewardBalance,getRewardToken) - MORPHO_MARKETS_ABI.ts — core Morpho markets contract
Fetching vault data
Vault list
Createsrc/lib/hooks/useVaultsList.ts to load all available vaults. The hook reads the active chain from wagmi and queries the Morpho API for vaults on that chain:
src/lib/hooks/useVaultsList.ts

Vault detail
When a user selects a vault, fetch its full details (includingassetAddress and assetDecimals) before performing any operations. Note the query uses vault(id:) to fetch a single vault by ID, not by address. Create src/lib/hooks/useVaultDetail.ts:
src/lib/hooks/useVaultDetail.ts
assetAddress and assetDecimals from this hook are passed into useVaultOperations to correctly encode transaction amounts.
Deposit and withdraw
Deposits require a two-step flow: the user must first approve the vault to spend their tokens, then deposit.useVaultOperations handles this automatically — when handleApprove succeeds, it sets a pendingDeposit flag and triggers the deposit automatically via onSuccess. Create src/lib/hooks/useVaultOperations.ts:
src/lib/hooks/useVaultOperations.ts
Wiring it together
On a vault detail page, useuseVaultDetail to load vault data, construct a vaultInfo object from it, and pass that to useVaultOperations. The submit handler checks needsApproval first — if approval is needed, handleApprove fires and the deposit follows automatically once it’s confirmed.
src/app/earn/[vaultId]/page.tsx

Enable transaction simulation
Dynamic’s embedded wallets include built-in transaction previews. To enable, go to Developer Settings → Embedded Wallets → Dynamic in the dashboard and toggle on Show Confirmation UI and Transaction Simulation. Users will see the exact assets being transferred, estimated fees, and the vault contract before confirming.Run the app
http://localhost:3000 to your allowed origins in the Dynamic dashboard under Developer Settings → CORS Origins.