npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@morpho-org/consumer-sdk

v0.6.0

Published

Abstraction layer for Morpho's complexity.

Readme

Consumer SDK

Beta

⚠️ Experimental package: This SDK is currently in experimental phase.

The abstraction layer that simplifies Morpho protocol

Entities & Actions

| Entity | Action | Route | Why | | ------------ | ------------------------ | ------------------------- | --------------------------------------------------------------------------------------------------- | | VaultV2 | deposit | Bundler (general adapter) | Enforces maxSharePrice — inflation attack prevention. Supports native token wrapping. | | | withdraw | Direct vault call | No attack surface, no bundler overhead needed | | | redeem | Direct vault call | No attack surface, no bundler overhead needed | | | forceWithdraw | Vault multicall | N forceDeallocate + 1 withdraw in a single tx | | | forceRedeem | Vault multicall | N forceDeallocate + 1 redeem in a single tx | | VaultV1 | deposit | Bundler (general adapter) | Same ERC-4626 inflation attack prevention as V2. Supports native token wrapping. | | | withdraw | Direct vault call | No attack surface | | | redeem | Direct vault call | No attack surface | | | migrateToV2 | Bundler (general adapter) | Atomic V1 → V2 migration: redeem V1 shares + deposit into V2 in one tx. Slippage-protected. | | MarketV1 | supplyCollateral | Bundler (general adapter) | erc20TransferFrom + morphoSupplyCollateral. Supports native wrapping. | | | borrow | Bundler (general adapter) | morphoBorrow with minSharePrice slippage protection. Requires GA1 auth. Supports reallocations. | | | supplyCollateralBorrow | Bundler (general adapter) | Atomic supply + borrow. LLTV buffer prevents instant liquidation. Supports reallocations. |

VaultV2

import { MorphoClient } from "@morpho-org/consumer-sdk";
import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";

const viemClient = createPublicClient({ chain: mainnet, transport: http() });
const morpho = new MorphoClient(viemClient);

const vault = morpho.vaultV2("0xVault...", 1);

Deposit

const { buildTx, getRequirements } = await vault.deposit({
  amount: 1000000000000000000n,
  userAddress: "0xUser...",
});

const requirements = await getRequirements();
const tx = buildTx(requirementSignature);

Deposit with native token wrapping

For vaults whose underlying asset is wNative, you can deposit native token that will be automatically wrapped:

// Native ETH only — wraps 1 ETH to WETH and deposits
const { buildTx, getRequirements } = await vault.deposit({
  nativeAmount: 1000000000000000000n,
  userAddress: "0xUser...",
});

// Mixed — 0.5 WETH (ERC-20) + 0.5 native ETH wrapped to WETH
const { buildTx, getRequirements } = await vault.deposit({
  amount: 500000000000000000n,
  nativeAmount: 500000000000000000n,
  userAddress: "0xUser...",
});

The bundler atomically transfers native token, wraps it to wNative, and deposits alongside any ERC-20 amount. The transaction's value field is set to nativeAmount.

Withdraw

const { buildTx } = vault.withdraw({
  amount: 500000000000000000n,
  userAddress: "0xUser...",
});

const tx = buildTx();

Redeem

const { buildTx } = vault.redeem({
  shares: 1000000000000000000n,
  userAddress: "0xUser...",
});

const tx = buildTx();

Force Withdraw

const { buildTx } = vault.forceWithdraw({
  deallocations: [{ adapter: "0xAdapter...", amount: 100n }],
  withdraw: { amount: 500000000000000000n },
  userAddress: "0xUser...",
});

const tx = buildTx();

Force Redeem

const { buildTx } = vault.forceRedeem({
  deallocations: [{ adapter: "0xAdapter...", amount: 100n }],
  redeem: { shares: 1000000000000000000n },
  userAddress: "0xUser...",
});

const tx = buildTx();

VaultV1

const vault = morpho.vaultV1("0xVault...", 1);

Deposit

const { buildTx, getRequirements } = await vault.deposit({
  amount: 1000000000000000000n,
  userAddress: "0xUser...",
});

const requirements = await getRequirements();
const tx = buildTx(requirementSignature);

Withdraw

const { buildTx } = vault.withdraw({
  amount: 500000000000000000n,
  userAddress: "0xUser...",
});

const tx = buildTx();

Redeem

const { buildTx } = vault.redeem({
  shares: 1000000000000000000n,
  userAddress: "0xUser...",
});

const tx = buildTx();

Migrate to V2

Atomically migrate a full position from a VaultV1 (MetaMorpho) vault into a VaultV2 vault. The bundler redeems the V1 shares and deposits the resulting assets into V2 in a single transaction. Both vaults must share the same underlying asset.

const sourceVault = morpho.vaultV1("0xV1Vault...", 1);
const targetVault = morpho.vaultV2("0xV2Vault...", 1);

const { buildTx, getRequirements } = sourceVault.migrateToV2({
  userAddress: "0xUser...",
  sourceVault: await sourceVault.getData(),
  targetVault: await targetVault.getData(),
  shares: 1000000000000000000n,
});

const requirements = await getRequirements();
const tx = buildTx(requirementSignature);

MarketV1

