@liberfi.io/ui-portfolio
v2.0.0
Published
Portfolio Components for Liberfi React SDK
Readme
@liberfi.io/ui-portfolio
Portfolio components for Liberfi React SDK. Provides portfolio page layout, holdings, curve charts, distribution, and an account / login button with a wallet overview popover showing balances, token holdings, and deposit/withdraw actions. Consumed by apps that need portfolio views and header account UI.
Design Philosophy
- Script / widget / ui layering — Logic lives in script hooks (no JSX); widgets wire hooks to UI and accept callbacks; UI components are presentational and receive formatted data and handlers.
- PortfolioProvider required — Wallet summary (balance, PnL) is provided by
PortfolioProvider; components that display balance must run inside it. - Inversion of control — Side effects (e.g. opening settings, deposit, withdraw) are passed in via props; the package does not hardcode navigation or modals.
- Single source of truth — Types and formatting come from
@liberfi.io/typesand@liberfi.io/utils; auth state from@liberfi.io/wallet-connector.
Installation
pnpm add @liberfi.io/ui-portfolioPeer dependencies
The consumer must provide:
| Package | Version |
| ------------------------------ | --------- |
| react | >= 18 |
| react-dom | >= 18 |
| @tanstack/react-query | ^5.90.2 |
| @liberfi.io/wallet-connector | workspace |
For account UI the app must also wrap the tree with AuthProvider (from @liberfi.io/wallet-connector), PortfolioProvider, and PortfolioClientProvider (from this package).
API Reference
Components (Account)
AccountInfoWidget
Login button and account popover. Renders sign-in when unauthenticated, loading when authenticating/deauthenticating, and a popover with USD balance, chain tabs, token chips, token balance rows, and deposit/withdraw actions when authenticated.
function AccountInfoWidget(props: AccountInfoWidgetProps): JSX.Element;| Prop | Type | Description |
| ------------------- | ------------ | ------------------------------------------------------------------------ |
| onAccountSettings | () => void | Optional. Called when user taps the settings gear icon. Omit to hide it. |
| onDeposit | () => void | Optional. Called when user presses Deposit. Omit to hide the button. |
| onWithdraw | () => void | Optional. Called when user presses Withdraw. Omit to hide the button. |
Requirements: Must be used inside AuthProvider, PortfolioProvider, and PortfolioClientProvider.
AccountInfoUI
Presentational account UI. Receives status, formatted balances, holdings, and callbacks. Use when you need to drive state yourself.
function AccountInfoUI(props: AccountInfoUIProps): JSX.Element;| Prop | Type | Description |
| ------------------------ | ------------------------------ | --------------------------------------------------------------------------- |
| status | AuthStatus | unauthenticated / authenticating / authenticated / deauthenticating |
| signIn | () => void \| Promise<void> | Sign-in handler |
| signOut | () => void \| Promise<void> | Sign-out handler |
| balanceUsdFormatted | string | e.g. "$1,234.56" |
| balanceNativeFormatted | string | e.g. "1.23" |
| nativeToken | PredefinedToken \| undefined | Current chain native token |
| chainLabel | string | Chain display name (e.g. "Solana") |
| holdings | SpotHolding[] | User's spot token holdings |
| isHoldingsLoading | boolean | Whether holdings are still loading |
| onAccountSettings | () => void | Optional. Settings gear handler. |
| onDeposit | () => void | Optional. Deposit button handler. |
| onWithdraw | () => void | Optional. Withdraw button handler. |
Hooks (Account)
useAccountInfo
Returns auth status, signIn/signOut, formatted balances, holdings, and chain label for the account popover. Must be used within AuthProvider, PortfolioProvider, and PortfolioClientProvider.
function useAccountInfo(): UseAccountInfoResult;| Return field | Type | Description |
| ------------------------ | ------------------------------ | ------------------------------------------- |
| status | AuthStatus | Current auth status |
| signIn | () => void \| Promise<void> | Sign-in function |
| signOut | () => void \| Promise<void> | Sign-out function |
| balanceUsdFormatted | string | Formatted USD balance |
| balanceNativeFormatted | string | Formatted native token amount |
| nativeToken | PredefinedToken \| undefined | Current chain native token |
| isSummaryReady | boolean | Whether wallet summary is available |
| chainLabel | string | Chain display name (e.g. "Solana") |
| holdings | SpotHolding[] | User's spot holdings (sorted by value desc) |
| isHoldingsLoading | boolean | Whether holdings query is loading |
Components — Portfolio (Phase 3)
Portfolio widgets introduced alongside the Phase 3 server migration. Every script calls @liberfi.io/react hooks directly and never touches @chainstream-io/sdk; the UI layers are pure presentational tables driven by props. All three widgets accept a chain + address (wallet address) pair and manage their own cursor-pagination state.
| Export | Kind | Description |
| ------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| PortfolioActivitiesWidget | Widget | Wallet activities table (Phase 3 /v2/trade/{chain}/activities) with sortBy (timestamp / totalUsd), type filter, trader tags, and gas fee. |
| PortfolioNetWorthTokensWidget | Widget | Net-worth-by-token holdings table (Phase 3 /v2/wallet/{chain}/{wallet}/net-worth/tokens) with avgCostUsd, wallet tags, and last-active-at. |
| PortfolioPnlDetailsWidget | Widget | Per-token PnL details (Phase 3 /v2/wallet/{chain}/{wallet}/pnl-details) with resolution / positionState / sortBy selectors and new fields (isClosed, firstBuyAt, lastSellAt). |
| TagBadge / TagBadgeList | UI | Shared classification chip primitive used across the Phase 3 widgets. |
Other exports
The package also exports portfolio page components (PortfolioPageWidget, usePortfolioPage, etc.), holdings, hooks (useWalletSummary, useOverviewQuery, etc.), providers, contexts, and types. See src/index.ts and src/components/index.tsx for the full list.
Usage Examples
Account button in a header
import {
PortfolioProvider,
PortfolioClientProvider,
AccountInfoWidget,
} from "@liberfi.io/ui-portfolio";
import { AuthProvider } from "@liberfi.io/wallet-connector";
function App() {
return (
<AuthProvider {...authProps}>
<PortfolioClientProvider client={portfolioClient}>
<PortfolioProvider chain={chain} address={address}>
<Header>
<AccountInfoWidget
onAccountSettings={() => openSettings()}
onDeposit={() => openDeposit()}
onWithdraw={() => openWithdraw()}
/>
</Header>
</PortfolioProvider>
</PortfolioClientProvider>
</AuthProvider>
);
}Without action buttons
Omit callbacks to hide the corresponding UI elements:
<AccountInfoWidget />Composing the portfolio page
import {
PortfolioActivitiesWidget,
PortfolioNetWorthTokensWidget,
PortfolioPnlDetailsWidget,
} from "@liberfi.io/ui-portfolio";
function PortfolioPage({ chain, address }: { chain: Chain; address: string }) {
return (
<div className="flex flex-col gap-6">
<PortfolioNetWorthTokensWidget chain={chain} address={address} />
<PortfolioPnlDetailsWidget chain={chain} address={address} />
<PortfolioActivitiesWidget chain={chain} address={address} />
</div>
);
}Future Improvements
- Optional portfolio context so the account widget can render outside
PortfolioProviderwith placeholder balances. - ARIA and keyboard improvements for the popover trigger.
- Perps tab integration when perps positions data is available.
- Portfolio Phase 3 widgets: add CSV / image export, and support grouped tokens (by chain) for multi-chain wallets.
