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 🙏

© 2025 – Pkg Stats / Ryan Hefner

nemo-vaults-sdk

v1.0.69

Published

A TypeScript SDK for interacting with Nemo Vaults on the Sui blockchain. This SDK provides comprehensive functionality for managing liquidity vaults, including deposits, withdrawals, rebalancing, and administrative operations.

Readme

Nemo Vaults SDK

A TypeScript SDK for interacting with Nemo Vaults on the Sui blockchain. This SDK provides comprehensive functionality for managing liquidity vaults, including deposits, withdrawals, rebalancing, and administrative operations.

Features

  • Vault Management: Create, configure, and manage different types of vaults (Stable, Uncorrelated, Drift)
  • Liquidity Operations: Deposit and withdraw liquidity with automatic optimization
  • Automated Bots: Built-in reward collection and rebalancing bots
  • Administrative Functions: Complete admin interface for vault configuration
  • Multi-Protocol Support: Integration with various staking protocols (Haedal, Volo, Aftermath)
  • Docker Support: Ready-to-use Docker containers for production deployment

Installation

npm install nemo-vaults-sdk
# or
yarn add nemo-vaults-sdk
# or
pnpm add nemo-vaults-sdk

Quick Start

import { Vaults, Admin } from 'nemo-vaults-sdk';
import { SuiClient } from '@mysten/sui/client';

// Initialize the SDK
const suiClient = new SuiClient({ url: 'https://sui-mainnet.blockvision.org' });
const vaults = Vaults.createSDK({
  client: suiClient,
  senderAddress: 'your-wallet-address'
});

// Get all vaults
const vaultList = await vaults.getVaultList();

// Get a specific vault
const vault = await vaults.getVault('vault-id');

// Get user's vault balances
const balances = await vaults.getOwnerVaultsBalance('user-address');

Core Concepts

Vault Types

  1. Stable Vaults: Optimized for stable asset pairs with minimal price volatility
  2. Uncorrelated Vaults: Designed for assets with low correlation, includes rebalancing triggers
  3. Drift Vaults: Specialized for trending markets with directional price movements

Liquidity Management

  • Both-sided deposits: Provide both tokens in optimal ratio
  • One-sided deposits: Provide single token with automatic swapping
  • Flexible withdrawals: Withdraw as LP tokens or individual assets
  • Slippage protection: Configurable slippage tolerance for all operations

Examples

Basic Vault Operations

import { Vaults, Admin, InputType } from 'nemo-vaults-sdk';
import { SuiClient } from '@mysten/sui/client';
import { Transaction } from '@mysten/sui/transactions';

// Initialize the SDK
const suiClient = new SuiClient({ url: 'https://sui-mainnet.blockvision.org' });
const vaults = Vaults.createSDK({
  client: suiClient,
  senderAddress: 'your-wallet-address'
});

async function basicVaultOperations() {
  try {
    // 1. Get all available vaults
    console.log('Fetching all vaults...');
    const allVaults = await vaults.getVaultList();
    console.log(`Found ${allVaults.length} vaults`);

    // 2. Get detailed information about a specific vault
    const vaultId = allVaults[0].id;
    const vault = await vaults.getVault(vaultId);
    if (!vault) {
      console.error('Vault not found');
      return;
    }
    console.log('Vault details:', {
      id: vault.id,
      coinTypeA: vault.coin_type_a,
      coinTypeB: vault.coin_type_b,
      totalSupply: vault.total_supply,
      depositEnabled: vault.is_deposit_enabled
    });

    // 3. Check user's vault balances
    const userAddress = 'user-wallet-address';
    const userBalances = await vaults.getOwnerVaultsBalance(userAddress);
    console.log(`User has positions in ${userBalances.length} vaults`);

    // 4. Calculate deposit amount for one-sided deposit
    console.log('Calculating deposit amount...');
    const depositCalc = await vaults.calculateDepositAmount({
      vault_id: vaultId,
      is_amount_a: true,
      input_amount: '1000000', // 1 token (assuming 6 decimals)
      slippage: 0.01, // 1% slippage
      side: InputType.OneSide
    });

    console.log('Deposit calculation result:', {
      amountA: depositCalc.amount_a,
      amountB: depositCalc.amount_b,
      lpTokens: depositCalc.ft_amount,
      swapRequired: !!depositCalc.swap_result
    });

    // 5. Execute deposit transaction
    const tx = new Transaction();
    const lpToken = await vaults.deposit({
      vault_id: vaultId,
      slippage: 0.01,
      deposit_result: depositCalc,
      return_coin: true
    }, tx);

    console.log('Deposit transaction prepared');
    // Note: You would sign and execute the transaction here

  } catch (error) {
    console.error('Error in vault operations:', error);
  }
}

