@taufinancexyz/blue-sdk
v1.2.0
Published
Framework-agnostic package that defines Morpho-related entity classes (such as `Market`, `Token`, `Vault`).
Readme
@taufinancexyz/blue-sdk
Framework-agnostic package that defines Morpho-related entity classes:
MarketParams: represents the immutable configuration of a market on MorphoMarket: represents the state of a market on MorphoToken: represents a ERC20 tokenUser: represents a user of MorphoVaultConfig: represents the configuration of a Morpho VaultVault: represents the state of a Morpho VaultVaultUser: represents the state of a user on a Morpho VaultVaultMarketAllocation: represents the allocation (and configuration) of a Morpho Vault on a Morpho market
Installation
npm install @taufinancexyz/blue-sdkyarn add @taufinancexyz/blue-sdkGetting Started
Instance of the immutable configuration of a specific market
Leverage the MarketParams class to manipulate a given market's immutable configuration:
import { MarketParams } from "@taufinancexyz/blue-sdk";
const config = new MarketParams({
loanToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
collateralToken: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0", // wstETH
oracle: "0x2a01EB9496094dA03c4E364Def50f5aD1280AD72",
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC", // AdaptiveCurveIrm
lltv: 94_5000000000000000n, // 94.5%
});
config.liquidationIncentiveFactor; // e.g. 1_090000000000000000n (109%).Instance of a specific market
Leverage the Market class to manipulate a specific market:
import { Market, MarketParams } from "@taufinancexyz/blue-sdk";
import { Time } from "@taufinancexyz/morpho-ts";
const market = new Market({
config: new MarketParams({
loanToken: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
collateralToken: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0", // wstETH
oracle: "0x2a01EB9496094dA03c4E364Def50f5aD1280AD72",
irm: "0x870aC11D48B15DB9a138Cf899d20F13F79Ba00BC", // AdaptiveCurveIrm
lltv: 94_5000000000000000n, // 94.5%
}),
totalSupplyAssets: 1000_000000000000000000n,
totalBorrowAssets: 920_000000000000000000n,
totalSupplyShares: 1000_000000000000000000000000n,
totalBorrowShares: 920_000000000000000000000000n,
lastUpdate: 1721000000n,
fee: 0n,
price: 1_100000000000000000000000000000000000n,
rateAtTarget: 94850992095n,
});
market.utilization; // e.g. 92_0000000000000000n (92%).
market.liquidity; // e.g. 80_000000000000000000n (in loan assets).
market.apyAtTarget; // e.g. 3_0000000000000000n (3%).
const accruedMarket = market.accrueInterest(Time.timestamp()); // Accrue interest to the latest's timestamp.
accruedMarket.toSupplyAssets(shares); // Convert supply shares to assets.Instance of the position of a specific user on a specific market
Leverage the Position class to manipulate the position of a user on a given market:
import { Position } from "@taufinancexyz/blue-sdk";
import { Time } from "@taufinancexyz/morpho-ts";
const position = new AccrualPosition(
new Position({
user,
marketId: market.id,
supplyShares: 0n,
borrowShares: 20_000000000000000000000000n,
collateral: 27_000000000000000000n,
}),
market
);
position.borrowAssets; // e.g. 20_000000000000000000n (in loan assets).
position.isHealthy; // e.g. true.
position.maxBorrowableAssets; // e.g. 2100_000000000000000000n (in loan assets).
const accruedPosition = position.accrueInterest(Time.timestamp()); // Accrue interest to the latest's timestamp.
position.borrowAssets; // e.g. 20_400000000000000000n (in loan assets).Addresses customization
registerCustomAddresses
Extends the default address registry and unwrapped token mapping for known or custom chains. Useful for testing or adding support for new networks.
[!Note]
- Custom addresses should be registered statically, at the root level.
- Custom addresses can't be removed nor changed.
✅ Use Cases
- Injecting additional or missing contract addresses on known chains.
- Providing a full set of addresses for an unknown (custom) chain.
- Registering mappings of wrapped → unwrapped tokens per chain (e.g., WETH → ETH).
Function Signature
registerCustomAddresses(options?: {
addresses?: Record<number, ChainAddresses>; // Can be a subset of ChainAddresses if chain is known
unwrappedTokens?: Record<number, Record<Address, Address>>;
}): voidParameters
addresses(optional)
A map ofchainId → ChainAddresses.- For known chains, partial overrides are allowed (e.g., add a missing adapter).
- For unknown chains, a complete
ChainAddressesobject with required addresses must be provided. - Throws an error if you attempt to override an existing address.
unwrappedTokens(optional)
A map ofchainId → { wrapped → unwrapped }.- Throws an error if you attempt to override an existing mapping.
Behavior
- Merges user-provided addresses and unwrapped tokens into the internal registries.
- Uses a deep merge with custom logic to prevent overwriting existing values.
- Updates internal constants:
addressesRegistry,addresses, andunwrappedTokensMapping. - Applies
Object.freeze()to ensure immutability.
Example
registerCustomAddresses({
addresses: {
8453: { stEth: "0xabc..." }, // provide stEth address on base
31337: {
morpho: "0x123...",
bundler3: {
bundler3: "0x456...",
...
},
...
}, // registers a new local test chain
},
unwrappedTokens: {
31337: {
"0xWrapped": "0xUnwrapped" // e.g., WETH → ETH
}
}
});