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);
});