Deposit and Withdrawal Operations

async function depositWithdrawExample() {
  // Initialize SDK
  const suiClient = new SuiClient({ url: 'https://sui-mainnet.blockvision.org' });
  const vaults = Vaults.createSDK({
    client: suiClient,
    senderAddress: 'your-wallet-address'
  });

  const vaultId = 'your-vault-id';
  const slippage = 0.01; // 1% slippage tolerance

  try {
    // === DEPOSIT OPERATIONS ===
    
    // 1. One-sided deposit (provide only token A)
    console.log('Calculating one-sided deposit...');
    const oneSidedDeposit = await vaults.calculateDepositAmount({
      vault_id: vaultId,
      is_amount_a: true,
      input_amount: '1000000', // 1 token A (assuming 6 decimals)
      slippage,
      side: InputType.OneSide
    });

    console.log('One-sided deposit calculation:', {
      inputAmount: oneSidedDeposit.original_input_amount,
      amountA: oneSidedDeposit.amount_a,
      amountB: oneSidedDeposit.amount_b,
      lpTokens: oneSidedDeposit.ft_amount,
      swapRequired: !!oneSidedDeposit.swap_result
    });

    // Execute one-sided deposit
    const depositTx = new Transaction();
    await vaults.deposit({
      vault_id: vaultId,
      slippage,
      deposit_result: oneSidedDeposit,
      return_coin: false // Transfer LP tokens to user
    }, depositTx);

    console.log('One-sided deposit transaction prepared');

    // 2. Both-sided deposit (provide both tokens)
    console.log('Calculating both-sided deposit...');
    const bothSidedDeposit = await vaults.calculateDepositAmount({
      vault_id: vaultId,
      is_amount_a: true,
      input_amount: '1000000', // 1 token A
      slippage,
      side: InputType.Both
    });

    console.log('Both-sided deposit calculation:', {
      amountA: bothSidedDeposit.amount_a,
      amountB: bothSidedDeposit.amount_b,
      lpTokens: bothSidedDeposit.ft_amount
    });

    // Execute both-sided deposit
    const bothDepositTx = new Transaction();
    await vaults.deposit({
      vault_id: vaultId,
      slippage,
      deposit_result: bothSidedDeposit,
      return_coin: false
    }, bothDepositTx);

    console.log('Both-sided deposit transaction prepared');

    // === WITHDRAWAL OPERATIONS ===

    // 1. Both-sided withdrawal (receive both tokens)
    console.log('Calculating both-sided withdrawal...');
    const bothSidedWithdraw = await vaults.calculateWithdrawAmount({
      vault_id: vaultId,
      is_amount_a: true,
      is_ft_input: true,
      input_amount: oneSidedDeposit.ft_amount, // Withdraw all LP tokens
      max_ft_amount: oneSidedDeposit.ft_amount,
      slippage,
      side: InputType.Both
    });

    console.log('Both-sided withdrawal calculation:', {
      burnAmount: bothSidedWithdraw.burn_ft_amount,
      receiveA: bothSidedWithdraw.amount_a,
      receiveB: bothSidedWithdraw.amount_b
    });

    // Execute both-sided withdrawal
    const withdrawTx = new Transaction();
    await vaults.withdraw({
      vault_id: vaultId,
      ft_amount: bothSidedWithdraw.burn_ft_amount,
      slippage,
      return_coin: false
    }, withdrawTx);

    console.log('Both-sided withdrawal transaction prepared');

    // 2. One-sided withdrawal (receive only token A)
    console.log('Calculating one-sided withdrawal...');
    const oneSidedWithdraw = await vaults.calculateWithdrawAmount({
      vault_id: vaultId,
      is_amount_a: true,
      is_ft_input: false,
      input_amount: '1000000', // Want to receive 1 token A
      max_ft_amount: oneSidedDeposit.ft_amount,
      slippage,
      side: InputType.OneSide
    });

    console.log('One-sided withdrawal calculation:', {
      burnAmount: oneSidedWithdraw.burn_ft_amount,
      receiveA: oneSidedWithdraw.amount_a,
      receiveB: oneSidedWithdraw.amount_b,
      swapRequired: !!oneSidedWithdraw.swap_result
    });

    // Execute one-sided withdrawal
    const oneSideWithdrawTx = new Transaction();
    await vaults.withdraw({
      vault_id: vaultId,
      is_amount_a: true,
      is_ft_input: false,
      input_amount: '1000000',
      max_ft_amount: oneSidedDeposit.ft_amount,
      slippage,
      return_coin: false
    }, oneSideWithdrawTx);

    console.log('One-sided withdrawal transaction prepared');

    // === ADVANCED: Using coin objects ===

    // Deposit with specific coin objects
    const advancedDepositTx = new Transaction();
    const coinA = advancedDepositTx.splitCoins(advancedDepositTx.gas, [1000000]);
    const coinB = advancedDepositTx.splitCoins(advancedDepositTx.gas, [1000000]);

    await vaults.deposit({
      vault_id: vaultId,
      coin_object_a: coinA,
      coin_object_b: coinB,
      slippage,
      deposit_result: bothSidedDeposit,
      return_coin: true // Return LP token object
    }, advancedDepositTx);

    console.log('Advanced deposit with coin objects prepared');

  } catch (error) {
    console.error('Error in deposit/withdraw operations:', error);
  }
}

