SDK Documentation

This page describes the use of the Morpho SDK.

Morpho AaveV3-ETH Optimizer: SDK Documentation

Introduction

  • Morpho's AaveV3-ETH Optimizer SDK is a TypeScript-based toolkit for building decentralized applications (dApps) using Morpho-AaveV3 smart contracts.

  • The SDK is a "plug-and-play" adapter, easing the construction of any app or script that requires interaction with the Morpho AaveV3-ETH Optimizer contracts. It also provides seamless integration with RxJS for reactive programming, facilitating efficient handling of async data streams.

  • The SDK is still under development, and any feedback is welcome.

Prerequisites

  • Knowledge of blockchain, TypeScript, and decentralized applications.

  • Node.js (v.^14.0) and npm/yarn installed on your system.

  • ethers (v.^5.7.0).

Getting Started

  • Installation

using npm or yarn:

npm install @morpho-org/morpho-aave-v3-sdk
yarn add @morpho-org/morpho-aave-v3-sdk

Basic Use

  1. First example using getMarketsData()

import { MorphoAaveV3Adapter } from "@morpho-org/morpho-aave-v3-sdk";
import sdk from "@morpho-org/morpho-aave-v3-sdk/lib";
import { getDefaultProvider } from "ethers";

sdk.setConfiguration({
  defaultProvider: new providers.JsonRpcProvider(
    "https://RPC"
  ) as providers.BaseProvider,
});

export const main = async () => {
  try {
    const adapter: MorphoAaveV3Adapter = MorphoAaveV3Adapter.fromChain({});
    await adapter.refreshAll("latest");
    const marketsData: any = adapter.getMarketsData();
    console.log(marketsData);
  } catch (error) {
    console.error(`Failed to run main function: ${error}`);
  }
};

main()
  .then(() => process.exit(0))
  .catch((error: Error) => {
    console.error(`Failed to run script: ${error}`);
    process.exit(1);
  });

it returns: (WETH market displayed below)

{
  '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2': {
    address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
    chainUsdPrice: BigNumber { _hex: '0x2a4caf8e00', _isBigNumber: true },
    poolLiquidity: BigNumber { _hex: '0x14b060d6c505e0096e3a', _isBigNumber: true },
    scaledPoolBorrow: BigNumber { _hex: '0x227a5fc1c09a6e8edbf8', _isBigNumber: true },
    poolStableBorrow: BigNumber { _hex: '0x00', _isBigNumber: true },
    scaledPoolSupply: BigNumber { _hex: '0x373ca00a23f10d32f418', _isBigNumber: true },
    scaledMorphoBorrowOnPool: BigNumber { _hex: '0x00', _isBigNumber: true },
    scaledMorphoSupplyInP2P: BigNumber { _hex: '0x0c0f6eca2c5369', _isBigNumber: true },
    scaledMorphoBorrowInP2P: BigNumber { _hex: '0x0c0f6de638908d', _isBigNumber: true },
    scaledMorphoGlobalPoolSupply: BigNumber { _hex: '0x0476aaf59bf29efb2d', _isBigNumber: true },
    indexes: {
      poolBorrowIndex: [BigNumber],
      poolSupplyIndex: [BigNumber],
      p2pBorrowIndex: [BigNumber],
      p2pSupplyIndex: [BigNumber],
      lastUpdateTimestamp: [BigNumber]
    },
    aaveIndexes: {
      lastUpdateTimestamp: [BigNumber],
      liquidityIndex: [BigNumber],
      variableBorrowIndex: [BigNumber],
      liquidityRate: [BigNumber],
      variableBorrowRate: [BigNumber]
    },
    idleSupply: BigNumber { _hex: '0x00', _isBigNumber: true },
    deltas: { supply: [Object], borrow: [Object] },
    scaledMorphoCollateral: BigNumber { _hex: '0x00', _isBigNumber: true },
    scaledMorphoSupplyOnPool: BigNumber { _hex: '0x046f9bf8d96886fa26', _isBigNumber: true },
    usdPrice: BigNumber { _hex: '0x2a4caf8e00', _isBigNumber: true },
    poolBorrow: BigNumber { _hex: '0x22e5a5d0e0f5b89f23d3', _isBigNumber: true },
    poolSupply: BigNumber { _hex: '0x379484acf21e7c0cda6c', _isBigNumber: true },
    morphoBorrowInP2P: BigNumber { _hex: '0x0c14ce865f5014', _isBigNumber: true },
    morphoBorrowOnPool: BigNumber { _hex: '0x00', _isBigNumber: true },
    morphoSupplyInP2P: BigNumber { _hex: '0x0c14ce865f5013', _isBigNumber: true },
    morphoSupplyOnPool: BigNumber { _hex: '0x0476aaf59bf29ef743', _isBigNumber: true },
    morphoGlobalSupplyOnPool: BigNumber { _hex: '0x047dc52da81df255d5', _isBigNumber: true },
    totalMorphoSupply: BigNumber { _hex: '0x0476b70a6a78fe4756', _isBigNumber: true },
    totalMorphoBorrow: BigNumber { _hex: '0x0c14ce865f5014', _isBigNumber: true },
    totalMorphoCollateral: BigNumber { _hex: '0x00', _isBigNumber: true },
    poolBorrowAPY: BigNumber { _hex: '0x0196', _isBigNumber: true },
    poolSupplyAPY: BigNumber { _hex: '0xd7', _isBigNumber: true },
    p2pSupplyAPY: BigNumber { _hex: '0x0136', _isBigNumber: true },
    p2pBorrowAPY: BigNumber { _hex: '0x0136', _isBigNumber: true },
    matchingRatio: BigNumber { _hex: '0x01', _isBigNumber: true },
    supplyMatchingRatio: BigNumber { _hex: '0x00', _isBigNumber: true },
    borrowMatchingRatio: BigNumber { _hex: '0x2710', _isBigNumber: true },
    borrowMorphoRewardsRate: BigNumber { _hex: '0x00', _isBigNumber: true },
    supplyMorphoRewardsRate: BigNumber { _hex: '0x00', _isBigNumber: true },
    collateralMorphoRewardsRate: BigNumber { _hex: '0x00', _isBigNumber: true }
  },
  ...
  ... 
}

