Steer Protocol SDK - v1.19.17

Steer Finance SDK

A TypeScript SDK for interacting with Steer Finance services.

npm install @steer-finance/sdk viem
# or
yarn add @steer-finance/sdk viem
# or
pnpm add @steer-finance/sdk viem
import { createPublicClient, createWalletClient, http } from 'viem';
import { mainnet } from 'viem/chains';
import { VaultClient, StakingClient } from '@steer-finance/sdk';

// Create viem clients
const publicClient = createPublicClient({
chain: mainnet,
transport: http()
});

const walletClient = createWalletClient({
chain: mainnet,
transport: http()
});

// Initialize clients
const vaultClient = new VaultClient(publicClient, walletClient, 'production');
const stakingClient = new StakingClient(publicClient, walletClient);

// Use vault operations (including single-asset deposits)
const vaults = await vaultClient.getVaults({ chainId: 1 });

// Use staking operations
const pools = await stakingClient.getStakingPools();
  • Vault Operations: Traditional vault deposits, withdrawals, and balance checking
  • Single-Asset Deposits: Deposit one token and automatically balance for LP provision
  • Staking: Interact with staking pools for rewards
  • Pool Data: Fetch pool information and statistics
  • Smart Rewards: Manage reward campaigns and claims

The StakingClient provides functionality for interacting with Steer Finance staking pools. It supports both single and dual reward staking pools.

  • Fetch available staking pools
  • Stake and withdraw tokens
  • Claim rewards
  • Check earned rewards and balances
  • Calculate APR for staking pools
  • Support for both single and dual reward pools
// Initialize the staking client
const stakingClient = steerClient.staking;

// Get all staking pools
const pools = await stakingClient.getStakingPools();

// Get pools for a specific chain
const polygonPools = await stakingClient.getStakingPools(137); // Polygon chain ID

// Stake tokens
await stakingClient.stake({
stakingPool: '0x...', // staking pool address
amount: 1000000000000000000n // amount in wei
});

// Check earned rewards
const earned = await stakingClient.earned('0x...', '0x...'); // pool address, account address
console.log('Earned rewards:', earned.data);

// Calculate APR
const apr = stakingClient.calculateAPR(
pool,
rewardTokenPriceUSD,
totalStakedUSD
);
  • getStakingPools(chainId?: number, protocol?: string): Fetch available staking pools
  • stake(params: StakeParams): Stake tokens in a pool
  • withdraw(params: WithdrawParams): Withdraw tokens from a pool
  • getReward(params: GetRewardParams): Claim rewards
  • earned(stakingPool: Address, account: Address): Get earned rewards
  • totalSupply(stakingPool: Address): Get total staked tokens
  • balanceOf(stakingPool: Address, account: Address): Get staked balance
  • calculateAPR(pool: StakingPool, rewardTokenPriceUSD: number, totalStakedUSD: number): Calculate current pool APR

The Single-Asset Deposit feature allows users to deposit only one token (token0 or token1) into a liquidity vault, while the contract internally performs a swap to balance the token pair before depositing into the vault. This eliminates the need for users to provide both tokens in the correct ratio.

  • Single Token Input: Deposit only token0 or token1 instead of both
  • Automatic Balancing: Internal swap to achieve the correct token ratio
  • Slippage Protection: Configurable slippage limits for both swap and deposit
  • Preview Functionality: Simulate the entire process before execution
  • Modular Architecture: Each step is separately testable and reusable
  • Multiple AMM Support: Currently supports UniswapV3, extensible for other AMMs
  • Comprehensive Error Handling: Detailed error messages and validation

The single-asset deposit process follows these steps:

  1. Calculate Swap Amount: Determine how much of the input token needs to be swapped
  2. Calculate Limit Price: Apply slippage protection using current pool price
  3. Simulate Swap: Preview the swap results without executing
  4. Estimate LP Tokens: Calculate expected LP token output
  5. Execute Deposit: Submit the transaction with all parameters
import { VaultClient, AMMType } from '@steerprotocol/sdk';
import { createPublicClient, createWalletClient, http, parseEther } from 'viem';
import { mainnet } from 'viem/chains';

// Setup clients
const publicClient = createPublicClient({
chain: mainnet,
transport: http()
});

const walletClient = createWalletClient({
chain: mainnet,
transport: http()
});

// Initialize vault client
const vaultClient = new VaultClient(publicClient, walletClient, 'production');

// Preview single-asset deposit
const preview = await vaultClient.previewSingleAssetDeposit({
assets: parseEther('100'), // 100 tokens to deposit
receiver: userAddress, // Address to receive LP tokens
vault: vaultAddress, // Vault contract address
isToken0: true, // Depositing token0
depositSlippagePercent: 5n, // 5% max slippage for deposit
swapSlippageBP: 500, // 5% slippage for internal swap (in basis points)
ammType: AMMType.UniswapV3, // AMM type
singleAssetDepositContract: contractAddress // Single-asset deposit contract
}, poolAddress);

if (preview.success) {
console.log('Expected LP tokens:', preview.data.lpEstimation.lpTokens);
console.log('Amount to be swapped:', preview.data.swapAmount);
console.log('Final token0 amount:', preview.data.lpEstimation.finalAmount0);
console.log('Final token1 amount:', preview.data.lpEstimation.finalAmount1);

// Execute the deposit
const result = await vaultClient.singleAssetDeposit({
assets: parseEther('100'),
receiver: userAddress,
vault: vaultAddress,
isToken0: true,
depositSlippagePercent: 5n,
swapSlippageBP: 500,
ammType: AMMType.UniswapV3,
singleAssetDepositContract: contractAddress
});

if (result.success) {
console.log('Transaction hash:', result.data);
}
}

