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();
The StakingClient provides functionality for interacting with Steer Finance staking pools. It supports both single and dual reward staking 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 poolsstake(params: StakeParams)
: Stake tokens in a poolwithdraw(params: WithdrawParams)
: Withdraw tokens from a poolgetReward(params: GetRewardParams)
: Claim rewardsearned(stakingPool: Address, account: Address)
: Get earned rewardstotalSupply(stakingPool: Address)
: Get total staked tokensbalanceOf(stakingPool: Address, account: Address)
: Get staked balancecalculateAPR(pool: StakingPool, rewardTokenPriceUSD: number, totalStakedUSD: number)
: Calculate current pool APRThe 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.
The single-asset deposit process follows these steps:
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);
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:
npm install
npm run build
npm test
npm run format
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