and all other information on the other available markets.

  1. Second example using getUserMarketsData()

export const main = async () => {
  try {
    const adapter: MorphoAaveV3Adapter = MorphoAaveV3Adapter.fromChain({
      _provider: getDefaultProvider(
        "https://YOUR_HTTPS_ACCESS"
      ),
    });
    await adapter.connect("0x395012DF0D443a7639E46Fcb0DAF756a9Bbf3c6c"); // User selected randomly
    await adapter.refreshAll("latest");
    const userDataUsdc: any =
      adapter.getUserMarketsData()[
        "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" // This is the USDC market
      ];
    console.log(userDataUsdc);
  } catch (error) {
    console.error(`Failed to run main function: ${error}`);
  }
};

main()
  .then(() => process.exit(0))
  .catch((error: Error) => {
    console.error(`Failed to run script: ${error}`);
    process.exit(1);
  });

will returns:

{
  underlyingAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  scaledSupplyOnPool: BigNumber { _hex: '0x00', _isBigNumber: true },
  scaledCollateral: BigNumber { _hex: '0x97a2d2', _isBigNumber: true },
  scaledSupplyInP2P: BigNumber { _hex: '0x00', _isBigNumber: true },
  scaledBorrowOnPool: BigNumber { _hex: '0x00', _isBigNumber: true },
  scaledBorrowInP2P: BigNumber { _hex: '0x00', _isBigNumber: true },
  walletBalance: BigNumber { _hex: '0x10179138', _isBigNumber: true },
  approval: BigNumber { _hex: '0x00', _isBigNumber: true },
  nonce: BigNumber { _hex: '0x01', _isBigNumber: true },
  permit2Approval: BigNumber {
    _hex: '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffff67697f',
    _isBigNumber: true
  },
  totalCollateral: BigNumber { _hex: '0x9896d7', _isBigNumber: true },
  supplyInP2P: BigNumber { _hex: '0x00', _isBigNumber: true },
  supplyOnPool: BigNumber { _hex: '0x00', _isBigNumber: true },
  borrowInP2P: BigNumber { _hex: '0x00', _isBigNumber: true },
  borrowOnPool: BigNumber { _hex: '0x00', _isBigNumber: true },
  totalBorrow: BigNumber { _hex: '0x00', _isBigNumber: true },
  totalSupply: BigNumber { _hex: '0x00', _isBigNumber: true },
  supplyMatchingRatio: BigNumber { _hex: '0x00', _isBigNumber: true },
  borrowMatchingRatio: BigNumber { _hex: '0x00', _isBigNumber: true },
  matchingRatio: BigNumber { _hex: '0x00', _isBigNumber: true },
  experiencedBorrowAPY: BigNumber { _hex: '0x00', _isBigNumber: true },
  experiencedCollateralAPY: BigNumber { _hex: '0xe0', _isBigNumber: true },
  experiencedSupplyAPY: BigNumber { _hex: '0x00', _isBigNumber: true },
  experiencedBorrowMorphoEmission: BigNumber { _hex: '0x00', _isBigNumber: true },
  experiencedSupplyMorphoEmission: BigNumber { _hex: '0x00', _isBigNumber: true },
  experiencedCollateralMorphoEmission: BigNumber { _hex: '0x00', _isBigNumber: true }
}

Third example to retrieve the supply emission of MORPHO rewards emitted for 1000$ using getMarketsData(): on the WETH market:

export const main = async () => {
  try {
    const adapter: MorphoAaveV3Adapter = MorphoAaveV3Adapter.fromChain();
    await adapter.refreshAll("latest");
    const marketsData: any = adapter.getMarketsData();
    const marketAddress = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"; //WETH market
    const specificMarketData = marketsData[marketAddress];
    const SECONDS_PER_YEAR = BigNumber.from(31_536_000);
    let supplyMorphoEmission: BigNumber = constants.Zero;

    const scalingValueUnderlying = utils
      .parseUnits("1000") // 1000$ in underlying
      .mul(pow10(18))
      .div(specificMarketData.usdPrice.mul(10 ** 10));

    supplyMorphoEmission = scalingValueUnderlying
      .mul(specificMarketData.supplyMorphoRewardsRate)
      .mul(SECONDS_PER_YEAR) // in WAD
      .div(specificMarketData.totalMorphoSupply.add(scalingValueUnderlying))
      .div(pow10(18));

    console.log(supplyMorphoEmission.toString());
  } catch (error) {
    console.error(`Failed to run main function: ${error}`);
  }
};

main()
  .then(() => process.exit(0))
  .catch((error: Error) => {
    console.error(`Failed to run script: ${error}`);
    process.exit(1);
  });

Will returns

BigNumber { _hex: '0x15', _isBigNumber: true }

Advanced Use

Developers seeking to make advanced customizations can find additional resources and extended documentation in the full documentation provided in the README. If you have any questions or need further assistance, please don't hesitate to reach out on Discord.

Last updated

Logo

This documentation is provided by MorphoLabs, main contributor to Morpho DAO. For any question, reach out.