npm package: @morpholabs/morpho-js
Description: A SDK to interract with morpho-compound and morpho-aavev2 optimizers
Author: Morpho Labs
Latest version: 1.0.0

# Morpho-JS (DEPRECATED)

see [morpho-dapp](https://github.com/morpho-labs/morpho-dapp)

A JavaScript library for Morpho. Wraps around Ethers.js.

This SDK is in open beta, and is constantly under development. **USE AT YOUR OWN RISK**.

to run it locally, please install the 2 peer dependencies

## Features

- [x] User adapter
- [x] Markets adapter
- [x] off chain indexes & rates computation
- [x] off chain transaction simulation (hypothetical user state)
- [ ] unit testing for math computations (WIP)
- [ ] E2E tests for marketsAdapter (WIP)
- [ ] E2E tests for userAdapter (WIP)
- [x] Retrieve & format markets data from Thegraph subgraph (used by Morpho Dashboard)
- [ ] Retrieve & format markets data from chain using a given provider
- [ ] Use of referralCode & maxGasToConsume (not on mumbai)
- [ ] Add rewards computations (`claimRewards` function & contract versioning, because claims rewards is not available on aave mumbai)

## Improvements

- fix timestamp for testing (instead of using `expectBNApproximatlyEquals`)
- use the contract repo as a git module, and simulate transaction on a local contract (to be sure that transactions pass and follow the contract improvements)

## Morpho AAVE uses cases examples

### Without provider

You can use Morpho JS without provider in order to retrieve and format the markets data from our subgraph.  
This does not yet allow you to retrieve information about a user

```typescript
import { MarketAdapterAave } from "@morpholabs/morpho-js";

const main = async () => {
  const mainnetNetworkId = 1; // only available on mumbai or fuji, for now
  const marketAdapter = await MarketAdapterAave.fromNetwork(mainnetNetworkId);

  const markets = marketAdapter.markets;
  /*
    Returns array of {
      decimals: number;
      name?: string;
      symbol: string;
      address: Address;
      token: Token;
      liquidationThreshold: BigNumber;
      borrowThreshold: BigNumber;
      reserveData: {
          borrowIndex: {
                  index: BigNumber;
                  rate: BigNumber;
                  lastUpdateTimestamp: number;
                  units: number;
                };
          supplyIndex: {
                  index: BigNumber;
                  rate: BigNumber;
                  lastUpdateTimestamp: number;
                  units: number;
                };
          midRate: BigNumber;
          eth: BigNumber;
          usd: BigNumber;
        };
      morphoData: {
          borrowP2PIndex: {
                  index: BigNumber;
                  rate: BigNumber;
                  lastUpdateTimestamp: number;
                  units: number;
                };
          supplyP2PIndex: {
                      index: BigNumber;
                      rate: BigNumber;
                      lastUpdateTimestamp: number;
                      units: number;
                    };
          p2pReserve: BigNumber;
          supplyP2PDelta: BigNumber;
          borrowP2PDelta: BigNumber;
          supplyP2PAmount: BigNumber;
          borrowP2PAmount: BigNumber;
        },
      rewardsData?: {
          supplyRewardsEmissionPerSecond: BigNumber;
          borrowRewardsEmissionPerSecond: BigNumber;
          supplyP2PRewardsEmissionPerSecond: BigNumber;
          borrowP2PRewardsEmissionPerSecond: BigNumber;
        },
      metrics: {
          totalBorrowOnPool: BigNumber;
          totalSupplyOnPool: BigNumber;
          totalBorrowInP2P: BigNumber;
          totalSupplyInP2P: BigNumber;
          totalSupplyScaledBalance: BigNumber;
          totalBorrowScaledBalance: BigNumber;
        };
    }
    
     */

  const marketsConfig = marketAdapter.marketsConfig;
  /*
    Returns array of {
      readonly poolBorrowAPY: BigNumber; // the max APY for a borrower (in WEI units)
      readonly poolSupplyAPY: BigNumber; // the min APY for a supplier (in WEI units)
      readonly poolSupplyRewardsAPR: BigNumber; // the supply liquidity mining APR of the pool (in WEI units)
      readonly poolBorrowRewardsAPR: BigNumber; // the borrow liquidity mining APR of the pool (in WEI units)
      readonly p2pSupplyRewardsAPR: BigNumber; // the supply liquidity mining APR of morpho (in WEI units)
      readonly p2pBorrowRewardsAPR: BigNumber; // the borrow liquidity mining APR of morpho (in WEI units)
      readonly p2pAPY: BigNumber; // the APY of the midRate (in WEI units, without reserveFactor)
      readonly p2pSupplyAPY: BigNumber; // the APY of the supply P2P rate (in WEI units, without reserveFactor)
      readonly p2pBorrowAPY: BigNumber; // the APY of the borrow P2P rate (in WEI units, without reserveFactor)
      readonly p2pReserveFactor: BigNumber; // the percentage of the reserve factor (in BASE_UNIT, i.e 1e4)
      readonly unlockableSupply: BigNumber; // the amount supplied on pool who can be matched (in underlying)
      readonly unlockableBorrow: BigNumber; // the amount borrowed on pool who can be matched (in underlying)
      readonly matchedSupply: BigNumber; // the supply amount matched (in underlying)
      readonly matchedBorrow: BigNumber; // the borrow amount matched (in underlying)
      readonly fallbackLiquidity: BigNumber; // the pool liquidity available in the pool fallback (in underlying)
      readonly usdPrice: BigNumber; // the ETH price of the asset (in wei units)
      readonly ethPrice: BigNumber; // the USD price of the asset (in wei units)
      readonly collateralFactor: BigNumber; // the collateral factor of the market;
      readonly borrowableFactor: BigNumber; // the loan to value of the market (equals to the collateral factor for compound)
      readonly decimals: number; // number of decimal of the underlying token
      readonly symbol: string; // symbol of the token
      readonly name: string; // name of the token
      readonly address: string; // address of the market (a/cToken)
      readonly underlying: string; // address of the underlying
    }
     */
};
main()
  .then(() => process.exit(0))
  .catch((e) => {
    console.error(e);
    process.exit(1);
  });
```

### Make a transaction with signer

You can now use a signer as a provider for the user related data.
The user adapter still uses our subgraph for markets data (for speed issues)

```typescript
//import {UserAdapterAave} from "@morpholabs/morpho-js";
import { Contract, providers, Wallet } from "ethers";
import { formatUnits, parseUnits } from "ethers/lib/utils";
import ERC20 from "@morpholabs/morpho-js/config/abis/ERC20.json";
import { TransactionType } from "./transactions";

const main = async () => {
  const provider = new providers.JsonRpcProvider(process.env.RPC_URL, process.env.NETWORK_ID);
  const signer = new Wallet(process.env.PRIVATE_KEY);
  const userAdapter = await userAdapterAave.fromSigner(signer);
  console.log(userAdapter.isConnected); // true
  const DAImarket = userAdapter.getMarketConfig().find((m) => m.symbol === "DAI");

  const amount = parseUnits("10", DAImarket.decimals); // 10 DAI

  // approve 10 DAI to positions manager
  const daiErc20 = new Contract(DAImarket.underlying, ERC20, signer);
  const tx = await daiErc20.approve(userAdapter.positionsManager!.address);
  const recipt = await tx.wait();
  console.log(recipt);

  // supply 10 DAI to positions manager
  const receipt = await userAdapter.morphoTransaction(
    TransactionType.Supply,
    DAImarket.address, // Atoken address,
    amount,
    {
      onStart: (txResponse) => console.log(txResponse),
      onSuccess: (txReceipt) => console.log(txReceipt),
      onError: (errorMessage) => console.error(errorMessage),
    },
  );

  // get user borrow capacity
  console.log(formatUnits(userAdapter.userBalance.borrowCapacityUsedPercentage));

  // get market P2P APY
  console.log(formatUnits(userAdapter.getMarketConfig().p2pAPY));
};
main()
  .then(() => process.exit(0))
  .catch((e) => {
    console.error(e);
    process.exit(1);
  });
```

## Development setup

- `yarn link:build` to setup & symlink build folder using `yarn link`
- `yarn dev` to start ts compiler with hot-transpilation

Then, inside the project integrating `morpho-js` package:

- `yarn add @morpholabs/morpho-js`
- `yarn link @morpholabs/morpho-js`
- If you want to disable the symlink, use: `yarn unlink @morpholabs/morpho-js`