Administrative Operations

async function adminOperations() {
  const admin = Admin.createSDK({
    fullNodeUrl: 'https://sui-mainnet.blockvision.org',
    senderAddress: 'admin-wallet-address'
  });

  try {
    // Create a new stable vault
    const tx = await admin.newStableVault({
      pool_id: 'clmm-pool-id',
      treasury_cap_id: 'treasury-cap-id',
      upper_price_scalling: '1.1', // 10% above current price
      lower_price_scalling: '0.9', // 10% below current price
      slippage_up: '0.02', // 2% slippage tolerance up
      slippage_down: '0.02', // 2% slippage tolerance down
      free_threshold_a: '1000000', // 1 token A threshold
      free_threshold_b: '1000000', // 1 token B threshold
      fee_val: '0.003', // 0.3% fee
      withdraw_fee_val: '0.001', // 0.1% withdrawal fee
      decimals_a: 6,
      decimals_b: 6,
      deposit_limit: '1000000000', // 1000 tokens limit
      coin_type_a: '0x2::sui::SUI',
      coin_type_b: '0x...::usdc::USDC',
      coin_type_token: '0x...::lp_token::LP_TOKEN'
    });

    console.log('Stable vault creation transaction prepared');

    // Configure vault settings
    const configTx = new Transaction();
    await admin.setDepositLimit('vault-id', 'vault-cap', 2000000000n, configTx);
    // await admin.setSlippage('risk-admin-cap', 'vault-id', '0.03', '0.03', configTx);

    console.log('Vault configuration transaction prepared');

  } catch (error) {
    console.error('Error in admin operations:', error);
  }
}