const market = morpho.marketV1(
  {
    loanToken: "0xLoan...",
    collateralToken: "0xCollateral...",
    oracle: "0xOracle...",
    irm: "0xIrm...",
    lltv: 860000000000000000n,
  },
  1
);

Supply Collateral

const { buildTx, getRequirements } = market.supplyCollateral({
  amount: 1000000000000000000n,
  userAddress: "0xUser...",
});

const requirements = await getRequirements();
const tx = buildTx(requirementSignature);

Borrow

const positionData = await market.getPositionData("0xUser...");

const { buildTx, getRequirements } = market.borrow({
  amount: 500000000000000000n,
  userAddress: "0xUser...",
  positionData,
});

const requirements = await getRequirements();
const tx = buildTx();

Supply Collateral & Borrow

const positionData = await market.getPositionData("0xUser...");

const { buildTx, getRequirements } = market.supplyCollateralBorrow({
  amount: 1000000000000000000n,
  borrowAmount: 500000000000000000n,
  userAddress: "0xUser...",
  positionData,
});

const requirements = await getRequirements();
const tx = buildTx(requirementSignature);

Borrow with Shared Liquidity (Reallocations)

When a market lacks sufficient liquidity, you can reallocate liquidity from other markets managed by MetaMorpho Vaults via the PublicAllocator contract:

import type { VaultReallocation } from "@morpho-org/consumer-sdk";

const reallocations: VaultReallocation[] = [
  {
    vault: "0xVault...", // MetaMorpho vault to reallocate from
    fee: 0n, // PublicAllocator fee in native token (can be 0)
    withdrawals: [
      {
        marketParams: sourceMarketParams, // Source market to withdraw from
        amount: 2000000000n, // Amount to withdraw
      },
    ],
  },
];

const positionData = await market.getPositionData("0xUser...");

// Borrow with reallocations
const { buildTx, getRequirements } = market.borrow({
  amount: 500000000000000000n,
  userAddress: "0xUser...",
  positionData,
  reallocations,
});

const requirements = await getRequirements();
const tx = buildTx();
// tx.value includes the sum of all reallocation fees

Reallocations also work with supplyCollateralBorrow:

const { buildTx, getRequirements } = market.supplyCollateralBorrow({
  amount: 1000000000000000000n,
  borrowAmount: 500000000000000000n,
  userAddress: "0xUser...",
  positionData,
  reallocations,
});

Architecture

graph LR
    MC[MorphoClient]

    MC -->|.vaultV1| MV1
    MC -->|.vaultV2| MV2
    MC -->|.marketV1| MM1

    subgraph VaultV1 Flow
        MV1[MorphoVaultV1]
        MV1 --> V1D[vaultV1Deposit]
        MV1 --> V1W[vaultV1Withdraw]
        MV1 --> V1R[vaultV1Redeem]
        MV1 --> V1M[vaultV1MigrateToV2]

        V1D -->|nativeTransfer + wrapNative + erc4626Deposit| B1[Bundler3]
        V1W -->|direct call| MM[MetaMorpho]
        V1R -->|direct call| MM
        V1M -->|erc20TransferFrom + erc4626Redeem + erc4626Deposit| B1
    end

    subgraph VaultV2 Flow
        MV2[MorphoVaultV2]
        MV2 --> V2D[vaultV2Deposit]
        MV2 --> V2W[vaultV2Withdraw]
        MV2 --> V2R[vaultV2Redeem]
        MV2 --> V2FW[vaultV2ForceWithdraw]
        MV2 --> V2FR[vaultV2ForceRedeem]

        V2D -->|nativeTransfer + wrapNative + erc4626Deposit| B2[Bundler3]
        V2W -->|direct call| V2C[VaultV2 Contract]
        V2R -->|direct call| V2C
        V2FW -->|multicall| V2C
        V2FR -->|multicall| V2C
    end

    subgraph MarketV1 Flow
        MM1[MorphoMarketV1]
        MM1 --> M1SC[marketV1SupplyCollateral]
        MM1 --> M1B[marketV1Borrow]
        MM1 --> M1SCB[marketV1SupplyCollateralBorrow]

        M1SC -->|erc20TransferFrom + morphoSupplyCollateral| B3[Bundler3]
        M1B -->|reallocateTo? + morphoBorrow| B3
        M1SCB -->|transfer + supplyCollateral + reallocateTo? + borrow| B3

        B3 -.->|reallocateTo| PA[PublicAllocator]
    end


    subgraph Shared
        REQ[getRequirements]
    end

    MV1 -.->|approval / permit| REQ
    MV2 -.->|approval / permit| REQ
    MM1 -.->|approval / permit / authorization| REQ

    style B1 fill:#e8f5e9,stroke:#4caf50
    style B2 fill:#e8f5e9,stroke:#4caf50
    style B3 fill:#e8f5e9,stroke:#4caf50
    style MM fill:#fff3e0,stroke:#ff9800
    style V2C fill:#e3f2fd,stroke:#2196f3
    style REQ fill:#f3e5f5,stroke:#9c27b0
    style PA fill:#fff9c4,stroke:#f9a825

Local Development

Link this package to your app for local debugging:

# In this consumer-sdk project
pnpm run build:link

In your other project:

# Link the local package
pnpm link consumer-sdk

Contributing

Contributions are welcome! Feel free to open an issue or PR.