### Market Blacklist Entry Example Source: https://github.com/morpho-org/morpho-blue-api-metadata/blob/main/README.md An example entry for the markets-blacklist.json file, specifying a market ID, chain ID, and the countries where it is blacklisted. Use '*' for all countries. ```json { "id": "0x495130878b7d2f1391e21589a8bcaef22cbc7e1fbbd6866127193b3cc239d8b1", "chainId": 1, "countryCodes": ["US", "GB"] } ``` -------------------------------- ### Token with Hardcoded Oracle (DAI) Source: https://github.com/morpho-org/morpho-blue-api-metadata/blob/main/README.md This example shows a stablecoin (DAI) configured with 'USDS' as an alternative hardcoded oracle, potentially for specific market pairings. ```json { "chainId": 1, "address": "0x6B175474E89094C44Da98b954EedeAC495271d0F", "symbol": "DAI", "decimals": 18, "name": "Dai Stablecoin", "metadata": { "logoURI": "https://cdn.morpho.org/assets/logos/dai.svg", "tags": ["stablecoin", "usd-pegged", "dai-specific-permit"], "alternativeHardcodedOracles": ["USDS"] }, "isWhitelisted": true, "isListed": true } ``` -------------------------------- ### Token with Alternative Oracle (WETH) Source: https://github.com/morpho-org/morpho-blue-api-metadata/blob/main/README.md Example of a token listing where 'ETH' is specified as an alternative oracle for 'WETH', allowing WETH to be safely used with ETH-denominated oracles. ```json { "name": "Wrapped Ether", "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "symbol": "WETH", "decimals": 18, "chainId": 1, "metadata": { "logoURI": "https://cdn.morpho.org/assets/logos/weth.svg", "alternativeOracles": ["ETH"], "tags": ["eth"] }, "isWhitelisted": true, "isListed": true } ``` -------------------------------- ### Example Curator Entry JSON Source: https://github.com/morpho-org/morpho-blue-api-metadata/blob/main/README.md An example of a curator entry in JSON format. Ensure all fields are present and correctly formatted according to validation rules. ```json { "image": "https://cdn.morpho.org/v2/assets/images/gauntlet.svg", "name": "Gauntlet", "url": "https://www.gauntlet.xyz/", "verified": true, "addresses": { "1": [ "0x123", ], "8453": [ "0x456", ] } }, ``` -------------------------------- ### Running Validation Tests Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Commands to install dependencies and run various test suites, including JSON schema validation and Chainalysis network calls. ```bash # Install dependencies (from repo root) yarn # Run all JSON schema validation tests cd test && yarn test # Run only JSON validation tests (skips Chainalysis network calls) cd test && yarn test:json # Run Chainalysis risk screening tests only (requires CHAINALYSIS_API_TOKEN) cd test && yarn test:chainalysis ``` -------------------------------- ### Example Price Feed Entry Source: https://github.com/morpho-org/morpho-blue-api-metadata/blob/main/README.md This JSON object represents a single price feed entry, specifying details like chain ID, token addresses, vendor, and pair information. ```json { "chainId": 8453, "address": "0x07DA0E54543a844a80ABE69c8A12F22B3aA59f9D", "vendor": "Chainlink", "description": "cbBTC / USD (0.5%)", "pair": ["CBBTC", "USD"], "tokenIn": { "address": "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf", "chainId": 8453 }, "tokenOut": { "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "chainId": 8453 }, "decimals": 8 } ``` -------------------------------- ### Example Token Listing Entry Source: https://github.com/morpho-org/morpho-blue-api-metadata/blob/main/README.md This JSON object defines a token recognized by the protocol, including its chain ID, address, symbol, decimals, name, and metadata. ```json { "chainId": 1, "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "symbol": "USDC", "decimals": 6, "name": "USDCoin", "metadata": { "logoURI": "https://cdn.morpho.org/assets/logos/usdc.svg", "tags": ["stablecoin", "simple-permit"], "alternativeHardcodedOracles": ["USD"] }, "isWhitelisted": true, "isListed": true } ``` -------------------------------- ### GitHub Actions Workflow for Validation Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt This YAML configuration defines GitHub Actions workflows for validating the repository. It includes steps for installing dependencies, running tests, and performing Chainalysis validation on pushes to the main branch. ```yaml # .github/workflows/validation.yml (abbreviated) on: push: branches: [main] pull_request: jobs: test: name: JSON Schema Validation runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: "20", cache: yarn } - run: yarn --frozen-lockfile working-directory: ./test - run: yarn test working-directory: ./test chainalysis: name: Chainalysis Validation if: github.event_name == 'push' && github.ref == 'refs/heads/main' environment: production steps: - run: yarn test:chainalysis working-directory: ./test env: CHAINALYSIS_API_TOKEN: ${{ secrets.CHAINALYSIS_API_TOKEN }} ``` -------------------------------- ### Verify Price Feed Decimals Against On-Chain Values Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt This script iterates through `data/price-feeds.json`, verifies the decimal precision of each price feed contract on-chain using viem, and automatically updates the JSON file if any discrepancies are found. Execute from the 'test' directory. ```bash cd test && ts-node scripts/feedCheck.ts ``` ```text # Starting price feed decimal check... # Loaded 150 price feeds # Checking: cbBTC / USD (0x07DA...) on chain 8453 # On-chain decimals: 8 # Config file decimals: 8 # ✅ Decimals match. # ... # ✅ All feed decimals in the configuration file match the on-chain values. ``` -------------------------------- ### Spot Prices Configuration Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Defines DEX-based spot price sources for assets. Uses the same order/type pattern as oracle prices. The data field must include first_block_number and an optional in_token. ```json // data/spot-prices.json (conceptual entry) { "assetAddress": "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3", "contractAddress": "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640", "order": 0, "type": "uniswap_v3_twap", "data": "{\"first_block_number\": 18000000, \"in_token\": 0}", "assetChainId": 1, "contractChainId": 1 } ``` -------------------------------- ### Price Feed Listing Configuration Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Lists oracle price feed contracts, mapping addresses to vendors, descriptions, and token pairs. Token chain IDs must match the feed's chainId. ```json // data/price-feeds.json (sample entry) { "chainId": 8453, "address": "0x07DA0E54543a844a80ABE69c8A12F22B3aA59f9D", "vendor": "Chainlink", "description": "cbBTC / USD (0.5%)", "pair": ["CBBTC", "USD"], "tokenIn": { "address": "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf", "chainId": 8453 }, "tokenOut": { "address": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE", "chainId": 8453 }, "decimals": 8 } ``` -------------------------------- ### Token with Hardcoded Oracle (USDe) Source: https://github.com/morpho-org/morpho-blue-api-metadata/blob/main/README.md Demonstrates a token (USDe) with 'DAI' and 'USDC' as alternative hardcoded oracles, intended for scenarios where oracles might be intentionally nullified to prevent liquidations. ```json { "chainId": 1, "address": "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3", "name": "USDe", "symbol": "USDe", "decimals": 18, "metadata": { "logoURI": "https://cdn.morpho.org/assets/logos/usde.svg", "alternativeHardcodedOracles": ["DAI", "USDC"], "tags": ["stablecoin", "usd-pegged", "rwa"] }, "isWhitelisted": true, "isListed": true } ``` -------------------------------- ### Report Non-Checksummed Token Addresses Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Run this script to identify and report any token addresses in the configuration that are not properly checksummed. Ensure you are in the 'test' directory before execution. ```bash cd test && ts-node scripts/checksumTokens.ts ``` ```text # Output: # Token: USDC (USDCoin) # Chain ID: 1 # Current: 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 # Checksum: 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 # ------------------- # All addresses are properly checksummed! 🎉 ``` -------------------------------- ### Configure Custom Market Warning Source: https://github.com/morpho-org/morpho-blue-api-metadata/blob/main/README.md Adds a custom warning to a specific market. The 'level' indicates severity, and 'metadata.content' provides the human-readable warning message. ```json { "marketId": "0x9e90aec7d768403dacc9dd0d8320307fda3f980eed4df43e3e52168a1c667709", "chainId": 42161, "level": "red", "metadata": { "content": "This market is experiencing significant volatility. Proceed with caution." } } ``` -------------------------------- ### Oracle Prices Configuration Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Defines on-chain oracle price sources. Each entry specifies the asset, oracle contract, order, type, and type-specific configuration data. Used for pricing assets via various oracle types. ```json // data/oracle-prices.json (sample entries showing a 2-step pricing chain for one asset) [ { "assetAddress": "0x0000000000000000000000000000000000000000", "contractAddress": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419", "order": 0, "type": "chainlink_aggregator", "data": "{\"decimals\": 8}", "assetChainId": 1, "contractChainId": 1 }, { "assetAddress": "0xA8c8861b5ccF8CCe0ade6811CD2A7A7d3222B0B8", "contractAddress": "0x353d0B2EFB5B3a7987fB06D30Ad6160522d08426", "order": 0, "type": "pendle_asset_rate", "data": "{\"decimals\": 18, \"first_block_number\": 21587766}", "assetChainId": 1, "contractChainId": 1 }, { "assetAddress": "0xA8c8861b5ccF8CCe0ade6811CD2A7A7d3222B0B8", "contractAddress": "0xf9C7c25FE58AAA494EE7ff1f6Cf0b70d7C7ce88c", "order": 1, "type": "redstone_without_logs", "data": "{\"decimals\": 8, \"first_block_number\": 21587766}", "assetChainId": 1, "contractChainId": 1 } ] ``` -------------------------------- ### Load JSON File Utility Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Reads and parses a JSON file from the 'data/' directory. Ensure the file exists in the specified path relative to the test utilities. ```typescript // test/utils/jsonValidators.ts import { loadJsonFile, VALID_CHAIN_IDS } from "./utils/jsonValidators"; // Returns the parsed array from data/tokens.json const tokens = loadJsonFile("tokens.json"); // VALID_CHAIN_IDS constant (all supported chain IDs) // [1, 8453, 10, 130, 137, 999, 747474, 42161, 143, 988, 98866, 4217, 480] console.log(VALID_CHAIN_IDS); ``` -------------------------------- ### Fetch with Retry Utility Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Wraps the fetch API to provide resilient HTTP requests with exponential back-off retries. Useful for external API calls that may be temporarily unavailable. ```typescript import { fetchWithRetry } from "./utils/jsonValidators"; // Example: call the Morpho GraphQL API const response = await fetchWithRetry( { input: "https://api.morpho.org/graphql", init: { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ query: " query VaultByAddress($address: String!, $chainId: Int!) { vaultByAddress(address: $address, chainId: $chainId) { address } } ", variables: { address: "0x89BeDBB1C4837444Da215A377275Ff96A84D6f53", chainId: 8453 }, }), }, }, 3 // maxRetries ); const data = await response.json(); // data.data.vaultByAddress.address === "0x89BeDBB1C4837444Da215A377275Ff96A84D6f53" ``` -------------------------------- ### Market Blacklist Configuration Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Restricts specific markets from being displayed based on country codes. A wildcard '*' in countryCodes blacklists a market globally. ```json // data/markets-blacklist.json (sample entries) [ { "id": "0x495130878b7d2f1391e21589a8bcaef22cbc7e1fbbd6866127193b3cc239d8b1", "chainId": 1, "countryCodes": ["US", "GB"] }, { "id": "0x864c9b82eb066ae2c038ba763dfc0221001e62fc40925530056349633eb0a259", "chainId": 1, "countryCodes": ["*"] } ] ``` -------------------------------- ### Configure stETH Token with Alternative Oracles Source: https://github.com/morpho-org/morpho-blue-api-metadata/blob/main/README.md Defines the stETH token with its metadata, including alternative hardcoded oracles like ETH and WETH. This configuration helps manage potential oracle discrepancies. ```json { "chainId": 1, "address": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84", "name": "stETH", "symbol": "stETH", "decimals": 18, "metadata": { "logoURI": "https://cdn.morpho.org/assets/logos/steth.svg", "alternativeHardcodedOracles": ["ETH", "WETH"], "tags": ["yield", "lst", "eth"] }, "isWhitelisted": true, "isListed": true } ``` -------------------------------- ### Define Exchange Rate Configuration for an Asset Source: https://github.com/morpho-org/morpho-blue-api-metadata/blob/main/README.md Specifies how to fetch the exchange rate between an asset and its underlying asset. Ensure all addresses are checksummed and chain IDs are supported. ```json { "assetAddress": "0x83F20F44975D03b1b09e64809B757c47f942BEeA", "contractAddress": "0x83F20F44975D03b1b09e64809B757c47f942BEeA", "data": "{\"abi\": \"function convertToAssets(uint256) view returns (uint256)\", \"decimals\": 18, \"function\": \"convertToAssets\", \"args\": [{\"type\": \"bigint\", \"value\": \"1000000000000000000\"}]}", "assetChainId": 1, "contractChainId": 1 } ``` -------------------------------- ### Tokens Listing Configuration Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt The canonical list of ERC-20 tokens recognized by the protocol. Each entry includes on-chain metadata, logo URI, and optional tags. isListed: true marks tokens active in the UI. ```json // data/tokens.json (sample entries) [ { "chainId": 1, "address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "symbol": "USDC", "decimals": 6, "name": "USDCoin", "metadata": { "logoURI": "https://cdn.morpho.org/assets/logos/usdc.svg", "tags": ["stablecoin", "simple-permit"], "alternativeHardcodedOracles": ["USD"] }, "isWhitelisted": true, "isListed": true }, { "chainId": 1, "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "name": "Wrapped Ether", "symbol": "WETH", "decimals": 18, "metadata": { "logoURI": "https://cdn.morpho.org/assets/logos/weth.svg", "alternativeOracles": ["ETH"], "tags": ["eth"] }, "isWhitelisted": true, "isListed": true }, { "chainId": 1, "address": "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84", "name": "stETH", "symbol": "stETH", "decimals": 18, "metadata": { "logoURI": "https://cdn.morpho.org/assets/logos/steth.svg", "alternativeHardcodedOracles": ["ETH", "WETH"], "tags": ["yield", "lst", "eth"] }, "isWhitelisted": true, "isListed": true } ] ``` -------------------------------- ### Configure Custom Vault Warning Source: https://github.com/morpho-org/morpho-blue-api-metadata/blob/main/README.md Adds a custom warning to a specific vault. The 'level' indicates severity, and 'metadata.content' provides the human-readable warning message. ```json { "vaultAddress": "0xbEEFC01767ed5086f35deCb6C00e6C12bc7476C1", "chainId": 1, "level": "red", "metadata": { "content": "This vault is being deprecated following USDL asset deprecation. Please withdraw your funds." } } ``` -------------------------------- ### Vault V2 Listing Configuration Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Defines Morpho Vault V2 instances to be listed in the API. Requires address, chainId, image URL, description, and a history array. Vault V1 is not supported. ```json // data/vaults-v2-listing.json (sample entry) [ { "address": "0x89BeDBB1C4837444Da215A377275Ff96A84D6f53", "chainId": 8453, "image": "https://cdn.morpho.org/v2/assets/images/anthias.svg", "description": "The Moonwell Flagship ETH Morpho Vault curated by Anthias Labs is intended to optimize risk-adjusted interest earned from blue-chip collateral markets.", "history": [ { "action": "added", "timestamp": 1773884158 } ] } ] ``` -------------------------------- ### Custom Warnings JSON Structure Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Defines user-facing warning banners for specific vaults or markets. Use 'vaultAddress' for vaults and 'marketId' for markets. 'level' indicates severity (e.g., 'red', 'yellow'). ```json // data/custom-warnings.json (sample entries) [ { "vaultAddress": "0x0F359FD18BDa75e9c49bC027E7da59a4b01BF32a", "chainId": 1, "level": "red", "metadata": { "content": "The risk curator has executed a forced removal of the sdeUSD/USDC market. The vault's share price decreased proportionally, resulting in a loss for affected depositors." } }, { "marketId": "0x9e90aec7d768403dacc9dd0d8320307fda3f980eed4df43e3e52168a1c667709", "chainId": 42161, "level": "red", "metadata": { "content": "This market is experiencing significant volatility. Proceed with caution." } } ] ``` -------------------------------- ### Screen Curator Addresses via Chainalysis Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt A standalone script that checks curator addresses from `data/curators-listing.json` using the Chainalysis risk v2 API. It requires the `CHAINALYSIS_API_TOKEN` environment variable to be set and provides a detailed summary of the risk levels. ```bash CHAINALYSIS_API_TOKEN=your_token ts-node test/scripts/chainalysisTest.ts ``` ```text # Loaded 25 curators from listing # Processing curator: Gauntlet # Checking address: 0x9E33faAE... # ✅ Address 0x9E33faAE... has LOW risk # ... # ==== SUMMARY RESULTS ==== # Total addresses checked: 87 # ✅ All addresses have LOW risk level! ``` -------------------------------- ### Validate Curator Listing: Names, IDs, and Image URLs Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Validates curator listings, checking for unique names and IDs, correct ID format (`/^[a-z0-9-]+$/`), CDN image URL prefix, required social links, verified status, and checksummed addresses. Includes optional Chainalysis risk screening. ```typescript // Curator id must match /^[a-z0-9-]+$/: // "mev-capital" ✅ // "MEV Capital" ❌ // Image URL must start with "https://cdn.morpho.org/v2/assets/images": // "https://cdn.morpho.org/v2/assets/images/gauntlet.svg" ✅ // "https://example.com/gauntlet.svg" ❌ // Chainalysis check (runs on CI push to main with CHAINALYSIS_API_TOKEN): // Batches of 20 addresses, 1 second between batches // Fails if any address has risk level other than "LOW" ``` -------------------------------- ### Exchange Rates Configuration Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Configures ERC-4626-style exchange rate lookups. The data field is a JSON string encoding the on-chain function to call, its ABI, asset decimals, and unit argument. ```json // data/exchange-rates.json (sample entry) { "assetAddress": "0x83F20F44975D03b1b09e64809B757c47f942BEeA", "contractAddress": "0x83F20F44975D03b1b09e64809B757c47f942BEeA", "data": "{\"abi\": \"function convertToAssets(uint256) view returns (uint256)\", \"decimals\": 18, \"function\": \"convertToAssets\", \"args\": [{\"type\": \"bigint\", \"value\": \"1000000000000000000\"}]}", "assetChainId": 1, "contractChainId": 1 } ``` -------------------------------- ### Validate Custom Warnings: Address/Market Pairs and API Existence Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Validates custom warnings data, checking for duplicate (address/market + chainId) pairs and optionally verifying vault/market existence via the Morpho GraphQL API. Vault warnings use checksummed addresses, market warnings use 32-byte hex strings. ```typescript // Vault warnings use vaultAddress (checksummed EIP-55 address) // Market warnings use marketId (0x + 64 hex chars = 32-byte hex string) // API existence check (skippable via SKIP_VAULTS_API_TESTS=true): const query = ` query VaultByAddress($address: String!, $chainId: Int!) { vaultByAddress(address: $address, chainId: $chainId) { address } } `; // Throws if vault does not exist in the Morpho API: // "Morpho API GraphQL error for vault 0x... on chain 1: ..." ``` -------------------------------- ### Validate Oracle Price Data: Order, Decimals, and Exchange Rate Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Validates oracle price data, ensuring sequential `order` indices, valid decimal ranges (0-18), and correct fields for `exchange_rate` types. Requires specific JSON structure for exchange rates. ```typescript // Pricing chain validation: for each (assetAddress, assetChainId) group, // the `order` values must be 0, 1, 2, ... with no gaps or duplicates. // ✅ Valid: // order 0: pendle_asset_rate // order 1: redstone_without_logs // ❌ Invalid (gap): // order 0: pendle_asset_rate // order 2: redstone_without_logs → "Expected order 1 but got 2" // exchange_rate type requires these fields in the data JSON string: const validExchangeRateData = { abi: "function convertToAssets(uint256) view returns (uint256)", function: "convertToAssets", decimals: 18, args: [{ type: "bigint", value: "1000000000000000000" }] // value must equal "1" + "0".repeat(decimals) }; ``` -------------------------------- ### Screen Vault Owner/Curator Addresses via Chainalysis Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt This script checks vault owner and curator addresses listed in `data/vaults-listing.json` against the Chainalysis risk API. It requires the `CHAINALYSIS_API_TOKEN` environment variable to be set. Addresses are fetched on-chain using viem's multicall. ```bash # Requires CHAINALYSIS_API_TOKEN in test/.env CHAINALYSIS_API_TOKEN=your_token ts-node test/scripts/vaultRolesCheck.ts ``` ```text # Processing vault: 0x89BeDB... (Chain ID: 8453) # ✅ Address 0x38afC3... has LOW risk - Roles: owner # ✅ Address 0x06590F... has LOW risk - Roles: curator # ==== SUMMARY RESULTS ==== # Total addresses checked: 42 # ✅ All addresses have LOW risk level! ``` -------------------------------- ### Validate Vault V2 Listing Checksums and Uniqueness Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Ensures vault addresses are EIP-55 checksummed and unique per chain ID. Requires `viem` for address checksumming. ```typescript import { describe, expect, test } from "@jest/globals"; import { loadJsonFile, VALID_CHAIN_IDS } from "../../utils/jsonValidators"; import { getAddress } from "viem"; describe("vaults-v2-listing.json validation", () => { const vaults = loadJsonFile("vaults-v2-listing.json"); test("each vault address is checksummed", () => { vaults.forEach((vault, index) => { const checksummedAddress = getAddress(vault.address); // Throws if not checksummed — e.g. "0xabcdef..." must be "0xAbCdEf..." expect(vault.address).toBe(checksummedAddress); }); }); test("vault addresses are unique per chain ID", () => { const seen = new Map(); const duplicates = []; vaults.forEach((vault) => { const key = vault.address.toLowerCase(); const chains = seen.get(key) || new Set(); if (chains.has(vault.chainId)) duplicates.push({ address: vault.address, chainId: vault.chainId }); chains.add(vault.chainId); seen.set(key, chains); }); expect(duplicates).toHaveLength(0); // Fails with: "Found duplicate address-chainId combinations: [...]" }); }); ``` -------------------------------- ### Curator Listing JSON Structure Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Registers verified vault curators. Each entry includes an 'id', 'name', 'image', 'socials', and 'addresses' keyed by chain ID. Curators must have 'verified: true'. ```json // data/curators-listing.json (sample entry) { "image": "https://cdn.morpho.org/v2/assets/images/mevcapital.png", "name": "MEV Capital", "id": "mev-capital", "verified": true, "addresses": { "1": [ "0x38afC3aA2c76b4cA1F8e1DabA68e998e1F4782DB", "0x06590Fef209Ebc1f8eEF83dA05984cD4eFf0d0E3" ], "8453": [ "0xB672Ea44A1EC692A9Baf851dC90a1Ee3DB25F1C4" ], "42161": [ "0xBB4B5BdC1a77971B6C35D87D30BB30F79543a2EF" ] }, "socials": { "url": "https://mevcapital.com/", "twitter": "https://x.com/MEVCapital", "forum": "https://forum.morpho.org/c/vaults/mev-capital/30" } } ``` -------------------------------- ### Validate Token Data: Checksums, Uniqueness, and URIs Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Validates token data including address checksums, uniqueness per chain, required fields, and proper CDN logo URI encoding. Filters tokens to supported chain IDs. ```typescript import { getAddress } from "viem"; import { loadJsonFile, VALID_CHAIN_IDS } from "../../utils/jsonValidators"; const allTokens = loadJsonFile("tokens.json"); // Filters to only supported chain IDs const tokens = allTokens.filter((t) => VALID_CHAIN_IDS.includes(t.chainId)); // logoURI must be properly percent-encoded // "https://cdn.morpho.org/assets/logos/USD%2B.svg" ✅ // "https://cdn.morpho.org/assets/logos/USD+.svg" ❌ // Tags must be from the allow-list; unknown tags cause test failure: // "stablecoin", "eth", "lst", "lrt", "yield", "rwa", "erc4626", etc. // Oracle fields must use plural form: // metadata.alternativeOracles: ["ETH"] ✅ // metadata.alternativeOracle: "ETH" ❌ (use plural) ``` -------------------------------- ### Validate Required Fields Utility Source: https://context7.com/morpho-org/morpho-blue-api-metadata/llms.txt Checks if an object contains all specified required fields. Returns true if all fields are present, false otherwise. ```typescript import { validateRequiredFields } from "./utils/jsonValidators"; const vault = { address: "0xABC...", chainId: 1, description: "My vault" }; const ok = validateRequiredFields(vault, ["address", "chainId", "description"]); // ok === true const bad = validateRequiredFields(vault, ["address", "chainId", "image"]); // bad === false ("image" is missing) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.