> ## Documentation Index
> Fetch the complete documentation index at: https://zyfai.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# getPortfolio

Get a detailed and accurate portfolio view for a user, including positions, balances by asset type, and session key status. This method provides more accurate data than `getPositions`, use it to display portfolio value in your UI.

Balances are enriched with **net-of-pending-fee** fields (`balanceWithFee`, `underlyingAmountWithFee`). The pending fee is derived from onchain `current` earnings × the Zyfi fee rate (10%). Gross fields (`balance`, `underlyingAmount`) are unchanged. If earnings cannot be fetched, `*WithFee` equals the gross value so the response shape stays stable.

<Tip title="User-facing display">
  Show `balanceWithFee` / `underlyingAmountWithFee` as the primary numbers in your product UI (parity with the Zyfai app). Gross fields remain available for debugging or advanced transparency.
</Tip>

## Signature

```typescript theme={null}
getPortfolio(userAddress: string): Promise<PortfolioDetailedResponse>
```

## Parameters

| Parameter     | Type     | Required | Description        |
| ------------- | -------- | -------- | ------------------ |
| `userAddress` | `string` | ✅        | User's EOA address |

## Returns

Detailed portfolio data including positions and balances by asset type, plus fee-adjusted balance fields.

## Return Type

```typescript theme={null}
interface PortfolioDetailedResponse {
  success: boolean;
  userAddress: string;
  portfolio: PortfolioDetailed;
}

interface PortfolioAssetBalance {
  balance: Hex;           // gross (live)
  balanceWithFee?: Hex;   // live − pending fee — SHOW THIS
  decimals: number;
}

type PortfolioByAssetType = Record<string, PortfolioAssetBalance>;

type PortfolioByChain = Record<string, PortfolioByAssetType>;

interface PortfolioDetailed {
  hasBalance?: boolean;
  staleBalances?: string[];
  hasActiveSessionKey?: boolean;
  positions?: PositionSlot[];
  portfolioByAssetType?: PortfolioByAssetType;
  portfolioByChain?: PortfolioByChain;
}

interface PositionSlot {
  chain?: string;
  protocol_id?: string;
  protocol_name?: string;
  protocol_icon?: string;
  pool?: string;
  token_id?: string;
  token_symbol?: string;
  token_icon?: string;
  amount?: string;
  underlyingAmount?: string;        // gross
  underlyingAmountWithFee?: string; // SHOW THIS
  pool_apy?: number;
  pool_tvl?: number;
  liquidity?: number;
  decimals?: number;
}
```

## How `*WithFee` is calculated

```text theme={null}
pendingFee(token[, chain]) = current_earnings × 0.1
balanceWithFee             = liveBalance − pendingFee
```

* Fee source: **`current_earnings_by_chain` only** (fetched in parallel with the portfolio)
* Multiple positions on the same chain + token: fee is split **proportionally** by `underlyingAmount`
* Portfolio balances are live; earnings used for the fee may be from a snapshot — small mismatches are possible

## Example

```typescript theme={null}
import { formatUnits } from "viem";

const { portfolio } = await sdk.getPortfolio("0xUser...");

// Check session key status
console.log("Has active session key:", portfolio.hasActiveSessionKey);

// User-facing balances by asset type (prefer balanceWithFee)
if (portfolio.portfolioByAssetType) {
  Object.entries(portfolio.portfolioByAssetType).forEach(([asset, data]) => {
    const hex = data.balanceWithFee ?? data.balance;
    console.log(`${asset}: ${formatUnits(BigInt(hex), data.decimals)}`);
  });
}

// Per-chain (same fields)
const usdcOnBase = portfolio.portfolioByChain?.["8453"]?.usdc?.balanceWithFee;

// Positions — prefer underlyingAmountWithFee
portfolio.positions?.forEach((p) => {
  console.log(
    `${p.protocol_name} (${p.chain}): ${p.underlyingAmountWithFee ?? p.underlyingAmount} ${p.token_symbol} @ ${p.pool_apy}% APY`
  );
});
```

## Notes

* This method automatically resolves the smart wallet address from the EOA
* If no smart wallet exists for the user, returns an empty portfolio
* Auth is not required for this read path
* `portfolioByAssetType` provides balances grouped by token (e.g., USDC, WETH, EURC)
* `portfolioByChain` provides the same balance structure grouped by chain, then by asset type
* Decode hex / wei amounts with the correct `decimals` (USDC/EURC = 6, WETH = 18, …)
* For earnings net of fee, see [getOnchainEarnings](/docs/sdk/api/get-onchain-earnings)
* For legacy position data, see [getPositions](/docs/sdk/api/get-positions)