Monitoring Vault Performance

async function monitorVaultPerformance() {
  const suiClient = new SuiClient({ url: 'https://sui-mainnet.blockvision.org' });
  const vaults = Vaults.createSDK({
    client: suiClient,
    senderAddress: 'your-wallet-address'
  });

  const userAddress = 'user-wallet-address';

  try {
    // Get user's positions across all vaults
    const userBalances = await vaults.getOwnerVaultsBalance(userAddress);
    
    console.log(`User has positions in ${userBalances.length} vaults:`);
    
    for (const balance of userBalances) {
      console.log(`
Vault: ${balance.vault_id}
LP Token Balance: ${balance.lp_token_balance}
Underlying Token A: ${balance.amount_a} (${balance.coin_type_a})
Underlying Token B: ${balance.amount_b} (${balance.coin_type_b})
Position Range: ${balance.tick_lower_index} to ${balance.tick_upper_index}
      `);
    }

    // Get detailed vault information
    for (const balance of userBalances) {
      const vault = await vaults.getVault(balance.vault_id);
      if (vault) {
        console.log(`
Vault ${vault.id} Details:
- Type: ${vault.config_type}
- Total Supply: ${vault.total_supply}
- Deposit Enabled: ${vault.is_deposit_enabled}
- Locked: ${vault.is_lock}
- Fee: ${vault.fee_val}
- Withdraw Fee: ${vault.withdraw_fee_val}
- Last Rebalance: ${new Date(parseInt(vault.last_rebalance_time) * 1000).toISOString()}
        `);
      }
    }

  } catch (error) {
    console.error('Error monitoring vault performance:', error);
  }
}

API Reference

Vaults Class

The main class for interacting with vaults.

Creating an Instance

const vaults = Vaults.createSDK({
  client: suiClient,           // SuiClient instance
  senderAddress: 'address'     // Your wallet address
});

// Or with custom RPC URL
const vaults = Vaults.createSDK({
  fullNodeUrl: 'https://custom-rpc-url',
  senderAddress: 'address'
});

Core Methods

getVaultList()

Retrieves all available vaults.

const vaults = await sdk.getVaultList();
getVault(id: string)

Get detailed information about a specific vault.

const vault = await sdk.getVault('vault-id');
getOwnerVaultsBalance(address: string)

Get user's balances across all vaults.

const balances = await sdk.getOwnerVaultsBalance('user-address');

Deposit Operations

calculateDepositAmount(params)

Calculate optimal deposit amounts and required swaps.

const depositCalc = await sdk.calculateDepositAmount({
  vault_id: 'vault-id',
  is_amount_a: true,
  input_amount: '1000000',
  slippage: 0.01,
  side: InputType.OneSide
});
deposit(params, tx)

Execute a deposit transaction.

import { Transaction } from '@mysten/sui/transactions';

const tx = new Transaction();
const result = await sdk.deposit({
  vault_id: 'vault-id',
  slippage: 0.01,
  deposit_result: depositCalc,
  return_coin: true
}, tx);

Withdrawal Operations

calculateWithdrawAmount(params)

Calculate withdrawal amounts and required swaps.

const withdrawCalc = await sdk.calculateWithdrawAmount({
  vault_id: 'vault-id',
  is_amount_a: true,
  is_ft_input: true,
  input_amount: '1000000',
  max_ft_amount: '2000000',
  slippage: 0.01,
  side: InputType.OneSide
});
withdraw(params, tx)

Execute a withdrawal transaction.

const tx = new Transaction();
const result = await sdk.withdraw({
  vault_id: 'vault-id',
  ft_amount: '1000000',
  slippage: 0.01,
  return_coin: true
}, tx);

Admin Class

Administrative functions for vault management.

Creating an Instance

const admin = Admin.createSDK({
  fullNodeUrl: 'https://sui-mainnet.blockvision.org',
  senderAddress: 'admin-address'
});

