userVaultEquities - HyperCore Info Endpoint
Get user's vault equity positions on Hyperliquid including share balances, current value, unrealized gains, and vault allocation details.
Get user's equity positions across all vaults, including share balances, current value, unrealized gains, and allocation details.
Why Hyperliquid? Build on the trading-focused EVM and HyperCore ecosystem built for onchain perpetuals and market data with HyperCore market structure, sub-second finality, and direct access to trading-focused data services.
Authenticate HyperCore Info requests by sending your Dwellir API key in the x-api-key header to https://api-hyperliquid-mainnet-info.n.dwellir.com/info.
When to Use This Endpoint
The userVaultEquities endpoint is essential for portfolio trackers, wealth managers, and investors who need to:
- Track Vault Investments — Monitor all vault positions in one place
- Calculate Portfolio Value — Get real-time value of vault holdings
- Analyze Performance — Track unrealized gains/losses across vaults
- Portfolio Management — View vault allocation and diversification
Common Use Cases
1. Calculate Total Vault Portfolio Value
Get comprehensive portfolio metrics:
async function getVaultPortfolioMetrics(userAddress) {
const equities = await getUserVaultEquities(userAddress);
if (equities.length === 0) {
return { message: 'No vault positions found' };
}
const totalCurrentValue = equities.reduce((sum, e) =>
sum + parseFloat(e.currentValue), 0
);
const totalDeposited = equities.reduce((sum, e) =>
sum + parseFloat(e.netDeposits), 0
);
const totalPnl = equities.reduce((sum, e) =>
sum + parseFloat(e.unrealizedPnl), 0
);
const weightedReturn = equities.reduce((sum, e) => {
const weight = parseFloat(e.currentValue) / totalCurrentValue;
return sum + (parseFloat(e.pnlPercent) * weight);
}, 0);
return {
totalPositions: equities.length,
totalValue: totalCurrentValue.toFixed(2),
totalDeposited: totalDeposited.toFixed(2),
totalPnl: totalPnl.toFixed(2),
totalReturnPercent: ((totalPnl / totalDeposited) * 100).toFixed(2),
weightedReturnPercent: weightedReturn.toFixed(2),
largestPosition: equities.reduce((max, e) =>
parseFloat(e.currentValue) > parseFloat(max.currentValue) ? e : max
)
};
}
// Usage
const metrics = await getVaultPortfolioMetrics('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log('Portfolio Metrics:', metrics);
console.log(`Largest position: ${metrics.largestPosition.vaultName}`);2. Check Withdrawal Availability
Determine which positions can be withdrawn:
async function checkWithdrawalAvailability(userAddress) {
const equities = await getUserVaultEquities(userAddress);
const now = Date.now();
const available = [];
const locked = [];
equities.forEach(equity => {
const position = {
vaultName: equity.vaultName,
value: parseFloat(equity.currentValue),
shares: parseFloat(equity.shares),
lockupExpiry: equity.lockupExpiry
};
if (equity.lockupExpiry <= now) {
position.status = 'Available';
available.push(position);
} else {
const daysRemaining = Math.ceil((equity.lockupExpiry - now) / (1000 * 60 * 60 * 24));
position.status = 'Locked';
position.daysRemaining = daysRemaining;
locked.push(position);
}
});
const availableValue = available.reduce((sum, p) => sum + p.value, 0);
const lockedValue = locked.reduce((sum, p) => sum + p.value, 0);
return {
available: available,
locked: locked,
availableValue: availableValue.toFixed(2),
lockedValue: lockedValue.toFixed(2),
totalValue: (availableValue + lockedValue).toFixed(2)
};
}
// Usage
const withdrawal = await checkWithdrawalAvailability('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`\nWithdrawal Status:`);
console.log(`Available: $${withdrawal.availableValue}`);
console.log(`Locked: $${withdrawal.lockedValue}`);
console.log(`\nAvailable Positions (${withdrawal.available.length}):`);
withdrawal.available.forEach(p => {
console.log(` ${p.vaultName}: $${p.value.toLocaleString()}`);
});
console.log(`\nLocked Positions (${withdrawal.locked.length}):`);
withdrawal.locked.forEach(p => {
console.log(` ${p.vaultName}: $${p.value.toLocaleString()} (${p.daysRemaining} days)`);
});3. Analyze Vault Allocation
View portfolio diversification across vaults:
async function analyzeVaultAllocation(userAddress) {
const equities = await getUserVaultEquities(userAddress);
const totalValue = equities.reduce((sum, e) =>
sum + parseFloat(e.currentValue), 0
);
const allocation = equities.map(e => {
const value = parseFloat(e.currentValue);
const percentage = (value / totalValue) * 100;
return {
vaultName: e.vaultName,
value: value,
percentage: percentage.toFixed(2),
shares: parseFloat(e.shares),
pnl: parseFloat(e.unrealizedPnl),
pnlPercent: parseFloat(e.pnlPercent)
};
}).sort((a, b) => b.value - a.value);
// Check concentration risk
const top3Concentration = allocation.slice(0, 3).reduce((sum, a) =>
sum + parseFloat(a.percentage), 0
);
return {
allocation: allocation,
totalValue: totalValue.toFixed(2),
positions: allocation.length,
top3Concentration: top3Concentration.toFixed(2),
diversified: top3Concentration < 75
};
}
// Usage
const analysis = await analyzeVaultAllocation('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`\n=== Portfolio Allocation ===`);
console.log(`Total Value: $${parseFloat(analysis.totalValue).toLocaleString()}`);
console.log(`Positions: ${analysis.positions}`);
console.log(`Top 3 Concentration: ${analysis.top3Concentration}%`);
console.log(`Diversified: ${analysis.diversified ? 'Yes' : 'No (concentrated)'}`);
console.log(`\n=== Allocation by Vault ===`);
analysis.allocation.forEach((a, i) => {
console.log(`${i + 1}. ${a.vaultName}: ${a.percentage}% ($${a.value.toLocaleString()})`);
console.log(` PnL: ${a.pnlPercent > 0 ? '+' : ''}${a.pnlPercent}%`);
});4. Track Performance Over Time
Monitor vault performance metrics:
async function trackVaultPerformance(userAddress) {
const equities = await getUserVaultEquities(userAddress);
const performance = equities.map(e => {
const currentValue = parseFloat(e.currentValue);
const depositValue = parseFloat(e.netDeposits);
const pnl = parseFloat(e.unrealizedPnl);
const pnlPercent = parseFloat(e.pnlPercent);
// Calculate holding period
const depositDate = new Date(e.depositTimestamp);
const now = new Date();
const daysHeld = Math.floor((now - depositDate) / (1000 * 60 * 60 * 24));
// Annualized return
const annualizedReturn = daysHeld > 0
? (pnlPercent / daysHeld) * 365
: 0;
return {
vaultName: e.vaultName,
currentValue: currentValue,
depositValue: depositValue,
pnl: pnl,
returnPercent: pnlPercent,
daysHeld: daysHeld,
annualizedReturn: annualizedReturn.toFixed(2),
dailyReturn: daysHeld > 0 ? (pnlPercent / daysHeld).toFixed(3) : '0.000'
};
}).sort((a, b) => parseFloat(b.annualizedReturn) - parseFloat(a.annualizedReturn));
return performance;
}
// Usage
const performance = await trackVaultPerformance('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`\n=== Vault Performance ===`);
performance.forEach((p, i) => {
console.log(`\n${i + 1}. ${p.vaultName}`);
console.log(` Value: $${p.currentValue.toLocaleString()}`);
console.log(` Return: ${p.returnPercent > 0 ? '+' : ''}${p.returnPercent}%`);
console.log(` Days Held: ${p.daysHeld}`);
console.log(` Annualized: ${p.annualizedReturn}%`);
console.log(` Daily Avg: ${p.dailyReturn}%`);
});5. Identify Best and Worst Performers
Analyze which vaults are performing well:
async function identifyPerformers(userAddress) {
const equities = await getUserVaultEquities(userAddress);
// Sort by PnL percentage
const sorted = [...equities].sort((a, b) =>
parseFloat(b.pnlPercent) - parseFloat(a.pnlPercent)
);
const bestPerformers = sorted.slice(0, 3).map(e => ({
vaultName: e.vaultName,
pnl: parseFloat(e.unrealizedPnl),
pnlPercent: parseFloat(e.pnlPercent),
value: parseFloat(e.currentValue)
}));
const worstPerformers = sorted.slice(-3).reverse().map(e => ({
vaultName: e.vaultName,
pnl: parseFloat(e.unrealizedPnl),
pnlPercent: parseFloat(e.pnlPercent),
value: parseFloat(e.currentValue)
}));
// Calculate averages
const avgPnlPercent = equities.reduce((sum, e) =>
sum + parseFloat(e.pnlPercent), 0
) / equities.length;
return {
bestPerformers: bestPerformers,
worstPerformers: worstPerformers,
avgReturn: avgPnlPercent.toFixed(2),
spread: (parseFloat(sorted[0].pnlPercent) - parseFloat(sorted[sorted.length - 1].pnlPercent)).toFixed(2)
};
}
// Usage
const performers = await identifyPerformers('0x63E8c7C149556D5f34F833419A287bb9Ef81487f');
console.log(`\n=== Best Performers ===`);
performers.bestPerformers.forEach((p, i) => {
console.log(`${i + 1}. ${p.vaultName}: +${p.pnlPercent}% ($${p.pnl.toLocaleString()})`);
});
console.log(`\n=== Worst Performers ===`);
performers.worstPerformers.forEach((p, i) => {
console.log(`${i + 1}. ${p.vaultName}: ${p.pnlPercent}% ($${p.pnl.toLocaleString()})`);
});
console.log(`\nPortfolio Statistics:`);
console.log(`Average Return: ${performers.avgReturn}%`);
console.log(`Performance Spread: ${performers.spread}%`);Best Practices
- Poll responsibly — Update vault positions every 30-60 seconds for dashboards
- Handle empty results — Users may have no vault positions
- Check lockup periods — Verify withdrawal availability before transactions
- Track allocation — Monitor portfolio concentration and diversification
- Calculate returns properly — Account for deposits/withdrawals over time
Related Endpoints
- leadingVaults — Discover top-performing vaults
- vaultSummaries — Get comprehensive vault information
- clearinghouseState — Get user's perpetual account state
- spotClearinghouseState — Get spot trading balances
Track your Hyperliquid vault investments with Dwellir's HyperCore Info Endpoint. Get your API key →