Skip to main content

Morpho SDK Ethers Tutorial

Introduction

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

Installation

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

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

Setup

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

import { ethers, JsonRpcProvider } from "ethers";
import {
Market,
AccrualPosition,
MarketId,
MarketConfig,
} from "@morpho-org/blue-sdk";
import { Time } from "@morpho-org/morpho-ts";
import "@morpho-org/blue-sdk-ethers/lib/augment";
import "@morpho-org/blue-sdk-ethers/lib/augment/MarketConfig";
import "dotenv/config";

// Set up the provider
const provider = new JsonRpcProvider(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;
const config = await MarketConfig.fetch(marketId, provider);
console.log("Collateral Token:", config.collateralToken);

Fetching Market Data

To fetch data for a specific market:

const market = await Market.fetch(marketId, provider);
console.log("Market Utilization:", ethers.formatUnits(market.utilization, 18));
console.log("Market Liquidity:", ethers.formatUnits(market.liquidity, 18));
console.log(
"Market APY at Target:",
ethers.formatUnits(market.apyAtTarget ?? 0, 18)
);

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:

const userAddress = "0x7f65e7326F22963e2039734dDfF61958D5d284Ca";
const position = await AccrualPosition.fetch(userAddress, marketId, provider);
console.log("Borrow Assets:", ethers.formatUnits(position.borrowAssets, 18));
console.log("Is Position Healthy:", position.isHealthy);
console.log(
"Max Borrowable Assets:",
ethers.formatUnits(position.maxBorrowableAssets, 18)
);

Accruing Interest on a Position

To accrue interest on a user's position:

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

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-ethers package to interact with Morpho markets and positions. For more advanced usage, feel free to jump on the github repository.

Full Code Example

import { ethers, JsonRpcProvider } from "ethers";
import { Market, AccrualPosition } from "@morpho-org/blue-sdk";
import { Time } from "@morpho-org/morpho-ts";
import "@morpho-org/blue-sdk-ethers/lib/augment";
import { MarketId, MarketConfig } from "@morpho-org/blue-sdk";
import "@morpho-org/blue-sdk-ethers/lib/augment/MarketConfig";
import "dotenv/config";

async function main() {
// Replace with your Ethereum node URL
// Set up the provider (replace with your own provider)
const provider = new JsonRpcProvider(process.env.RPL_URL_MAINNET);

// Example Market ID - replace with an actual Market ID
const marketId =
"0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc" as MarketId;

// Fetch market config
console.log("Fetching market config...");
const config = await MarketConfig.fetch(marketId, provider);
console.log("Collateral Token:", config.collateralToken);

// Fetch market data
console.log("\nFetching market data...");
const market = await Market.fetch(marketId, provider);
console.log(
"Market Utilization:",
ethers.formatUnits(market.utilization, 18)
);
console.log("Market Liquidity:", ethers.formatUnits(market.liquidity, 18));
console.log(
"Market APY at Target:",
ethers.formatUnits(market.apyAtTarget ?? 0, 18)
);

// Accrue interest
const accruedMarket = market.accrueInterest(Time.timestamp());

// Convert supply shares to assets
const shares = ethers.parseUnits("1", 18);
console.log(
"Supply Assets for 1 Share:",
ethers.formatUnits(accruedMarket.toSupplyAssets(shares), 18)
);

// Fetch position data
console.log("\nFetching position data...");
const userAddress = "0x7f65e7326F22963e2039734dDfF61958D5d284Ca";
const position = await AccrualPosition.fetch(userAddress, marketId, provider);
console.log("Borrow Assets:", ethers.formatUnits(position.borrowAssets, 18));
console.log("Is Position Healthy:", position.isHealthy);
console.log(
"Max Borrowable Assets:",
ethers.formatUnits(position.maxBorrowableAssets, 18)
);

// Accrue interest for the position
const accruedPosition = position.accrueInterest(Time.timestamp());
console.log(
"Accrued Borrow Assets:",
ethers.formatUnits(accruedPosition.borrowAssets, 18)
);
}

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