Vault Creation

newStableVault(params)

Create a new stable vault.

const tx = await admin.newStableVault({
  pool_id: 'clmm-pool-id',
  treasury_cap_id: 'treasury-cap-id',
  upper_price_scalling: '1.1',
  lower_price_scalling: '0.9',
  slippage_up: '0.01',
  slippage_down: '0.01',
  free_threshold_a: '1000000',
  free_threshold_b: '1000000',
  fee_val: '0.003',
  withdraw_fee_val: '0.001',
  decimals_a: 6,
  decimals_b: 6,
  deposit_limit: '1000000000',
  coin_type_a: 'coin-type-a',
  coin_type_b: 'coin-type-b',
  coin_type_token: 'lp-token-type'
});
newUncorrelatedVault(params)

Create a new uncorrelated vault with rebalancing triggers.

const tx = await admin.newUncorrelatedVault({
  // ... similar params as stable vault
  lock_threshold_a: '5000000',
  lock_threshold_b: '5000000',
  target_adapter: 'price-adapter',
  is_target_reverse: false
});

Vault Configuration

setDepositLimit(vaultId, vaultCap, limit)

Update vault deposit limits.

await admin.setDepositLimit('vault-id', 'vault-cap', 1000000000n, tx);
setFee(adminCap, vaultId, feeVal)

Set vault fee percentages.

await admin.setFee('admin-cap', 'vault-id', '0.003', tx);

Types and Interfaces

Vault Interface

interface Vault {
  id: string;
  clmm_pool_id: string;
  coin_type_a: string;
  coin_type_b: string;
  lp_token_type: string;
  config_type: string;
  total_supply: string;
  deposit_limit: string;
  is_deposit_enabled: boolean;
  is_lock: boolean;
  // ... additional properties
}

Calculation Parameters

interface CalculateAmountParams {
  vault_id: string;
  is_amount_a: boolean;
  input_amount: string;
  slippage: number;
  side: InputType;
}

enum InputType {
  Both = 'both',
  OneSide = 'oneSide'
}

Automated Bots

The SDK includes two automated bots for production use:

Reward Bot

Automatically collects and compounds vault rewards.

# Run directly
pnpm run run:reward

# Or with Docker
docker-compose up reward-bot

Rebalance Bot

Monitors and rebalances uncorrelated vaults when price thresholds are reached.

# Run directly  
pnpm run run:rebalance

# Or with Docker
docker-compose up rebalance-bot

Environment Configuration

Create a .env file with the following variables:

# Sui Network
SUI_PRIVATE_KEY=your-base64-encoded-private-key
FULL_NODE_URL=https://sui-mainnet.blockvision.org

# Slack Notifications (for bots)
SLACK_TOKEN=xoxb-your-slack-bot-token
SLACK_CONVERSATION_ID=your-channel-id
SLACK_VAULT_REBALANCE_CONVERSATION_ID=rebalance-channel-id

# Optional
NODE_ENV=production

Docker Deployment

The SDK provides ready-to-use Docker containers:

# Build and run both bots
docker-compose up -d

# Run specific bot
docker-compose up -d reward-bot
docker-compose up -d rebalance-bot

# View logs
docker-compose logs -f reward-bot

See DOCKER.md for detailed Docker setup instructions.

Error Handling

The SDK uses a comprehensive error handling system:

import { VaultsErrorCode } from 'nemo-vaults-sdk';

try {
  const vault = await vaults.getVault('invalid-id');
} catch (error) {
  if (error.code === VaultsErrorCode.ObjectNotFound) {
    console.log('Vault not found');
  }
}

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests
  5. Submit a pull request

License

MIT License

Support

For issues and questions:

Development Setup

# Install dependencies
pnpm install

# Build the SDK
pnpm run build

# Run tests
pnpm test

# Build bots
pnpm run build:all