### Install and Run Development Server Source: https://docs.morpho.org/llms-full.txt Installs project dependencies and starts the development server for the Merkl Morpho Recipe. ```bash git clone https://github.com/morpho-org/merkl-morpho-recipe.git cd merkl-morpho-recipe yarn install yarn dev # Open http://localhost:3000 ``` -------------------------------- ### Install Dependencies and Setup Viem Client Source: https://docs.morpho.org/llms-full.txt Install the necessary Viem and Morpho SDK packages. Set up a Viem client with a wallet, chain, and transport, extending it with public actions for blockchain interactions. ```bash npm install viem @morpho-org/blue-sdk @morpho-org/morpho-ts ``` ```typescript import { createWalletClient, http, publicActions, parseUnits } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { mainnet } from "viem/chains"; import { IMorpho_ABI } from "@morpho-org/morpho-ts"; const morphoAddress = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"; const marketParams = { ... }; // Your target market's parameters const account = privateKeyToAccount("0x..."); const client = createWalletClient({ account, chain: mainnet, transport: http(process.env.RPC_URL_MAINNET), }).extend(publicActions); ``` -------------------------------- ### Install Morpho SDK Source: https://docs.morpho.org/tools/offchain/sdks/get-started Install the default Morpho SDK and viem for building on the Morpho protocol. This is the recommended starting point for application integrators. ```bash pnpm add @morpho-org/morpho-sdk viem ``` -------------------------------- ### Clone and Run Morpho Merkl Demo Source: https://docs.morpho.org/build/rewards/guides/complete-integration Quick start guide to clone the repository, install dependencies, and run the development server for the Morpho Merkl recipe. ```bash # Clone the repository git clone https://github.com/morpho-org/merkl-morpho-recipe.git cd merkl-morpho-recipe # Install dependencies yarn install # Run the development server yarn dev # Open http://localhost:3000 ``` -------------------------------- ### Install blue-sdk-viem and Dependencies Source: https://docs.morpho.org/tools/offchain/sdks/blue-sdk-viem Install the blue-sdk-viem package along with its peer dependencies using yarn. ```bash yarn add @morpho-org/blue-sdk @morpho-org/blue-sdk-viem @morpho-org/morpho-ts viem dotenv ``` -------------------------------- ### Install Morpho SDK and viem Source: https://docs.morpho.org/tools/offchain/sdks/morpho-sdk Install the Morpho SDK and its peer dependency viem using your preferred package manager. ```bash pnpm add @morpho-org/morpho-sdk viem # or yarn add @morpho-org/morpho-sdk viem # or npm install @morpho-org/morpho-sdk viem ``` -------------------------------- ### Install Viem Package Source: https://docs.morpho.org/build/earn/tutorials/assets-flow Install the Viem package to enable direct interaction with blockchain contracts. ```bash npm install viem ``` -------------------------------- ### Install Bundler SDK and Dependencies Source: https://docs.morpho.org/build/borrow/tutorials/public-allocator Installs the necessary packages for using the bundler-sdk-viem to construct and simulate complex DeFi operations atomically. ```bash yarn add @morpho-org/bundler-sdk-viem @morpho-org/blue-sdk @morpho-org/morpho-ts viem ``` -------------------------------- ### Install Morpho SDK Dependencies Source: https://docs.morpho.org/build/borrow/tutorials/assets-flow Install the necessary Viem and Morpho SDK packages for your project. ```bash npm install viem @morpho-org/blue-sdk @morpho-org/morpho-ts ``` -------------------------------- ### Example Rate Calculations Source: https://docs.morpho.org/llms-pages.json Demonstrates the calculation of borrow and supply APY using provided example values for rate, utilization, and fee. ```typescript // Shared example values const secondsInYear = 31536000; const ratePerSecond = "1512768697"; // Rate per second in Wei (18 decimals) const utilization = 0.85; // 85% utilization const fee = "0"; // No fee (0 in Wei / 18 decimals) // Calculate borrow APY const borrowAPY = calculateBorrowRate(ratePerSecond, secondsInYear); // Calculate supply APY const sup ``` -------------------------------- ### Comprehensive Asset Analysis in TypeScript Source: https://docs.morpho.org/llms-full.txt This TypeScript example demonstrates fetching and displaying detailed asset information, including basic metadata, supply, EIP-2612 support, user balances, and portfolio analysis. It utilizes multicall for efficient batch processing and formats large numbers for readability. Setup includes client configuration, ABIs, and helper functions. ```typescript // [!include ~/snippets/typescript/54-assets.ts:imports] ``` ```typescript // [!include ~/snippets/typescript/54-assets.ts:client-setup] ``` ```typescript // [!include ~/snippets/typescript/54-assets.ts:abis-and-constants] ``` ```typescript // [!include ~/snippets/typescript/54-assets.ts:types] ``` ```typescript // [!include ~/snippets/typescript/54-assets.ts:helper-functions] ``` ```typescript // [!include ~/snippets/typescript/54-assets.ts:core-logic] ``` ```typescript // [!include ~/snippets/typescript/54-assets.ts:display-results] ``` ```typescript // [!include ~/snippets/typescript/54-assets.ts:main-execution] ``` -------------------------------- ### Install Morpho SDK and Viem (TypeScript) Source: https://docs.morpho.org/build/borrow/tutorials/assets-flow Installs the necessary packages for integrating with Morpho Blue using the Morpho SDK and Viem. This is the first step for offchain integrations. ```bash npm install @morpho-org/morpho-sdk viem # or pnpm add @morpho-org/morpho-sdk viem # or yarn add @morpho-org/morpho-sdk viem ``` -------------------------------- ### Solidity Integration Example for reallocateTo Source: https://docs.morpho.org/tools/onchain/public-allocator A simplified Solidity example demonstrating how to construct and call the reallocateTo function. Ensure withdrawals are sorted by market ID and the correct fee is included in msg.value. ```solidity // Assuming IPublicAllocator and IMetaMorpho interfaces are available IPublicAllocator publicAllocator = IPublicAllocator(PA_ADDRESS); IMetaMorpho vault = IMetaMorpho(VAULT_ADDRESS); // 1. Check prerequisites require(vault.isAllocator(address(publicAllocator)), "PA: Not an allocator"); uint256 requiredFee = publicAllocator.fee(address(vault)); // 2. Prepare withdrawal parameters (must be sorted by market ID) Withdrawal[] memory withdrawals = new Withdrawal[](2); // Withdrawal from Market A (e.g., Idle Market) withdrawals[0] = Withdrawal({ marketParams: marketAParams, // MarketParams for Market A amount: 70 * 1e18 }); // Withdrawal from Market B (e.g., wstETH Market) // The ID of Market B must be greater than the ID of Market A withdrawals[1] = Withdrawal({ marketParams: marketBParams, // MarketParams for Market B amount: 800 * 1e18 }); // 3. Define the destination market MarketParams memory supplyMarketParams = rETHMarketParams; // MarketParams for rETH Market // 4. Execute the reallocation publicAllocator.reallocateTo{value: requiredFee}( address(vault), withdrawals, supplyMarketParams ); ``` -------------------------------- ### Example Reallocation with Target Allocations Source: https://docs.morpho.org/llms-full.txt Illustrates how to structure the allocations array to shift funds between markets. This example targets specific amounts for Market A and Market B. ```json [ { "marketParams": { ...Market A params... }, "assets": "50000000000000000000" // Target: 50 WETH }, { "marketParams": { ...Market B params... }, "assets": "20000000000000000000" // Target: 20 WETH } ] ``` -------------------------------- ### Basic Blue SDK Usage Example Source: https://docs.morpho.org/tools/offchain/sdks/blue-sdk Demonstrates creating a market configuration, initializing a market, and performing basic operations like accruing interest and converting shares to assets. ```typescript // Create a new market configuration using MarketParams const config = new MarketParams({ loanToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH collateralToken: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0", // wstETH oracle: "0x2a01EB9496094dA03c4E364Def50f5aD1280AD72", irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC", // AdaptiveCurveIrm lltv: 94_5000000000000000n, // 94.5% }); console.log("Market Config ID:", config.id); console.log("Liquidation Incentive Factor:", config.liquidationIncentiveFactor); // Create a new market with the specified configuration const market = new Market({ config, totalSupplyAssets: 1000_000000000000000000n, totalBorrowAssets: 920_000000000000000000n, totalSupplyShares: 1000_000000000000000000000000n, totalBorrowShares: 920_000000000000000000000000n, lastUpdate: 1721000000n, fee: 0n, price: 1_100000000000000000000000000000000000n, rateAtTarget: 94850992095n, }); console.log("Market Utilization:", market.utilization); console.log("Market Liquidity:", market.liquidity); console.log("Market APY at Target:", market.apyAtTarget); // Accrue interest to the latest timestamp const accruedMarket = market.accrueInterest(Time.timestamp()); // Convert supply shares to assets const shares = 1000000000000000000n; console.log("Supply Assets for Shares:", accruedMarket.toSupplyAssets(shares)); ``` -------------------------------- ### Example Variables for Historical Market States Query Source: https://docs.morpho.org/llms-full.txt Example JSON object for variables used in historical market states queries, specifying start timestamp, end timestamp, and interval. Note: 'HOUR' should be quoted. ```json "variables": { "startTimestamp": 1707749700, "endTimestamp": 1708354500, "interval": HOUR, } ``` -------------------------------- ### Get Historical Market Data Source: https://docs.morpho.org/llms-pages.json Allows retrieval of historical market data by specifying a start timestamp, end timestamp, and data interval. ```APIDOC ## GET /historicalState ### Description Retrieves historical data for specific queries. Requires backfilled data to be indexed and stored. Some queries may be deprecated. ### Method GET ### Endpoint /historicalState ### Parameters #### Query Parameters - **startTimestamp** (Int) - Optional - The beginning of the historical data in UNIX timestamp format. - **endTimestamp** (Int) - Optional - The end of the historical data in UNIX timestamp format. - **interval** (String) - Optional - The interval for the historical data points (e.g., "YEAR", "QUARTER", "MONTH", "WEEK", "DAY", "HOUR"). ### Notes - If no variables are specified, default values will be used. It is advised to specify these variables to control the data returned. - Some queries are not backfilled and are flagged as deprecated in the Morpho API sandbox. ``` -------------------------------- ### Setup Viem Client and Imports Source: https://docs.morpho.org/tools/offchain/sdks/blue-sdk-viem Import necessary modules from blue-sdk and blue-sdk-viem, and set up a Viem client for interacting with the Ethereum mainnet. Ensure your RPC_URL_MAINNET is configured in your .env file. ```typescript import { MarketParams, Market, AccrualPosition, MarketId } from "@morpho-org/blue-sdk"; import "@morpho-org/blue-sdk-viem/lib/augment/MarketParams"; import "@morpho-org/blue-sdk-viem/lib/augment/Market"; import "@morpho-org/blue-sdk-viem/lib/augment/Position"; import { createClient, http } from "viem"; import { mainnet } from "viem/chains"; import "dotenv/config"; // Set up the client const client = createClient({ chain: mainnet, transport: http(process.env.RPC_URL_MAINNET), }); ``` -------------------------------- ### Example Variables for Historical APYs Query Source: https://docs.morpho.org/llms-full.txt Example JSON object showing the required and optional variables for querying historical APY data, including market ID, chain ID, and historical options like start timestamp, end timestamp, and interval. ```json { "marketId": "0x9103c3b4e834476c9a62ea009ba2c884ee42e94e6e314a26f04d312434191836", "chainId": 8453, "options": { "startTimestamp": 1755420554, "endTimestamp": 1755506954, "interval": "HOUR" } } ``` -------------------------------- ### Initialize Viem Client and SDK Configuration Source: https://docs.morpho.org/tools/offchain/sdks/blue-sdk-viem Sets up a Viem public client and retrieves chain-specific addresses for the Blue SDK. Requires RPC URL to be configured in environment variables. ```typescript import { http, Address, PublicClient, createPublicClient } from "viem"; import "dotenv/config"; import { getChainAddresses, Market, MarketId, Vault, } from "@morpho-org/blue-sdk"; import "@morpho-org/blue-sdk-viem/lib/augment"; import { base, mainnet } from "viem/chains"; interface APYData { oneDayAPY: number; sevenDayAPY: number; thirtyDayAPY: number; } // Chain-specific blocks per day const BLOCKS_PER_DAY = { MAINNET: BigInt(7000), // Ethereum mainnet: ~7000 blocks per day BASE: BigInt(7000 * 7), // Base: ~7x faster than mainnet }; async function initializeClientAndLoader(chainId: number) { const rpcUrl = chainId === 1 ? process.env.RPC_URL_MAINNET : chainId === 8453 ? process.env.RPC_URL_BASE : undefined; if (!rpcUrl) throw new Error(`No RPC URL configured for chain ID: ${chainId}`); const client = createPublicClient({ chain: chainId === 1 ? mainnet : chainId === 8453 ? base : mainnet, transport: http(rpcUrl), }); const config = getChainAddresses(chainId); if (!config) throw new Error(`Unsupported chain ID: ${chainId}`); return { client, config }; } ``` -------------------------------- ### TypeScript Example for User Position Analysis Source: https://docs.morpho.org/llms-full.txt A comprehensive TypeScript example demonstrating how to fetch and analyze user positions, calculate health factors, and display detailed results. This includes setup, ABI definitions, math helpers, and core logic for real-time position assessment. ```typescript // [!include ~/snippets/typescript/55-user-position.ts:imports] // [!include ~/snippets/typescript/55-user-position.ts:client-setup] // [!include ~/snippets/typescript/55-user-position.ts:abis-and-constants] // [!include ~/snippets/typescript/55-user-position.ts:types] // [!include ~/snippets/typescript/55-user-position.ts:math-helpers] // [!include ~/snippets/typescript/55-user-position.ts:core-logic] // [!include ~/snippets/typescript/55-user-position.ts:display-results] // [!include ~/snippets/typescript/55-user-position.ts:main-execution] ``` -------------------------------- ### Local Development Setup for Morpho SDK Source: https://docs.morpho.org/tools/offchain/sdks/morpho-sdk Clone the Morpho SDK monorepo, install dependencies, build the morpho-sdk package, and link it globally to use in your application. ```bash # Clone the SDKs monorepo git clone https://github.com/morpho-org/sdks.git cd sdks pnpm install --frozen-lockfile # Build the morpho-sdk package pnpm --filter @morpho-org/morpho-sdk build # Link it globally from the package directory cd packages/morpho-sdk pnpm link --global # In your application pnpm link --global @morpho-org/morpho-sdk ``` -------------------------------- ### Morpho SDK Viem Setup Source: https://docs.morpho.org/llms-pages.json Set up the Morpho SDK with Viem by importing necessary modules and creating a wallet client. Ensure dotenv is configured for environment variables. ```typescript import "dotenv/config"; import { type Address, createWalletClient, http } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { mainnet } from "viem/chains"; import { morphoViemExtens ``` -------------------------------- ### Viem Client Setup Source: https://docs.morpho.org/llms-all.txt Set up a Viem wallet client for interacting with Ethereum mainnet. Ensure you have your private key and RPC URL configured. ```typescript import { createWalletClient, http, publicActions, parseUnits } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { mainnet } from "viem/chains"; import { IMorpho_ABI } from "@morpho-org/morpho-ts"; const morphoAddress = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"; const marketParams = { ... }; // Your target market's parameters const account = privateKeyToAccount("0x..."); const client = createWalletClient({ account, chain: mainnet, transport: http(process.env.RPC_URL_MAINNET), }).extend(publicActions); ``` -------------------------------- ### GraphQL Variables for Historical Market States Source: https://docs.morpho.org/llms-all.txt Example variables for historical market states, including start and end timestamps and interval. Note: 'HOUR' should be quoted. ```json { "variables": { "startTimestamp": 1707749700, "endTimestamp": 1708354500, "interval": "HOUR", } } ``` -------------------------------- ### Fetch and Display Morpho Vault V2 Configuration (TypeScript) Source: https://docs.morpho.org/llms-full.txt This TypeScript example demonstrates how to retrieve and display comprehensive configuration details for a Morpho Vault V2. It includes setup, ABI constants, helper functions, and the core logic for fetching and presenting the data. ```typescript // [!include ~/snippets/typescript/07-vault-configuration-v2.ts:imports] // [!include ~/snippets/typescript/07-vault-configuration-v2.ts:client-setup] // [!include ~/snippets/typescript/07-vault-configuration-v2.ts:abis-and-constants] // [!include ~/snippets/typescript/07-vault-configuration-v2.ts:types] // [!include ~/snippets/typescript/07-vault-configuration-v2.ts:helper-functions] // [!include ~/snippets/typescript/07-vault-configuration-v2.ts:core-logic] // [!include ~/snippets/typescript/07-vault-configuration-v2.ts:display-results] // [!include ~/snippets/typescript/07-vault-configuration-v2.ts:main-execution] ``` -------------------------------- ### Calculate Market APYs (TypeScript) Source: https://docs.morpho.org/llms-full.txt This comprehensive TypeScript example demonstrates how to calculate real-time market APYs, including interest accrual, IRM calculations, and fee impacts. It requires setup of client, ABIs, constants, types, math helpers, and core logic. ```typescript // [!include ~/snippets/typescript/52-market-apys.ts:imports] // [!include ~/snippets/typescript/52-market-apys.ts:client-setup] // [!include ~/snippets/typescript/52-market-apys.ts:abis-and-constants] // [!include ~/snippets/typescript/52-market-apys.ts:types] // [!include ~/snippets/typescript/52-market-apys.ts:math-helpers] // [!include ~/snippets/typescript/52-market-apys.ts:core-logic] // [!include ~/snippets/typescript/52-market-apys.ts:display-results] // [!include ~/snippets/typescript/52-market-apys.ts:main-execution] ``` -------------------------------- ### Setup Viem Client and ABIs Source: https://docs.morpho.org/build/earn/tutorials/assets-flow Configure your Viem client with necessary chain details and import ABIs for vault interactions. Ensure you have the correct vault and asset addresses. ```typescript import { createWalletClient, http, parseAbi, publicActions, parseUnits } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { mainnet } from "viem/chains"; const vaultAbi = parseAbi([ "function deposit(uint256 assets, address receiver) returns (uint256 shares)", "function redeem(uint256 shares, address receiver, address owner) returns (uint256 assets)", "function balanceOf(address owner) view returns (uint256)", ]); const vaultAddress = "0x..."; // The vault address const assetAddress = "0x..."; // The vault's underlying asset address const account = privateKeyToAccount("0x..."); // The user's account const client = createWalletClient({ account, chain: mainnet, transport: http(process.env.RPC_URL_MAINNET), }).extend(publicActions); ``` -------------------------------- ### Clone and Run Morpho Merkl Recipe Demo Source: https://docs.morpho.org/llms-pages.json Instructions for setting up and running the Morpho Merkl Recipe demo locally. Requires Node.js 18+, yarn, and a wallet with Morpho positions for testing. ```bash # Clone the repository git clone https://github.com/morpho-org/merkl-morpho-recipe.git cd merkl-morpho-recipe # Install dependencies yarn install # Run the development server yarn dev # Open http://localhost:3000 ``` -------------------------------- ### Initialize Morpho Viem Client Source: https://docs.morpho.org/llms-full.txt Set up a Viem wallet client extended with Morpho's SDK, configuring chain, account, and optional signature support. ```typescript import { createWalletClient, http } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { mainnet } from "viem/chains"; import { morphoViemExtension } from "@morpho-org/morpho-sdk"; const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`); const client = createWalletClient({ account, chain: mainnet, transport: http(process.env.RPC_URL_MAINNET), }).extend( morphoViemExtension({ // Enables Permit / Permit2 in getRequirements() so users skip the extra approve tx. supportSignature: true, }), ); const vault = client.morpho.vaultV2("0xVaultAddress...", mainnet.id); ``` -------------------------------- ### Install Bundler SDK and Dependencies Source: https://docs.morpho.org/llms-full.txt Install the bundler package and its required peer dependencies using yarn. ```bash yarn add @morpho/bundler-sdk-viem @morpho/blue-sdk @morpho/morpho-ts viem ``` -------------------------------- ### Blue SDK Full Code Example Source: https://docs.morpho.org/tools/offchain/sdks/blue-sdk This snippet demonstrates the core functionalities of the Blue SDK, including market configuration, market instantiation, interest accrual, share conversion, and position management. Ensure you have the necessary SDK imports and understand the token addresses and parameters used. ```typescript import { MarketParams, Market, AccrualPosition, Position, } from "@morpho-org/blue-sdk"; import { Time } from "@morpho-org/morpho-ts"; // Create a new market configuration using MarketParams const config = new MarketParams({ loanToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH collateralToken: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0", // wstETH oracle: "0x2a01EB9496094dA03c4E364Def50f5aD1280AD72", irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC", // AdaptiveCurveIrm lltv: 94_5000000000000000n, // 94.5% }); console.log("Market Config ID:", config.id); console.log("Liquidation Incentive Factor:", config.liquidationIncentiveFactor); // Create a new market with the specified configuration const market = new Market({ params: config, totalSupplyAssets: 1000_000000000000000000n, totalBorrowAssets: 920_000000000000000000n, totalSupplyShares: 1000_000000000000000000000000n, totalBorrowShares: 920_000000000000000000000000n, lastUpdate: 1721000000n, fee: 0n, price: 1_100000000000000000000000000000000000n, rateAtTarget: 94850992095n, }); console.log("Market Utilization:", market.utilization); console.log("Market Liquidity:", market.liquidity); console.log("Market APY at Target:", market.apyAtTarget); // Accrue interest to the latest timestamp const accruedMarket = market.accrueInterest(Time.timestamp()); // Convert supply shares to assets const shares = 1000000000000000000n; console.log("Supply Assets for Shares:", accruedMarket.toSupplyAssets(shares)); // Create a new position in the market const position = new AccrualPosition( new Position({ user: "0xCDB238D68d8Da74487711bC1F8f13f3d00667D1A", // Replace with actual user address marketId: market.id, supplyShares: 0n, borrowShares: 20_000000000000000000000000n, collateral: 27_000000000000000000n, }), market ); console.log("Borrow Assets:", position.borrowAssets); console.log("Is Position Healthy:", position.isHealthy); console.log("Max Borrowable Assets:", position.maxBorrowableAssets); // Accrue interest for the position to the latest timestamp const accruedPosition = position.accrueInterest(Time.timestamp()); console.log("Accrued Borrow Assets:", accruedPosition.borrowAssets); ``` -------------------------------- ### Example Usage of Blue SDK VIEM Source: https://docs.morpho.org/tools/offchain/sdks/blue-sdk-viem Demonstrates how to use the Blue SDK VIEM to fetch and display historical APY data for vaults and markets across different chains. ```typescript // Example usage async function main() { const testCases = [ { chain: "Base", chainId: 8453, vaultAddress: "0xc1256Ae5FF1cf2719D4937adb3bbCCab2E00A2Ca" as Address, marketId: "0x1c21c59df9db44bf6f645d854ee710a8ca17b479451447e9f56758aee10a2fad" as MarketId, }, ]; for (const test of testCases) { try { console.log(`\nFetching APY data for ${test.chain}...`); const vaultApyData = await fetchHistoricalVaultData( test.vaultAddress, test.chainId ); console.log("Vault APY Data:", { "1D APY": `${vaultApyData.oneDayAPY}%`, "7D APY": `${vaultApyData.sevenDayAPY}%`, "30D APY": `${vaultApyData.thirtyDayAPY}%`, }); const marketApyData = await fetchHistoricalMarketData( test.marketId, test.chainId ); console.log("Market APY Data:", { "1D APY": `${marketApyData.oneDayAPY}%`, "7D APY": `${marketApyData.sevenDayAPY}%`, "30D APY": `${marketApyData.thirtyDayAPY}%`, }); } catch (error) { console.error(`Error fetching data for ${test.chain}:`, error); } } } main().catch(console.error); ``` -------------------------------- ### Clone Repository and Install Dependencies Source: https://docs.morpho.org/curate/tutorials-v2/vault-creation Clone the vault-v2-deployment repository and install necessary dependencies using Forge. ```bash git clone https://github.com/morpho-org/vault-v2-deployment cd vault-v2-deployment forge install ``` -------------------------------- ### Viem Client Setup and Market Parameter Decoding Source: https://docs.morpho.org/llms-all.txt Sets up a Viem public client for Ethereum mainnet and demonstrates decoding market parameters from an ID. Includes functions for fetching token info and checking market existence. ```typescript import "dotenv/config"; import { createPublicClient, http, PublicClient, parseAbi, Address, keccak256, encodeAbiParameters, parseAbiParameters, formatUnits, } from "viem"; import { mainnet } from "viem/chains"; export function createMainnetClient(): PublicClient { const rpcUrl = process.env.RPC_URL_MAINNET; if (!rpcUrl) { throw new Error( "RPC_URL_MAINNET is not set in the .env file. Please add it." ); } return createPublicClient({ chain: mainnet, transport: http(rpcUrl, { retryCount: 2, batch: { batchSize: 100, wait: 200, }, }), batch: { multicall: { batchSize: 2048, wait: 100, }, }, }); } // Morpho V1 contract address const MORPHO_BLUE_ADDRESS: Address = "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb"; // Example market ID to demonstrate const EXAMPLE_MARKET_ID: `0x${string}` = "0x9a33209eee9e93f5f7aed04085f9f5e0ce9a7a103c476f5c30a0e5ca03c3d540"; // Minimal Morpho V1 ABI for market parameters const MORPHO_BLUE_ABI = parseAbi([ "function idToMarketParams(bytes32 id) view returns (address loanToken, address collateralToken, address oracle, address irm, uint256 lltv)", "function market(bytes32 id) view returns (uint128 totalSupplyAssets, uint128 totalSupplyShares, uint128 totalBorrowAssets, uint128 totalBorrowShares, uint128 lastUpdate, uint128 fee)", ]); // ERC20 ABI for token information const ERC20_ABI = parseAbi([ "function symbol() view returns (string)", "function name() view returns (string)", "function decimals() view returns (uint8)", ]); interface MarketParams { loanToken: Address; collateralToken: Address; oracle: Address; irm: Address; lltv: bigint; } interface TokenInfo { address: Address; symbol: string; name: string; decimals: number; } interface MarketInfo { id: `0x${string}`; params: MarketParams; loanToken: TokenInfo; collateralToken: TokenInfo; lltvPercentage: number; exists: boolean; } interface MarketState { totalSupplyAssets: bigint; totalSupplyShares: bigint; totalBorrowAssets: bigint; totalBorrowShares: bigint; lastUpdate: bigint; fee: bigint; } /** * Converts LLTV from WAD format to percentage */ function formatLLTV(lltv: bigint): number { return Number(formatUnits(lltv, 18)) * 100; } /** * Fetches token information for a given address */ async function getTokenInfo( client: PublicClient, tokenAddress: Address ): Promise { try { const [symbol, name, decimals] = await client.multicall({ contracts: [ { address: tokenAddress, abi: ERC20_ABI, functionName: "symbol" }, { address: tokenAddress, abi: ERC20_ABI, functionName: "name" }, { address: tokenAddress, abi: ERC20_ABI, functionName: "decimals" }, ], allowFailure: false, }); return { address: tokenAddress, symbol, name, decimals, }; } catch (error) { // If token info fails, return address as fallback return { address: tokenAddress, symbol: `Token(${tokenAddress.slice(0, 6)}...)`, name: `Unknown Token ${tokenAddress.slice(0, 6)}...`, decimals: 18, // Default fallback }; } } /** * Checks if a market exists by verifying if any of its state values are non-zero */ async function checkMarketExists( client: PublicClient, marketId: `0x${string}` ): Promise { try { const marketState = await client.readContract({ address: MORPHO_BLUE_ADDRESS, abi: MORPHO_BLUE_ABI, functionName: "market", args: [marketId], }) as [bigint, bigint, bigint, bigint, bigint, bigint]; // Market exists if it has been created (any non-zero state indicates creation) return marketState.some(value => value > 0n); } catch (error) { return false; } } ``` -------------------------------- ### Install Blue SDK Dependencies Source: https://docs.morpho.org/tools/offchain/sdks/blue-sdk Install the necessary dependencies for the Morpho Blue SDK and related packages using yarn. ```bash yarn add @morpho-org/blue-sdk @morpho-org/morpho-ts ``` -------------------------------- ### Install Dependencies for Gelato and Dynamic Integration Source: https://docs.morpho.org/build/borrow/guides/gelato Install necessary packages from Gelato, Dynamic, and other required libraries for your React application. ```bash npm install @gelatonetwork/smartwallet @dynamic-labs/sdk-react-core @dynamic-labs/wagmi-connector @tanstack/react-query viem wagmi ``` -------------------------------- ### Initial Vault V2 Setup with Zero Timelock Source: https://docs.morpho.org/curate/tutorials-v2/roles This script handles the complete initial setup of a Vault V2, including setting the broadcaster as temporary owner and curator, submitting allocator role assignments, and executing them immediately. ```solidity pragma solidity 0.8.28; import {VaultV2} from "vault-v2/VaultV2.sol"; import {IVaultV2} from "vault-v2/interfaces/IVaultV2.sol"; import {Script} from "forge-std/Script.sol"; contract DeployVaultV2 is Script { address public immutable broadcaster = msg.sender; address public immutable vaultV1; address public immutable asset; address public immutable curator; address public immutable allocator; address public immutable owner; address public immutable sentinel; constructor( address vaultV1_, address asset_, address curator_, address allocator_, address owner_, address sentinel_ ) { vaultV1 = vaultV1_; asset = asset_; curator = curator_; allocator = allocator_; owner = owner_; sentinel = sentinel_; } function run() external { // The script sets the broadcaster as temporary owner and curator VaultV2 vaultV2 = new VaultV2(broadcaster, vaultV1.asset()); vaultV2.setCurator(broadcaster); // Submit allocator role assignments vaultV2.submit(abi.encodeCall(vaultV2.setIsAllocator, (broadcaster, true))); vaultV2.submit(abi.encodeCall(vaultV2.setIsAllocator, (allocator, true))); // Execute immediately (timelock is 0 by default) vaultV2.setIsAllocator(broadcaster, true); vaultV2.setIsAllocator(allocator, true); // After configuration, transfer roles to final addresses vaultV2.setCurator(curator); if (sentinel != address(0)) { vaultV2.setIsSentinel(sentinel, true); } vaultV2.setOwner(owner); } } ``` -------------------------------- ### Example Market Identification Source: https://docs.morpho.org/learn/concepts/market An example of a market identification string, showing wstETH as collateral and WETH as the loan asset with specific parameters. ```text wstETH/WETH (94.5%, ChainlinkOracleV2-wstETHToWETH, AdaptiveCurveIRM) ``` -------------------------------- ### Set up Viem Client with Morpho SDK Extension (TypeScript) Source: https://docs.morpho.org/build/earn/tutorials/assets-flow Initializes a Viem wallet client and extends it with Morpho SDK functionality. Supports EIP-2612 permits for gasless approvals. ```typescript import { createWalletClient, http } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { mainnet } from "viem/chains"; import { morphoViemExtension } from "@morpho-org/morpho-sdk"; const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`); const client = createWalletClient({ account, chain: mainnet, transport: http(process.env.RPC_URL_MAINNET), }).extend( morphoViemExtension({ // Enables Permit / Permit2 in getRequirements() so users skip the extra approve tx. supportSignature: true, }), ); const vault = client.morpho.vaultV2("0xVaultAddress...", mainnet.id); ``` -------------------------------- ### Market ID Generator Example Source: https://docs.morpho.org/learn/concepts/market This is an example of a generated Market ID from the Market ID Generator tool, derived from specific market parameters. ```text 0xbc15a1782163f4be46c23ac61f5da50fed96ad40293f86a5ce0501ce4a246b32 ``` -------------------------------- ### Import and Client Setup for Morpho SDK Source: https://docs.morpho.org/llms-full.txt Imports necessary modules and sets up the viem client with the Morpho SDK extension. This enables the client.morpho namespace. ```typescript // [!include ~/snippets/typescript/morpho-sdk/00-setup.ts:imports] // [!include ~/snippets/typescript/morpho-sdk/00-setup.ts:client-setup] ``` -------------------------------- ### Get All FeeWrappers Yield Source: https://docs.morpho.org/llms-full.txt Retrieves the yield information for all FeeWrappers. Use this query to get yield data across all configured fee wrappers. ```graphql // [!include ~/snippets/api/all-queries.graphql:fee-wrapper-yield-all] ``` -------------------------------- ### Get All FeeWrappers Exposure Source: https://docs.morpho.org/llms-full.txt Retrieves the exposure details for all FeeWrappers. Use this query to get a comprehensive view of exposure across all fee wrappers. ```graphql // [!include ~/snippets/api/all-queries.graphql:fee-wrapper-exposure-all] ```