Skip to main content

Morpho SDK Viem Tutorial

Introduction

The blue-sdk-viem package extends the functionality of blue-sdk by providing Viem-based fetchers for interacting with Morpho markets and positions. This documentation will guide you through the setup and usage of blue-sdk-viem.

Installation

To use blue-sdk-viem, you need to install it along with its peer dependencies:

npm install @morpho-org/blue-sdk @morpho-org/blue-sdk-viem @morpho-org/morpho-ts viem dotenv

Setup

First, import the necessary modules and set up your environment:

import { AccrualPosition, MarketConfig, MarketId } from "@morpho-org/blue-sdk";
import "@morpho-org/blue-sdk-viem/lib/augment/MarketConfig";
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.RPL_URL_MAINNET),
});

Make sure to set up your .env file with the RPL_URL_MAINNET variable pointing to your Ethereum node URL.

Basic Usage

Fetching Market Configuration

To fetch the configuration of a specific market:

const marketId =
"0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc" as MarketId;
async function fetchMarketConfig() {
console.log("Fetching market config...");
const config = await MarketConfig.fetch(marketId, client);
console.log("Collateral Token:", config.collateralToken);
}

Fetching Market Data

To fetch data for a specific market:

import { Time } from "@morpho-org/morpho-ts";
import { Market } from "@morpho-org/blue-sdk";
import "@morpho-org/blue-sdk-viem/lib/augment/Market";
async function fetchMarketData() {
console.log("Fetching market data...");
const market = await Market.fetch(marketId, client);
console.log("Market Utilization:", market.utilization);
console.log("Market Liquidity:", market.liquidity);
console.log("Market APY at Target:", market.apyAtTarget);
}

Accruing Interest and Converting Shares

To accrue interest on the market and convert supply shares to assets:

const accruedMarket = market.accrueInterest(Time.timestamp());
const shares = ethers.parseUnits("1", 18);
console.log(
"Supply Assets for 1 Share:",
ethers.formatUnits(accruedMarket.toSupplyAssets(shares), 18)
);

Fetching Position Data

To fetch data for a user's position in a specific market:

import "@morpho-org/blue-sdk-viem/lib/augment/Position";

async function fetchUserPosition() {
console.log("Fetching user position...");
const userAddress = "0x7f65e7326F22963e2039734dDfF61958D5d284Ca";
const position = await AccrualPosition.fetch(userAddress, marketId, client);
console.log("Borrow Assets:", position.borrowAssets);
console.log("Is Position Healthy:", position.isHealthy);
console.log("Max Borrowable Assets:", position.maxBorrowableAssets);
}

Accruing Interest on a Position

To accrue interest on a user's position:

const accruedPosition = position.accrueInterest(Time.timestamp());
console.log("Accrued Borrow Assets:", accruedPosition.borrowAssets);

Advanced Usage

Error Handling

Always wrap your main function in a try-catch block to handle any errors:

async function main() {
// ... your code here ...
}

main().catch((error) => {
console.error("An error occurred:", error);
});

Complex Scenarios

  • Explore more complex scenarios, such as multi-market interactions.

Conclusion

This documentation provides a basic overview of how to use the blue-sdk-viem package to interact with Morpho markets and positions. For more advanced usage, feel free to jump on the github repository.

Full Code Example

import {
AccrualPosition,
Market,
MarketConfig,
MarketId,
} from "@morpho-org/blue-sdk";
import "@morpho-org/blue-sdk-viem/lib/augment/MarketConfig";
import { createClient, http } from "viem";
import { mainnet } from "viem/chains";
import "dotenv/config";
import { Time } from "@morpho-org/morpho-ts";
import "@morpho-org/blue-sdk-viem/lib/augment/Market";
import "@morpho-org/blue-sdk-viem/lib/augment/Position";
const client = createClient({
chain: mainnet,
transport: http(process.env.RPL_URL_MAINNET),
});
const marketId: MarketId =
"0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc" as MarketId;
async function fetchMarketConfig() {
console.log("Fetching market config...");
const config = await MarketConfig.fetch(marketId, client);
console.log("Collateral Token:", config.collateralToken);
}
async function fetchMarketData() {
console.log("Fetching market data...");
const market = await Market.fetch(marketId, client);
console.log("Market Utilization:", market.utilization);
console.log("Market Liquidity:", market.liquidity);
console.log("Market APY at Target:", market.apyAtTarget);
const accruedMarket = market.accrueInterest(Time.timestamp());
const assets = accruedMarket.toSupplyAssets(BigInt(1e18));
console.log("Supply Assets for 1 Share:", assets);
}
async function fetchUserPosition() {
console.log("Fetching user position...");
const userAddress = "0x7f65e7326F22963e2039734dDfF61958D5d284Ca";
const position = await AccrualPosition.fetch(userAddress, marketId, client);
console.log("Borrow Assets:", position.borrowAssets);
console.log("Is Position Healthy:", position.isHealthy);
console.log("Max Borrowable Assets:", position.maxBorrowableAssets);
const accruedPosition = position.accrueInterest(Time.timestamp());
console.log("Accrued Borrow Assets:", accruedPosition.borrowAssets);
}
async function main() {
await fetchMarketConfig();
await fetchMarketData();
await fetchUserPosition();
}
main().catch((error) => {
console.error("An error occurred:", error);
});