Each step can be used independently for testing or custom implementations:

import { 
calculateSwapAmount,
calculateLimitPrice,
simulateSwap,
estimateLpTokens,
AMMType
} from '@steerprotocol/sdk';

// Step 1: Calculate swap amount
const swapResult = await calculateSwapAmount(publicClient, {
depositAmount: parseEther('100'),
isToken0: true,
vault: vaultAddress,
pool: poolAddress,
ammType: AMMType.UniswapV3,
singleAssetDepositContract: contractAddress
});

// Step 2: Calculate price limit for slippage protection
const limitPrice = await calculateLimitPrice(publicClient, {
pool: poolAddress,
slippageBP: 500,
zeroForOne: true,
ammType: AMMType.UniswapV3
});

// Step 3: Simulate the swap
const simulation = await simulateSwap(publicClient, {
pool: poolAddress,
recipient: userAddress,
zeroForOne: true,
amountSpecified: parseEther('10'),
sqrtPriceLimitX96: limitPrice,
ammType: AMMType.UniswapV3,
tokenIn: '0x...', // Token being swapped from
tokenOut: '0x...', // Token being swapped to
fee: 3000 // Pool fee in basis points
}, 137); // Chain ID (e.g., 137 for Polygon)

// Step 4: Estimate LP tokens
const estimation = await estimateLpTokens(publicClient, {
vault: vaultAddress,
originalAssets: parseEther('100'),
swapAmount: swapResult.data.swapAmount,
swapResult: simulation.data,
isToken0: true
});
import { SingleAssetDepositClient } from '@steerprotocol/sdk';

const client = new SingleAssetDepositClient(publicClient, walletClient);

// Preview deposit
const preview = await client.previewDeposit(params, poolAddress);

// Prepare transaction (without executing)
const preparedTx = await client.prepareDepositTx(params);

// Validate parameters
client.validateDepositParams(params);
enum AMMType {
UniswapV3 = 0, // ✅ Fully implemented
Algebra = 1, // 🚧 Planned
AlgebraDirectional = 2, // 🚧 Planned
AlgebraVE33 = 3, // 🚧 Planned
AlgebraIntegral = 4 // 🚧 Planned
}

Currently, only UniswapV3 is fully implemented. Other AMM types will be added in future releases.

All functions return a consistent SteerResponse<T> format:

interface SteerResponse<T> {
data: T | null;
status: number;
success: boolean;
error?: string;
}

// Example error handling
const result = await vaultClient.previewSingleAssetDeposit(params, poolAddress);
if (!result.success) {
console.error('Preview failed:', result.error);
return;
}

// Use result.data safely
console.log('LP tokens:', result.data.lpEstimation.lpTokens);
  • Invalid AMM Type: Only UniswapV3 is currently supported
  • Insufficient Liquidity: Pool doesn't have enough liquidity for the swap
  • Slippage Too High: Price moved beyond acceptable limits
  • Invalid Addresses: Zero addresses or invalid contract addresses
  • Amount Too Small: Deposit amount too small to process

Each function is designed to be independently testable:

import { calculateSwapAmount, AMMType } from '@steerprotocol/sdk';

describe('Single-Asset Deposit', () => {
it('should calculate correct swap amount', async () => {
const result = await calculateSwapAmount(publicClient, {
depositAmount: parseEther('100'),
isToken0: true,
vault: vaultAddress,
pool: poolAddress,
ammType: AMMType.UniswapV3,
singleAssetDepositContract: contractAddress
});

expect(result.success).toBe(true);
expect(result.data.swapAmount).toBeGreaterThan(0n);
});
});
Parameter Type Description
assets bigint Amount of input token to deposit
receiver Address Address to receive LP tokens
vault Address Vault contract address
isToken0 boolean true for token0, false for token1
depositSlippagePercent bigint Max slippage for deposit (in %)
swapSlippageBP number Slippage for internal swap (basis points)
ammType AMMType Type of AMM (currently UniswapV3)
singleAssetDepositContract Address Single-asset deposit contract address

The module is built with a modular architecture where each step is a separate, testable function:

src/base/vault/single-asset/
├── types.ts # TypeScript interfaces and enums
├── calculateSwapAmount.ts # Step 1: Calculate swap amount
├── calculateLimitPrice.ts # Step 2: Calculate slippage protection
├── simulateSwap.ts # Step 3: Simulate swap execution
├── estimateLpTokens.ts # Step 4: Estimate LP token output
├── singleAssetDeposit.ts # Main orchestrator client
└── index.ts # Exports everything

This design allows for:

  • Individual Testing: Each function can be unit tested separately
  • Reusability: Functions can be used in different contexts
  • Maintainability: Easy to update or extend individual components
  • Debugging: Easy to isolate issues to specific steps
  • Node.js >= 18.0.0
  • viem >= 2.22.0
  1. Install dependencies:
npm install
  1. Build the package:
npm run build
  1. Run tests:
npm test
  1. Format code:
npm run format
  1. Lint code:
npm run lint

If you encounter the following error:

import { SteerClient } from "@steerprotocol/sdk";
^^^^^^^^^^^
SyntaxError: Named export 'SteerClient' not found. The requested module '@steerprotocol/sdk' is a CommonJS module...

Add the following to your tsconfig.json:

{
"compilerOptions": {
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
}
}

MIT