The Metastable SDK is a TypeScript library for interacting with the Metastable protocol on the Sui blockchain. The Metastable protocol allows users to mint and burn meta coins (e.g., mUSD, mSUI) by depositing or withdrawing supported assets into/from Meta Vaults, with dynamic withdrawal fees to maintain target liquidity distributions.
Key Features
Deposit: Mint meta coins (e.g., mUSD) by depositing supported assets (e.g., USDC) into a Meta Vault. Deposits are free (0% fee) and use on-chain price feeds for accurate conversions.
Withdraw: Burn meta coins to withdraw assets from a Meta Vault, subject to a dynamic withdrawal fee (0.01% to 1%) that incentivizes target liquidity distributions.
Fetch Vault Data: Retrieve vault information, such as deposit caps, total deposits, and fees for each supported asset.
Calculate Fees and Limits: Compute dynamic withdrawal fees, maximum deposits, and maximum withdrawals based on vault data and asset prices.
Ensure you have the following dependencies installed in your project:
@mysten/sui (for Sui blockchain interactions)
@pythnetwork/pyth-sui-js (for Pyth price feeds)
Usage
Initialize the SDK
First, create an instance of MetastableSDK with a SuiClient connected to the Sui blockchain.
import { SuiClient } from "@mysten/sui/client";
import { MetastableSDK } from "metastable-ts-sdk";
const suiClient = new SuiClient({ url: "https://fullnode.mainnet.sui.io" });
const sdk = new MetastableSDK({ suiClient });
Mint Meta Coins (Deposit)
Deposit a supported asset into a Meta Vault to mint meta coins. Deposits are free (0% fee). The amount of meta coin minted is determined by the on-chain price feed.
Example: Mint mUSD with USDC
import { M_USD } from "metastable-ts-sdk";
async function mintMUSD() {
try {
const tx = await sdk.buildMintTx({
mCoin: M_USD.coin,
coin: "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
amountIn: 100,
walletAddress: "0xYourWalletAddress",
minAmountOut: 99.5, // Optional, defaults to 0
});
// Sign and execute the transaction using your wallet
// Example: const result = await wallet.signAndExecuteTransaction({ transaction: tx });
console.log("Mint transaction built:", tx);
} catch (error) {
console.error("Error minting mUSD:", error);
}
}
mintMUSD();
Burn Meta Coins (Withdraw)
Burn meta coins to withdraw assets from a Meta Vault. Withdrawals incur a dynamic fee (0.01% to 1%) based on the vault's target liquidity distribution.
Example: Burn mUSD to Withdraw USDC
import { M_USD } from "metastable-ts-sdk";
async function burnMUSD() {
try {
const tx = await sdk.buildBurnTx({
mCoin: M_USD.coin,
coin: "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
amountIn: 50,
walletAddress: "0xYourWalletAddress",
minAmountOut: 49.5, // Optional, defaults to 0
});
// Sign and execute the transaction using your wallet
// Example: const result = await wallet.signAndExecuteTransaction({ transaction: tx });
console.log("Burn transaction built:", tx);
} catch (error) {
console.error("Error burning mUSD:", error);
}
}
burnMUSD();
Fetch Vault Data
Retrieve data about a Meta Vault, including deposit caps, total deposits, fees, and priorities for each supported asset.
The SDK provides functions to calculate the amounts involved in minting and burning meta coins.
Calculate Mint Amount Out from Amount In: Determine how much meta coin you will receive for a given amount of collateral coin deposited.
const amountOut = sdk.calcMintAmountOutFromAmountIn({
amountIn: 100, // Amount of USDC to deposit
coinPrice: await sdk.fetchCoinPrice({ coin: usdcCoin }), // Price of USDC in USD
mCoinPrice: await sdk.fetchCoinPrice({ coin: vault.mCoin }), // Price of mUSD in USD
});
console.log(`Minted mUSD: ${amountOut}`); // e.g., "Minted mUSD: 100"
Calculate Mint Amount In from Amount Out: Determine how much collateral coin is needed to mint a specific amount of meta coin.
const amountIn = sdk.calcMintAmountInFromAmountOut({
amountOut: 100, // Desired amount of mUSD to mint
coinPrice: await sdk.fetchCoinPrice({ coin: usdcCoin }), // Price of USDC in USD
mCoinPrice: await sdk.fetchCoinPrice({ coin: vault.mCoin }), // Price of mUSD in USD
});
console.log(`Required USDC: ${amountIn}`); // e.g., "Required USDC: 100"
Calculate Burn Amount Out from Amount In: Determine how much collateral coin you will receive for burning a specific amount of meta coin, accounting for the dynamic fee.
Calculate Burn Amount In from Amount Out: Determine how much meta coin you need to burn to receive a specific amount of collateral coin, accounting for the dynamic fee.
The Metastable SDK provides a method called fetchCoinPrice to retrieve the latest price for a specified coin type. This functionality is essential for tasks like calculating conversions, fees, or any other price-dependent values. The method supports:
Pyth-supported coins (e.g., SUI, USDC): Prices are fetched directly from Pyth price feeds.
mSUI and Liquid Staking Tokens (LSTs): Prices are calculated based on exchange rates relative to SUI, using on-chain data.
Example 1: Fetch SUI Price
Here’s how to fetch the price of SUI, a coin supported by Pyth price feeds:
import { SUI } from "metastable-ts-sdk";
async function fetchSUIPrice() {
try {
const price = await sdk.fetchCoinPrice({ coin: SUI.coin });
console.log(`SUI Price: ${price} USD`); // Example output: "SUI Price: 1.5 USD"
} catch (error) {
console.error("Error fetching SUI price:", error);
}
}
fetchSUIPrice();
Example 2: Fetch mSUI Price
For mSUI, the price is calculated using its exchange rate relative to SUI:
Deposit Caps: Each Meta Vault enforces deposit caps for supported assets. Check the latest caps on X (@MetaStables) or use fetchVault to retrieve them programmatically.
Dynamic Fees: Withdrawal fees range from 0.01% to 1%, depending on the vault's liquidity distribution. Use calcBurnFeeFromAmountIn to estimate fees before withdrawing.
Price Feeds: The SDK uses Pyth price feeds for accurate conversions between meta coins and collateral assets. Ensure your SuiClient is connected to a Sui network with access to these feeds.
Error Handling: Always wrap SDK calls in try-catch blocks to handle potential errors, such as unsupported coins or network issues.