@liberfi.io/ui-portfolio 3.0.72 → 3.0.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.d.mts +5 -5
- package/dist/client/index.d.ts +5 -5
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs.map +1 -1
- package/dist/{index-Bq_qim6b.d.mts → index-BK-jWEQ7.d.mts} +1 -1
- package/dist/{index-Bq_qim6b.d.ts → index-BK-jWEQ7.d.ts} +1 -1
- package/dist/index.d.mts +55 -6
- package/dist/index.d.ts +55 -6
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +20 -15
package/dist/client/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as IPortfolioClient, P as PortfolioQuery, b as PortfolioOverview, S as SpotHoldingsData,
|
|
1
|
+
import { I as IPortfolioClient, P as PortfolioQuery, b as PortfolioOverview, S as SpotHoldingsData, l as SpotHistoryQuery, d as SpotHistoryData, p as CurveQuery, c as CurveData, e as PerpsPositionsData, n as PerpsHistoryQuery, f as PerpsHistoryData, g as PredictionBetsData, o as PredictionSettledQuery, h as PredictionSettledData } from '../index-BK-jWEQ7.mjs';
|
|
2
2
|
import '@tanstack/react-query';
|
|
3
3
|
import '@liberfi.io/types';
|
|
4
4
|
|
|
@@ -9,10 +9,10 @@ declare class PortfolioClient implements IPortfolioClient {
|
|
|
9
9
|
getSpotHoldings(query?: PortfolioQuery): Promise<SpotHoldingsData>;
|
|
10
10
|
getSpotHistory(query?: SpotHistoryQuery): Promise<SpotHistoryData>;
|
|
11
11
|
getChartData(query: CurveQuery): Promise<CurveData>;
|
|
12
|
-
getPerpsPositions(
|
|
13
|
-
getPerpsHistory(
|
|
14
|
-
getPredictionBets(
|
|
15
|
-
getPredictionSettled(
|
|
12
|
+
getPerpsPositions(query?: PortfolioQuery): Promise<PerpsPositionsData>;
|
|
13
|
+
getPerpsHistory(query?: PerpsHistoryQuery): Promise<PerpsHistoryData>;
|
|
14
|
+
getPredictionBets(query?: PortfolioQuery): Promise<PredictionBetsData>;
|
|
15
|
+
getPredictionSettled(query?: PredictionSettledQuery): Promise<PredictionSettledData>;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export { PortfolioClient };
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { I as IPortfolioClient, P as PortfolioQuery, b as PortfolioOverview, S as SpotHoldingsData,
|
|
1
|
+
import { I as IPortfolioClient, P as PortfolioQuery, b as PortfolioOverview, S as SpotHoldingsData, l as SpotHistoryQuery, d as SpotHistoryData, p as CurveQuery, c as CurveData, e as PerpsPositionsData, n as PerpsHistoryQuery, f as PerpsHistoryData, g as PredictionBetsData, o as PredictionSettledQuery, h as PredictionSettledData } from '../index-BK-jWEQ7.js';
|
|
2
2
|
import '@tanstack/react-query';
|
|
3
3
|
import '@liberfi.io/types';
|
|
4
4
|
|
|
@@ -9,10 +9,10 @@ declare class PortfolioClient implements IPortfolioClient {
|
|
|
9
9
|
getSpotHoldings(query?: PortfolioQuery): Promise<SpotHoldingsData>;
|
|
10
10
|
getSpotHistory(query?: SpotHistoryQuery): Promise<SpotHistoryData>;
|
|
11
11
|
getChartData(query: CurveQuery): Promise<CurveData>;
|
|
12
|
-
getPerpsPositions(
|
|
13
|
-
getPerpsHistory(
|
|
14
|
-
getPredictionBets(
|
|
15
|
-
getPredictionSettled(
|
|
12
|
+
getPerpsPositions(query?: PortfolioQuery): Promise<PerpsPositionsData>;
|
|
13
|
+
getPerpsHistory(query?: PerpsHistoryQuery): Promise<PerpsHistoryData>;
|
|
14
|
+
getPredictionBets(query?: PortfolioQuery): Promise<PredictionBetsData>;
|
|
15
|
+
getPredictionSettled(query?: PredictionSettledQuery): Promise<PredictionSettledData>;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export { PortfolioClient };
|
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/index.ts","../../src/client/index.ts"],"names":["parseDecimal","raw","n","PortfolioClient","endpoint","query","qs","buildQuery","dto","httpGet","h","buildHistoryQuery","parseHistoryType","parseTimestamp","params","addr","p","_query","str","lower","d"],"mappings":"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","file":"index.js","sourcesContent":["import { formatAmount, formatAmountInUsd } from \"@liberfi.io/utils\";\nimport type { DistributionData, SpotHolding } from \"../types\";\n\n/**\n * Parse a decimal string to a number, returning 0 for empty / invalid values.\n */\nexport function parseDecimal(raw: string | undefined | null): number {\n if (!raw) return 0;\n const n = Number(raw);\n return Number.isFinite(n) ? n : 0;\n}\n\n/**\n * Format a number as a USD currency string.\n * - >= 1M → \"$1.2M\"\n * - >= 1K → \"$4.2K\"\n * - >= 1 → \"$1,234.56\"\n * - >= 0.01 → \"$0.42\"\n * - < 0.01 and > 0 → \"<$0.01\"\n * - 0 → \"$0.00\"\n */\nexport function formatUsd(value: number): string {\n return formatAmountInUsd(value);\n}\n\n/**\n * Format a signed USD value with + / - prefix for PnL display.\n */\nexport function formatSignedUsd(value: number): string {\n const formatted = formatUsd(Math.abs(value));\n if (value > 0) return `+${formatted}`;\n if (value < 0) return `-${formatted.replace(\"-\", \"\")}`;\n return formatted;\n}\n\n/**\n * Format a percentage value.\n * Returns \"+3.24%\" or \"-1.50%\"\n */\nexport function formatPercent(value: number): string {\n const sign = value > 0 ? \"+\" : \"\";\n return `${sign}${value.toFixed(2)}%`;\n}\n\n/**\n * Split a USD value into integer and decimal parts for display.\n * e.g., 12847.63 → { integer: \"12,847\", decimal: \".63\", sign: \"$\" }\n */\nexport function splitUsd(value: number): {\n sign: string;\n integer: string;\n decimal: string;\n} {\n const abs = Math.abs(value);\n const parts = abs.toFixed(2).split(\".\");\n const integer = Number(parts[0]).toLocaleString(\"en-US\");\n const decimal = `.${parts[1]}`;\n const sign = value < 0 ? \"-$\" : \"$\";\n return { sign, integer, decimal };\n}\n\n/**\n * Truncate an address to \"xxxx…xxxx\" format.\n */\nexport function truncateAddress(address: string, start = 4, end = 4): string {\n if (address.length <= start + end + 3) return address;\n return `${address.slice(0, start)}…${address.slice(-end)}`;\n}\n\n/**\n * Format a token balance with appropriate precision.\n */\nexport function formatTokenBalance(value: number): string {\n return formatAmount(value);\n}\n\n/**\n * Build a Solana explorer URL for a transaction hash.\n * Defaults to Solscan. Can be extended for other chains in the future.\n */\nexport function getExplorerUrl(txHash: string, _chain?: string): string {\n return `https://solscan.io/tx/${txHash}`;\n}\n\n// ── Distribution Helpers ────────────────────────────────────────────────────\n\nconst DISTRIBUTION_COLORS = [\n \"#C8FF00\",\n \"#00E676\",\n \"#0066FF\",\n \"#FF6B9D\",\n \"#8B7BFF\",\n \"#FF5252\",\n \"#FFB74D\",\n \"#4DD0E1\",\n];\n\nconst OTHER_COLOR = \"#3A3A4E\";\n\n/**\n * Compute asset distribution from spot holdings for the donut chart.\n * Groups tokens with < 2% into \"Other\".\n */\nexport function computeDistribution(holdings: SpotHolding[]): DistributionData {\n const totalValue = holdings.reduce((sum, h) => sum + h.value, 0);\n if (totalValue <= 0) return { items: [] };\n\n const sorted = [...holdings].sort((a, b) => b.value - a.value);\n\n const items: DistributionData[\"items\"] = [];\n let otherValue = 0;\n let colorIdx = 0;\n\n for (const h of sorted) {\n const pct = (h.value / totalValue) * 100;\n if (pct < 2) {\n otherValue += h.value;\n } else {\n items.push({\n name: h.name,\n symbol: h.symbol,\n percent: pct,\n value: h.value,\n color: DISTRIBUTION_COLORS[colorIdx % DISTRIBUTION_COLORS.length],\n });\n colorIdx++;\n }\n }\n\n if (otherValue > 0) {\n items.push({\n name: \"Other\",\n symbol: \"OTHER\",\n percent: (otherValue / totalValue) * 100,\n value: otherValue,\n color: OTHER_COLOR,\n });\n }\n\n return { items };\n}\n\n/**\n * Format an epoch-ms timestamp for display in history tables.\n */\nexport function formatTime(epochMs: number): string {\n const d = new Date(epochMs);\n return d.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false,\n });\n}\n","import { httpGet } from \"@liberfi.io/utils\";\nimport { SpotHistoryType } from \"../types\";\nimport type {\n CurveData,\n CurveQuery,\n GetPortfolioChartReply,\n GetSpotHoldingsReply,\n GetTradeHistoryReply,\n IPortfolioClient,\n PerpsHistoryData,\n PerpsHistoryQuery,\n PerpsPositionsData,\n PortfolioOverview,\n PortfolioOverviewDTO,\n PortfolioQuery,\n PredictionBetsData,\n PredictionSettledData,\n PredictionSettledQuery,\n SpotHistoryData,\n SpotHistoryQuery,\n SpotHoldingsData,\n} from \"../types\";\nimport { parseDecimal } from \"../utils\";\n\n// ── Client ──────────────────────────────────────────────────────────────────\n\nexport class PortfolioClient implements IPortfolioClient {\n constructor(private readonly endpoint: string) {}\n\n // ── Overview ──────────────────────────────────────────────────────────\n\n async getOverview(query?: PortfolioQuery): Promise<PortfolioOverview> {\n const qs = buildQuery(query);\n const dto = await httpGet<PortfolioOverviewDTO>(\n `${this.endpoint}/portfolio/overview${qs}`,\n );\n return {\n totalValue: parseDecimal(dto.totalBalanceUsd),\n uPnl: parseDecimal(dto.unrealizedPnl),\n realizedPnl: parseDecimal(dto.realizedPnl),\n totalProfit: parseDecimal(dto.totalProfitUsd),\n winRate: parseDecimal(dto.winRate),\n };\n }\n\n // ── Spot Holdings ─────────────────────────────────────────────────────\n\n async getSpotHoldings(query?: PortfolioQuery): Promise<SpotHoldingsData> {\n const qs = buildQuery(query);\n const dto = await httpGet<GetSpotHoldingsReply>(\n `${this.endpoint}/portfolio/spot/holdings${qs}`,\n );\n return {\n holdings: (dto.holdings ?? []).map((h) => ({\n tokenAddress: h.tokenAddress,\n name: h.name,\n symbol: h.symbol,\n image: h.imageUrl ?? \"\",\n chain: h.chain ?? \"\",\n balance: parseDecimal(h.balance),\n price: parseDecimal(h.priceUsd),\n value: parseDecimal(h.valueUsd),\n change24h: parseDecimal(h.priceChange24h),\n unrealizedPnl: parseDecimal(h.unrealizedPnl),\n realizedPnl: parseDecimal(h.realizedPnl),\n walletAddress: h.walletAddress ?? \"\",\n verified: false,\n })),\n };\n }\n\n // ── Spot History ──────────────────────────────────────────────────────\n\n async getSpotHistory(query?: SpotHistoryQuery): Promise<SpotHistoryData> {\n const qs = buildHistoryQuery(query);\n const dto = await httpGet<GetTradeHistoryReply>(\n `${this.endpoint}/portfolio/spot/history${qs}`,\n );\n return {\n trades: (dto.trades ?? []).map((t) => ({\n type: parseHistoryType(t.type),\n tokenSymbol: t.tokenSymbol ?? \"\",\n tokenName: t.tokenName ?? \"\",\n tokenImageUrl: t.tokenImageUrl ?? \"\",\n tokenAddress: t.tokenAddress ?? \"\",\n tokenAmount: parseDecimal(t.tokenAmount),\n valueUsd: parseDecimal(t.valueUsd),\n priceUsd: parseDecimal(t.priceUsd),\n sideTokenSymbol: t.sideTokenSymbol ?? \"\",\n sideTokenAmount: parseDecimal(t.sideTokenAmount),\n dex: t.dex ?? \"\",\n txHash: t.txHash ?? \"\",\n chain: t.chain ?? \"\",\n walletAddress: t.walletAddress ?? \"\",\n timestamp: parseTimestamp(t.timestamp),\n })),\n nextCursor: dto.nextCursor ?? \"\",\n hasNext: dto.hasNext ?? false,\n };\n }\n\n // ── Chart Data ────────────────────────────────────────────────────────\n\n async getChartData(query: CurveQuery): Promise<CurveData> {\n const params = new URLSearchParams();\n params.set(\"period\", query.period.toString());\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n const dto = await httpGet<GetPortfolioChartReply>(\n `${this.endpoint}/portfolio/chart?${params.toString()}`,\n );\n return {\n points: (dto.dataPoints ?? []).map((p) => ({\n timestamp: parseTimestamp(p.timestamp),\n netWorth: parseDecimal(p.netWorth),\n change: parseDecimal(p.change),\n changePercent: parseDecimal(p.changePercent),\n })),\n };\n }\n\n // ── Future APIs (stubs — backend not available yet) ───────────────────\n\n async getPerpsPositions(\n _query?: PortfolioQuery,\n ): Promise<PerpsPositionsData> {\n return { positions: [], totalValue: 0 };\n }\n\n async getPerpsHistory(_query?: PerpsHistoryQuery): Promise<PerpsHistoryData> {\n return { records: [], hasMore: false };\n }\n\n async getPredictionBets(\n _query?: PortfolioQuery,\n ): Promise<PredictionBetsData> {\n return { bets: [], totalValue: 0 };\n }\n\n async getPredictionSettled(\n _query?: PredictionSettledQuery,\n ): Promise<PredictionSettledData> {\n return { records: [], hasMore: false };\n }\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction buildQuery(query?: PortfolioQuery): string {\n if (!query) return \"\";\n const params = new URLSearchParams();\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n const str = params.toString();\n return str ? `?${str}` : \"\";\n}\n\nfunction buildHistoryQuery(query?: SpotHistoryQuery): string {\n if (!query) return \"\";\n const params = new URLSearchParams();\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n if (query.cursor) {\n params.set(\"cursor\", query.cursor);\n }\n if (query.limit !== undefined) {\n params.set(\"limit\", query.limit.toString());\n }\n const str = params.toString();\n return str ? `?${str}` : \"\";\n}\n\nfunction parseHistoryType(raw: string): SpotHistoryType {\n const lower = raw?.toLowerCase();\n if (lower === \"send\" || lower === \"transfer_out\") return SpotHistoryType.SEND;\n if (lower === \"receive\" || lower === \"transfer_in\")\n return SpotHistoryType.RECEIVE;\n return SpotHistoryType.SWAP;\n}\n\nfunction parseTimestamp(raw: string): number {\n if (!raw) return 0;\n const n = Number(raw);\n // If value looks like epoch seconds (< 1e12), convert to ms\n if (Number.isFinite(n)) {\n return n < 1e12 ? n * 1000 : n;\n }\n // Try ISO date string\n const d = Date.parse(raw);\n return Number.isFinite(d) ? d : 0;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/index.ts","../../src/client/index.ts"],"names":["parseDecimal","raw","n","PortfolioClient","endpoint","query","qs","buildQuery","dto","httpGet","h","buildHistoryQuery","parseHistoryType","parseTimestamp","params","addr","p","str","lower","d"],"mappings":"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","file":"index.js","sourcesContent":["import { formatAmount, formatAmountInUsd } from \"@liberfi.io/utils\";\nimport type { DistributionData, SpotHolding } from \"../types\";\n\n/**\n * Parse a decimal string to a number, returning 0 for empty / invalid values.\n */\nexport function parseDecimal(raw: string | undefined | null): number {\n if (!raw) return 0;\n const n = Number(raw);\n return Number.isFinite(n) ? n : 0;\n}\n\n/**\n * Format a number as a USD currency string.\n * - >= 1M → \"$1.2M\"\n * - >= 1K → \"$4.2K\"\n * - >= 1 → \"$1,234.56\"\n * - >= 0.01 → \"$0.42\"\n * - < 0.01 and > 0 → \"<$0.01\"\n * - 0 → \"$0.00\"\n */\nexport function formatUsd(value: number): string {\n return formatAmountInUsd(value);\n}\n\n/**\n * Format a signed USD value with + / - prefix for PnL display.\n */\nexport function formatSignedUsd(value: number): string {\n const formatted = formatUsd(Math.abs(value));\n if (value > 0) return `+${formatted}`;\n if (value < 0) return `-${formatted.replace(\"-\", \"\")}`;\n return formatted;\n}\n\n/**\n * Format a percentage value.\n * Returns \"+3.24%\" or \"-1.50%\"\n */\nexport function formatPercent(value: number): string {\n const sign = value > 0 ? \"+\" : \"\";\n return `${sign}${value.toFixed(2)}%`;\n}\n\n/**\n * Split a USD value into integer and decimal parts for display.\n * e.g., 12847.63 → { integer: \"12,847\", decimal: \".63\", sign: \"$\" }\n */\nexport function splitUsd(value: number): {\n sign: string;\n integer: string;\n decimal: string;\n} {\n const abs = Math.abs(value);\n const parts = abs.toFixed(2).split(\".\");\n const integer = Number(parts[0]).toLocaleString(\"en-US\");\n const decimal = `.${parts[1]}`;\n const sign = value < 0 ? \"-$\" : \"$\";\n return { sign, integer, decimal };\n}\n\n/**\n * Truncate an address to \"xxxx…xxxx\" format.\n */\nexport function truncateAddress(address: string, start = 4, end = 4): string {\n if (address.length <= start + end + 3) return address;\n return `${address.slice(0, start)}…${address.slice(-end)}`;\n}\n\n/**\n * Format a token balance with appropriate precision.\n */\nexport function formatTokenBalance(value: number): string {\n return formatAmount(value);\n}\n\n/**\n * Build a Solana explorer URL for a transaction hash.\n * Defaults to Solscan. Can be extended for other chains in the future.\n */\nexport function getExplorerUrl(txHash: string, chain?: string): string {\n void chain;\n return `https://solscan.io/tx/${txHash}`;\n}\n\n// ── Distribution Helpers ────────────────────────────────────────────────────\n\nconst DISTRIBUTION_COLORS = [\n \"#C8FF00\",\n \"#00E676\",\n \"#0066FF\",\n \"#FF6B9D\",\n \"#8B7BFF\",\n \"#FF5252\",\n \"#FFB74D\",\n \"#4DD0E1\",\n];\n\nconst OTHER_COLOR = \"#3A3A4E\";\n\n/**\n * Compute asset distribution from spot holdings for the donut chart.\n * Groups tokens with < 2% into \"Other\".\n */\nexport function computeDistribution(holdings: SpotHolding[]): DistributionData {\n const totalValue = holdings.reduce((sum, h) => sum + h.value, 0);\n if (totalValue <= 0) return { items: [] };\n\n const sorted = [...holdings].sort((a, b) => b.value - a.value);\n\n const items: DistributionData[\"items\"] = [];\n let otherValue = 0;\n let colorIdx = 0;\n\n for (const h of sorted) {\n const pct = (h.value / totalValue) * 100;\n if (pct < 2) {\n otherValue += h.value;\n } else {\n items.push({\n name: h.name,\n symbol: h.symbol,\n percent: pct,\n value: h.value,\n color: DISTRIBUTION_COLORS[colorIdx % DISTRIBUTION_COLORS.length],\n });\n colorIdx++;\n }\n }\n\n if (otherValue > 0) {\n items.push({\n name: \"Other\",\n symbol: \"OTHER\",\n percent: (otherValue / totalValue) * 100,\n value: otherValue,\n color: OTHER_COLOR,\n });\n }\n\n return { items };\n}\n\n/**\n * Format an epoch-ms timestamp for display in history tables.\n */\nexport function formatTime(epochMs: number): string {\n const d = new Date(epochMs);\n return d.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false,\n });\n}\n","import { httpGet } from \"@liberfi.io/utils\";\nimport { SpotHistoryType } from \"../types\";\nimport type {\n CurveData,\n CurveQuery,\n GetPortfolioChartReply,\n GetSpotHoldingsReply,\n GetTradeHistoryReply,\n IPortfolioClient,\n PerpsHistoryData,\n PerpsHistoryQuery,\n PerpsPositionsData,\n PortfolioOverview,\n PortfolioOverviewDTO,\n PortfolioQuery,\n PredictionBetsData,\n PredictionSettledData,\n PredictionSettledQuery,\n SpotHistoryData,\n SpotHistoryQuery,\n SpotHoldingsData,\n} from \"../types\";\nimport { parseDecimal } from \"../utils\";\n\n// ── Client ──────────────────────────────────────────────────────────────────\n\nexport class PortfolioClient implements IPortfolioClient {\n constructor(private readonly endpoint: string) {}\n\n // ── Overview ──────────────────────────────────────────────────────────\n\n async getOverview(query?: PortfolioQuery): Promise<PortfolioOverview> {\n const qs = buildQuery(query);\n const dto = await httpGet<PortfolioOverviewDTO>(\n `${this.endpoint}/portfolio/overview${qs}`,\n );\n return {\n totalValue: parseDecimal(dto.totalBalanceUsd),\n uPnl: parseDecimal(dto.unrealizedPnl),\n realizedPnl: parseDecimal(dto.realizedPnl),\n totalProfit: parseDecimal(dto.totalProfitUsd),\n winRate: parseDecimal(dto.winRate),\n };\n }\n\n // ── Spot Holdings ─────────────────────────────────────────────────────\n\n async getSpotHoldings(query?: PortfolioQuery): Promise<SpotHoldingsData> {\n const qs = buildQuery(query);\n const dto = await httpGet<GetSpotHoldingsReply>(\n `${this.endpoint}/portfolio/spot/holdings${qs}`,\n );\n return {\n holdings: (dto.holdings ?? []).map((h) => ({\n tokenAddress: h.tokenAddress,\n name: h.name,\n symbol: h.symbol,\n image: h.imageUrl ?? \"\",\n chain: h.chain ?? \"\",\n balance: parseDecimal(h.balance),\n price: parseDecimal(h.priceUsd),\n value: parseDecimal(h.valueUsd),\n change24h: parseDecimal(h.priceChange24h),\n unrealizedPnl: parseDecimal(h.unrealizedPnl),\n realizedPnl: parseDecimal(h.realizedPnl),\n walletAddress: h.walletAddress ?? \"\",\n verified: false,\n })),\n };\n }\n\n // ── Spot History ──────────────────────────────────────────────────────\n\n async getSpotHistory(query?: SpotHistoryQuery): Promise<SpotHistoryData> {\n const qs = buildHistoryQuery(query);\n const dto = await httpGet<GetTradeHistoryReply>(\n `${this.endpoint}/portfolio/spot/history${qs}`,\n );\n return {\n trades: (dto.trades ?? []).map((t) => ({\n type: parseHistoryType(t.type),\n tokenSymbol: t.tokenSymbol ?? \"\",\n tokenName: t.tokenName ?? \"\",\n tokenImageUrl: t.tokenImageUrl ?? \"\",\n tokenAddress: t.tokenAddress ?? \"\",\n tokenAmount: parseDecimal(t.tokenAmount),\n valueUsd: parseDecimal(t.valueUsd),\n priceUsd: parseDecimal(t.priceUsd),\n sideTokenSymbol: t.sideTokenSymbol ?? \"\",\n sideTokenAmount: parseDecimal(t.sideTokenAmount),\n dex: t.dex ?? \"\",\n txHash: t.txHash ?? \"\",\n chain: t.chain ?? \"\",\n walletAddress: t.walletAddress ?? \"\",\n timestamp: parseTimestamp(t.timestamp),\n })),\n nextCursor: dto.nextCursor ?? \"\",\n hasNext: dto.hasNext ?? false,\n };\n }\n\n // ── Chart Data ────────────────────────────────────────────────────────\n\n async getChartData(query: CurveQuery): Promise<CurveData> {\n const params = new URLSearchParams();\n params.set(\"period\", query.period.toString());\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n const dto = await httpGet<GetPortfolioChartReply>(\n `${this.endpoint}/portfolio/chart?${params.toString()}`,\n );\n return {\n points: (dto.dataPoints ?? []).map((p) => ({\n timestamp: parseTimestamp(p.timestamp),\n netWorth: parseDecimal(p.netWorth),\n change: parseDecimal(p.change),\n changePercent: parseDecimal(p.changePercent),\n })),\n };\n }\n\n // ── Future APIs (stubs — backend not available yet) ───────────────────\n\n async getPerpsPositions(\n query?: PortfolioQuery,\n ): Promise<PerpsPositionsData> {\n void query;\n return { positions: [], totalValue: 0 };\n }\n\n async getPerpsHistory(query?: PerpsHistoryQuery): Promise<PerpsHistoryData> {\n void query;\n return { records: [], hasMore: false };\n }\n\n async getPredictionBets(\n query?: PortfolioQuery,\n ): Promise<PredictionBetsData> {\n void query;\n return { bets: [], totalValue: 0 };\n }\n\n async getPredictionSettled(\n query?: PredictionSettledQuery,\n ): Promise<PredictionSettledData> {\n void query;\n return { records: [], hasMore: false };\n }\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction buildQuery(query?: PortfolioQuery): string {\n if (!query) return \"\";\n const params = new URLSearchParams();\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n const str = params.toString();\n return str ? `?${str}` : \"\";\n}\n\nfunction buildHistoryQuery(query?: SpotHistoryQuery): string {\n if (!query) return \"\";\n const params = new URLSearchParams();\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n if (query.cursor) {\n params.set(\"cursor\", query.cursor);\n }\n if (query.limit !== undefined) {\n params.set(\"limit\", query.limit.toString());\n }\n const str = params.toString();\n return str ? `?${str}` : \"\";\n}\n\nfunction parseHistoryType(raw: string): SpotHistoryType {\n const lower = raw?.toLowerCase();\n if (lower === \"send\" || lower === \"transfer_out\") return SpotHistoryType.SEND;\n if (lower === \"receive\" || lower === \"transfer_in\")\n return SpotHistoryType.RECEIVE;\n return SpotHistoryType.SWAP;\n}\n\nfunction parseTimestamp(raw: string): number {\n if (!raw) return 0;\n const n = Number(raw);\n // If value looks like epoch seconds (< 1e12), convert to ms\n if (Number.isFinite(n)) {\n return n < 1e12 ? n * 1000 : n;\n }\n // Try ISO date string\n const d = Date.parse(raw);\n return Number.isFinite(d) ? d : 0;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/index.ts","../../src/client/index.ts"],"names":["parseDecimal","raw","n","PortfolioClient","endpoint","query","qs","buildQuery","dto","httpGet","h","buildHistoryQuery","parseHistoryType","parseTimestamp","params","addr","p","_query","str","lower","d"],"mappings":"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","file":"index.mjs","sourcesContent":["import { formatAmount, formatAmountInUsd } from \"@liberfi.io/utils\";\nimport type { DistributionData, SpotHolding } from \"../types\";\n\n/**\n * Parse a decimal string to a number, returning 0 for empty / invalid values.\n */\nexport function parseDecimal(raw: string | undefined | null): number {\n if (!raw) return 0;\n const n = Number(raw);\n return Number.isFinite(n) ? n : 0;\n}\n\n/**\n * Format a number as a USD currency string.\n * - >= 1M → \"$1.2M\"\n * - >= 1K → \"$4.2K\"\n * - >= 1 → \"$1,234.56\"\n * - >= 0.01 → \"$0.42\"\n * - < 0.01 and > 0 → \"<$0.01\"\n * - 0 → \"$0.00\"\n */\nexport function formatUsd(value: number): string {\n return formatAmountInUsd(value);\n}\n\n/**\n * Format a signed USD value with + / - prefix for PnL display.\n */\nexport function formatSignedUsd(value: number): string {\n const formatted = formatUsd(Math.abs(value));\n if (value > 0) return `+${formatted}`;\n if (value < 0) return `-${formatted.replace(\"-\", \"\")}`;\n return formatted;\n}\n\n/**\n * Format a percentage value.\n * Returns \"+3.24%\" or \"-1.50%\"\n */\nexport function formatPercent(value: number): string {\n const sign = value > 0 ? \"+\" : \"\";\n return `${sign}${value.toFixed(2)}%`;\n}\n\n/**\n * Split a USD value into integer and decimal parts for display.\n * e.g., 12847.63 → { integer: \"12,847\", decimal: \".63\", sign: \"$\" }\n */\nexport function splitUsd(value: number): {\n sign: string;\n integer: string;\n decimal: string;\n} {\n const abs = Math.abs(value);\n const parts = abs.toFixed(2).split(\".\");\n const integer = Number(parts[0]).toLocaleString(\"en-US\");\n const decimal = `.${parts[1]}`;\n const sign = value < 0 ? \"-$\" : \"$\";\n return { sign, integer, decimal };\n}\n\n/**\n * Truncate an address to \"xxxx…xxxx\" format.\n */\nexport function truncateAddress(address: string, start = 4, end = 4): string {\n if (address.length <= start + end + 3) return address;\n return `${address.slice(0, start)}…${address.slice(-end)}`;\n}\n\n/**\n * Format a token balance with appropriate precision.\n */\nexport function formatTokenBalance(value: number): string {\n return formatAmount(value);\n}\n\n/**\n * Build a Solana explorer URL for a transaction hash.\n * Defaults to Solscan. Can be extended for other chains in the future.\n */\nexport function getExplorerUrl(txHash: string, _chain?: string): string {\n return `https://solscan.io/tx/${txHash}`;\n}\n\n// ── Distribution Helpers ────────────────────────────────────────────────────\n\nconst DISTRIBUTION_COLORS = [\n \"#C8FF00\",\n \"#00E676\",\n \"#0066FF\",\n \"#FF6B9D\",\n \"#8B7BFF\",\n \"#FF5252\",\n \"#FFB74D\",\n \"#4DD0E1\",\n];\n\nconst OTHER_COLOR = \"#3A3A4E\";\n\n/**\n * Compute asset distribution from spot holdings for the donut chart.\n * Groups tokens with < 2% into \"Other\".\n */\nexport function computeDistribution(holdings: SpotHolding[]): DistributionData {\n const totalValue = holdings.reduce((sum, h) => sum + h.value, 0);\n if (totalValue <= 0) return { items: [] };\n\n const sorted = [...holdings].sort((a, b) => b.value - a.value);\n\n const items: DistributionData[\"items\"] = [];\n let otherValue = 0;\n let colorIdx = 0;\n\n for (const h of sorted) {\n const pct = (h.value / totalValue) * 100;\n if (pct < 2) {\n otherValue += h.value;\n } else {\n items.push({\n name: h.name,\n symbol: h.symbol,\n percent: pct,\n value: h.value,\n color: DISTRIBUTION_COLORS[colorIdx % DISTRIBUTION_COLORS.length],\n });\n colorIdx++;\n }\n }\n\n if (otherValue > 0) {\n items.push({\n name: \"Other\",\n symbol: \"OTHER\",\n percent: (otherValue / totalValue) * 100,\n value: otherValue,\n color: OTHER_COLOR,\n });\n }\n\n return { items };\n}\n\n/**\n * Format an epoch-ms timestamp for display in history tables.\n */\nexport function formatTime(epochMs: number): string {\n const d = new Date(epochMs);\n return d.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false,\n });\n}\n","import { httpGet } from \"@liberfi.io/utils\";\nimport { SpotHistoryType } from \"../types\";\nimport type {\n CurveData,\n CurveQuery,\n GetPortfolioChartReply,\n GetSpotHoldingsReply,\n GetTradeHistoryReply,\n IPortfolioClient,\n PerpsHistoryData,\n PerpsHistoryQuery,\n PerpsPositionsData,\n PortfolioOverview,\n PortfolioOverviewDTO,\n PortfolioQuery,\n PredictionBetsData,\n PredictionSettledData,\n PredictionSettledQuery,\n SpotHistoryData,\n SpotHistoryQuery,\n SpotHoldingsData,\n} from \"../types\";\nimport { parseDecimal } from \"../utils\";\n\n// ── Client ──────────────────────────────────────────────────────────────────\n\nexport class PortfolioClient implements IPortfolioClient {\n constructor(private readonly endpoint: string) {}\n\n // ── Overview ──────────────────────────────────────────────────────────\n\n async getOverview(query?: PortfolioQuery): Promise<PortfolioOverview> {\n const qs = buildQuery(query);\n const dto = await httpGet<PortfolioOverviewDTO>(\n `${this.endpoint}/portfolio/overview${qs}`,\n );\n return {\n totalValue: parseDecimal(dto.totalBalanceUsd),\n uPnl: parseDecimal(dto.unrealizedPnl),\n realizedPnl: parseDecimal(dto.realizedPnl),\n totalProfit: parseDecimal(dto.totalProfitUsd),\n winRate: parseDecimal(dto.winRate),\n };\n }\n\n // ── Spot Holdings ─────────────────────────────────────────────────────\n\n async getSpotHoldings(query?: PortfolioQuery): Promise<SpotHoldingsData> {\n const qs = buildQuery(query);\n const dto = await httpGet<GetSpotHoldingsReply>(\n `${this.endpoint}/portfolio/spot/holdings${qs}`,\n );\n return {\n holdings: (dto.holdings ?? []).map((h) => ({\n tokenAddress: h.tokenAddress,\n name: h.name,\n symbol: h.symbol,\n image: h.imageUrl ?? \"\",\n chain: h.chain ?? \"\",\n balance: parseDecimal(h.balance),\n price: parseDecimal(h.priceUsd),\n value: parseDecimal(h.valueUsd),\n change24h: parseDecimal(h.priceChange24h),\n unrealizedPnl: parseDecimal(h.unrealizedPnl),\n realizedPnl: parseDecimal(h.realizedPnl),\n walletAddress: h.walletAddress ?? \"\",\n verified: false,\n })),\n };\n }\n\n // ── Spot History ──────────────────────────────────────────────────────\n\n async getSpotHistory(query?: SpotHistoryQuery): Promise<SpotHistoryData> {\n const qs = buildHistoryQuery(query);\n const dto = await httpGet<GetTradeHistoryReply>(\n `${this.endpoint}/portfolio/spot/history${qs}`,\n );\n return {\n trades: (dto.trades ?? []).map((t) => ({\n type: parseHistoryType(t.type),\n tokenSymbol: t.tokenSymbol ?? \"\",\n tokenName: t.tokenName ?? \"\",\n tokenImageUrl: t.tokenImageUrl ?? \"\",\n tokenAddress: t.tokenAddress ?? \"\",\n tokenAmount: parseDecimal(t.tokenAmount),\n valueUsd: parseDecimal(t.valueUsd),\n priceUsd: parseDecimal(t.priceUsd),\n sideTokenSymbol: t.sideTokenSymbol ?? \"\",\n sideTokenAmount: parseDecimal(t.sideTokenAmount),\n dex: t.dex ?? \"\",\n txHash: t.txHash ?? \"\",\n chain: t.chain ?? \"\",\n walletAddress: t.walletAddress ?? \"\",\n timestamp: parseTimestamp(t.timestamp),\n })),\n nextCursor: dto.nextCursor ?? \"\",\n hasNext: dto.hasNext ?? false,\n };\n }\n\n // ── Chart Data ────────────────────────────────────────────────────────\n\n async getChartData(query: CurveQuery): Promise<CurveData> {\n const params = new URLSearchParams();\n params.set(\"period\", query.period.toString());\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n const dto = await httpGet<GetPortfolioChartReply>(\n `${this.endpoint}/portfolio/chart?${params.toString()}`,\n );\n return {\n points: (dto.dataPoints ?? []).map((p) => ({\n timestamp: parseTimestamp(p.timestamp),\n netWorth: parseDecimal(p.netWorth),\n change: parseDecimal(p.change),\n changePercent: parseDecimal(p.changePercent),\n })),\n };\n }\n\n // ── Future APIs (stubs — backend not available yet) ───────────────────\n\n async getPerpsPositions(\n _query?: PortfolioQuery,\n ): Promise<PerpsPositionsData> {\n return { positions: [], totalValue: 0 };\n }\n\n async getPerpsHistory(_query?: PerpsHistoryQuery): Promise<PerpsHistoryData> {\n return { records: [], hasMore: false };\n }\n\n async getPredictionBets(\n _query?: PortfolioQuery,\n ): Promise<PredictionBetsData> {\n return { bets: [], totalValue: 0 };\n }\n\n async getPredictionSettled(\n _query?: PredictionSettledQuery,\n ): Promise<PredictionSettledData> {\n return { records: [], hasMore: false };\n }\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction buildQuery(query?: PortfolioQuery): string {\n if (!query) return \"\";\n const params = new URLSearchParams();\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n const str = params.toString();\n return str ? `?${str}` : \"\";\n}\n\nfunction buildHistoryQuery(query?: SpotHistoryQuery): string {\n if (!query) return \"\";\n const params = new URLSearchParams();\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n if (query.cursor) {\n params.set(\"cursor\", query.cursor);\n }\n if (query.limit !== undefined) {\n params.set(\"limit\", query.limit.toString());\n }\n const str = params.toString();\n return str ? `?${str}` : \"\";\n}\n\nfunction parseHistoryType(raw: string): SpotHistoryType {\n const lower = raw?.toLowerCase();\n if (lower === \"send\" || lower === \"transfer_out\") return SpotHistoryType.SEND;\n if (lower === \"receive\" || lower === \"transfer_in\")\n return SpotHistoryType.RECEIVE;\n return SpotHistoryType.SWAP;\n}\n\nfunction parseTimestamp(raw: string): number {\n if (!raw) return 0;\n const n = Number(raw);\n // If value looks like epoch seconds (< 1e12), convert to ms\n if (Number.isFinite(n)) {\n return n < 1e12 ? n * 1000 : n;\n }\n // Try ISO date string\n const d = Date.parse(raw);\n return Number.isFinite(d) ? d : 0;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/utils/index.ts","../../src/client/index.ts"],"names":["parseDecimal","raw","n","PortfolioClient","endpoint","query","qs","buildQuery","dto","httpGet","h","buildHistoryQuery","parseHistoryType","parseTimestamp","params","addr","p","str","lower","d"],"mappings":"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","file":"index.mjs","sourcesContent":["import { formatAmount, formatAmountInUsd } from \"@liberfi.io/utils\";\nimport type { DistributionData, SpotHolding } from \"../types\";\n\n/**\n * Parse a decimal string to a number, returning 0 for empty / invalid values.\n */\nexport function parseDecimal(raw: string | undefined | null): number {\n if (!raw) return 0;\n const n = Number(raw);\n return Number.isFinite(n) ? n : 0;\n}\n\n/**\n * Format a number as a USD currency string.\n * - >= 1M → \"$1.2M\"\n * - >= 1K → \"$4.2K\"\n * - >= 1 → \"$1,234.56\"\n * - >= 0.01 → \"$0.42\"\n * - < 0.01 and > 0 → \"<$0.01\"\n * - 0 → \"$0.00\"\n */\nexport function formatUsd(value: number): string {\n return formatAmountInUsd(value);\n}\n\n/**\n * Format a signed USD value with + / - prefix for PnL display.\n */\nexport function formatSignedUsd(value: number): string {\n const formatted = formatUsd(Math.abs(value));\n if (value > 0) return `+${formatted}`;\n if (value < 0) return `-${formatted.replace(\"-\", \"\")}`;\n return formatted;\n}\n\n/**\n * Format a percentage value.\n * Returns \"+3.24%\" or \"-1.50%\"\n */\nexport function formatPercent(value: number): string {\n const sign = value > 0 ? \"+\" : \"\";\n return `${sign}${value.toFixed(2)}%`;\n}\n\n/**\n * Split a USD value into integer and decimal parts for display.\n * e.g., 12847.63 → { integer: \"12,847\", decimal: \".63\", sign: \"$\" }\n */\nexport function splitUsd(value: number): {\n sign: string;\n integer: string;\n decimal: string;\n} {\n const abs = Math.abs(value);\n const parts = abs.toFixed(2).split(\".\");\n const integer = Number(parts[0]).toLocaleString(\"en-US\");\n const decimal = `.${parts[1]}`;\n const sign = value < 0 ? \"-$\" : \"$\";\n return { sign, integer, decimal };\n}\n\n/**\n * Truncate an address to \"xxxx…xxxx\" format.\n */\nexport function truncateAddress(address: string, start = 4, end = 4): string {\n if (address.length <= start + end + 3) return address;\n return `${address.slice(0, start)}…${address.slice(-end)}`;\n}\n\n/**\n * Format a token balance with appropriate precision.\n */\nexport function formatTokenBalance(value: number): string {\n return formatAmount(value);\n}\n\n/**\n * Build a Solana explorer URL for a transaction hash.\n * Defaults to Solscan. Can be extended for other chains in the future.\n */\nexport function getExplorerUrl(txHash: string, chain?: string): string {\n void chain;\n return `https://solscan.io/tx/${txHash}`;\n}\n\n// ── Distribution Helpers ────────────────────────────────────────────────────\n\nconst DISTRIBUTION_COLORS = [\n \"#C8FF00\",\n \"#00E676\",\n \"#0066FF\",\n \"#FF6B9D\",\n \"#8B7BFF\",\n \"#FF5252\",\n \"#FFB74D\",\n \"#4DD0E1\",\n];\n\nconst OTHER_COLOR = \"#3A3A4E\";\n\n/**\n * Compute asset distribution from spot holdings for the donut chart.\n * Groups tokens with < 2% into \"Other\".\n */\nexport function computeDistribution(holdings: SpotHolding[]): DistributionData {\n const totalValue = holdings.reduce((sum, h) => sum + h.value, 0);\n if (totalValue <= 0) return { items: [] };\n\n const sorted = [...holdings].sort((a, b) => b.value - a.value);\n\n const items: DistributionData[\"items\"] = [];\n let otherValue = 0;\n let colorIdx = 0;\n\n for (const h of sorted) {\n const pct = (h.value / totalValue) * 100;\n if (pct < 2) {\n otherValue += h.value;\n } else {\n items.push({\n name: h.name,\n symbol: h.symbol,\n percent: pct,\n value: h.value,\n color: DISTRIBUTION_COLORS[colorIdx % DISTRIBUTION_COLORS.length],\n });\n colorIdx++;\n }\n }\n\n if (otherValue > 0) {\n items.push({\n name: \"Other\",\n symbol: \"OTHER\",\n percent: (otherValue / totalValue) * 100,\n value: otherValue,\n color: OTHER_COLOR,\n });\n }\n\n return { items };\n}\n\n/**\n * Format an epoch-ms timestamp for display in history tables.\n */\nexport function formatTime(epochMs: number): string {\n const d = new Date(epochMs);\n return d.toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n hour12: false,\n });\n}\n","import { httpGet } from \"@liberfi.io/utils\";\nimport { SpotHistoryType } from \"../types\";\nimport type {\n CurveData,\n CurveQuery,\n GetPortfolioChartReply,\n GetSpotHoldingsReply,\n GetTradeHistoryReply,\n IPortfolioClient,\n PerpsHistoryData,\n PerpsHistoryQuery,\n PerpsPositionsData,\n PortfolioOverview,\n PortfolioOverviewDTO,\n PortfolioQuery,\n PredictionBetsData,\n PredictionSettledData,\n PredictionSettledQuery,\n SpotHistoryData,\n SpotHistoryQuery,\n SpotHoldingsData,\n} from \"../types\";\nimport { parseDecimal } from \"../utils\";\n\n// ── Client ──────────────────────────────────────────────────────────────────\n\nexport class PortfolioClient implements IPortfolioClient {\n constructor(private readonly endpoint: string) {}\n\n // ── Overview ──────────────────────────────────────────────────────────\n\n async getOverview(query?: PortfolioQuery): Promise<PortfolioOverview> {\n const qs = buildQuery(query);\n const dto = await httpGet<PortfolioOverviewDTO>(\n `${this.endpoint}/portfolio/overview${qs}`,\n );\n return {\n totalValue: parseDecimal(dto.totalBalanceUsd),\n uPnl: parseDecimal(dto.unrealizedPnl),\n realizedPnl: parseDecimal(dto.realizedPnl),\n totalProfit: parseDecimal(dto.totalProfitUsd),\n winRate: parseDecimal(dto.winRate),\n };\n }\n\n // ── Spot Holdings ─────────────────────────────────────────────────────\n\n async getSpotHoldings(query?: PortfolioQuery): Promise<SpotHoldingsData> {\n const qs = buildQuery(query);\n const dto = await httpGet<GetSpotHoldingsReply>(\n `${this.endpoint}/portfolio/spot/holdings${qs}`,\n );\n return {\n holdings: (dto.holdings ?? []).map((h) => ({\n tokenAddress: h.tokenAddress,\n name: h.name,\n symbol: h.symbol,\n image: h.imageUrl ?? \"\",\n chain: h.chain ?? \"\",\n balance: parseDecimal(h.balance),\n price: parseDecimal(h.priceUsd),\n value: parseDecimal(h.valueUsd),\n change24h: parseDecimal(h.priceChange24h),\n unrealizedPnl: parseDecimal(h.unrealizedPnl),\n realizedPnl: parseDecimal(h.realizedPnl),\n walletAddress: h.walletAddress ?? \"\",\n verified: false,\n })),\n };\n }\n\n // ── Spot History ──────────────────────────────────────────────────────\n\n async getSpotHistory(query?: SpotHistoryQuery): Promise<SpotHistoryData> {\n const qs = buildHistoryQuery(query);\n const dto = await httpGet<GetTradeHistoryReply>(\n `${this.endpoint}/portfolio/spot/history${qs}`,\n );\n return {\n trades: (dto.trades ?? []).map((t) => ({\n type: parseHistoryType(t.type),\n tokenSymbol: t.tokenSymbol ?? \"\",\n tokenName: t.tokenName ?? \"\",\n tokenImageUrl: t.tokenImageUrl ?? \"\",\n tokenAddress: t.tokenAddress ?? \"\",\n tokenAmount: parseDecimal(t.tokenAmount),\n valueUsd: parseDecimal(t.valueUsd),\n priceUsd: parseDecimal(t.priceUsd),\n sideTokenSymbol: t.sideTokenSymbol ?? \"\",\n sideTokenAmount: parseDecimal(t.sideTokenAmount),\n dex: t.dex ?? \"\",\n txHash: t.txHash ?? \"\",\n chain: t.chain ?? \"\",\n walletAddress: t.walletAddress ?? \"\",\n timestamp: parseTimestamp(t.timestamp),\n })),\n nextCursor: dto.nextCursor ?? \"\",\n hasNext: dto.hasNext ?? false,\n };\n }\n\n // ── Chart Data ────────────────────────────────────────────────────────\n\n async getChartData(query: CurveQuery): Promise<CurveData> {\n const params = new URLSearchParams();\n params.set(\"period\", query.period.toString());\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n const dto = await httpGet<GetPortfolioChartReply>(\n `${this.endpoint}/portfolio/chart?${params.toString()}`,\n );\n return {\n points: (dto.dataPoints ?? []).map((p) => ({\n timestamp: parseTimestamp(p.timestamp),\n netWorth: parseDecimal(p.netWorth),\n change: parseDecimal(p.change),\n changePercent: parseDecimal(p.changePercent),\n })),\n };\n }\n\n // ── Future APIs (stubs — backend not available yet) ───────────────────\n\n async getPerpsPositions(\n query?: PortfolioQuery,\n ): Promise<PerpsPositionsData> {\n void query;\n return { positions: [], totalValue: 0 };\n }\n\n async getPerpsHistory(query?: PerpsHistoryQuery): Promise<PerpsHistoryData> {\n void query;\n return { records: [], hasMore: false };\n }\n\n async getPredictionBets(\n query?: PortfolioQuery,\n ): Promise<PredictionBetsData> {\n void query;\n return { bets: [], totalValue: 0 };\n }\n\n async getPredictionSettled(\n query?: PredictionSettledQuery,\n ): Promise<PredictionSettledData> {\n void query;\n return { records: [], hasMore: false };\n }\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\nfunction buildQuery(query?: PortfolioQuery): string {\n if (!query) return \"\";\n const params = new URLSearchParams();\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n const str = params.toString();\n return str ? `?${str}` : \"\";\n}\n\nfunction buildHistoryQuery(query?: SpotHistoryQuery): string {\n if (!query) return \"\";\n const params = new URLSearchParams();\n if (query.walletAddresses?.length) {\n for (const addr of query.walletAddresses) {\n params.append(\"walletAddresses\", addr);\n }\n }\n if (query.chain) {\n params.set(\"chain\", query.chain);\n }\n if (query.cursor) {\n params.set(\"cursor\", query.cursor);\n }\n if (query.limit !== undefined) {\n params.set(\"limit\", query.limit.toString());\n }\n const str = params.toString();\n return str ? `?${str}` : \"\";\n}\n\nfunction parseHistoryType(raw: string): SpotHistoryType {\n const lower = raw?.toLowerCase();\n if (lower === \"send\" || lower === \"transfer_out\") return SpotHistoryType.SEND;\n if (lower === \"receive\" || lower === \"transfer_in\")\n return SpotHistoryType.RECEIVE;\n return SpotHistoryType.SWAP;\n}\n\nfunction parseTimestamp(raw: string): number {\n if (!raw) return 0;\n const n = Number(raw);\n // If value looks like epoch seconds (< 1e12), convert to ms\n if (Number.isFinite(n)) {\n return n < 1e12 ? n * 1000 : n;\n }\n // Try ISO date string\n const d = Date.parse(raw);\n return Number.isFinite(d) ? d : 0;\n}\n"]}
|
|
@@ -257,4 +257,4 @@ interface IPortfolioClient {
|
|
|
257
257
|
getPredictionSettled(query?: PredictionSettledQuery): Promise<PredictionSettledData>;
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
export { AssetTab as A, type GetTradeHistoryReply as B, CurveType as C, type DistributionData as D, type
|
|
260
|
+
export { AssetTab as A, type GetTradeHistoryReply as B, CurveType as C, type DistributionData as D, type PerpsTradeRecord as E, type PortfolioOverviewDTO as F, type GetPortfolioChartReply as G, type PredictionSettledRecord as H, type IPortfolioClient as I, type SpotHistoryRecord as J, type TradeRecordDTO as K, type PortfolioQuery as P, type SpotHoldingsData as S, type TokenHoldingDTO as T, type WalletSummary as W, CurvePeriod as a, type PortfolioOverview as b, type CurveData as c, type SpotHistoryData as d, type PerpsPositionsData as e, type PerpsHistoryData as f, type PredictionBetsData as g, type PredictionSettledData as h, type SpotHolding as i, type PerpsPosition as j, type PredictionBet as k, type SpotHistoryQuery as l, type AsyncStatus as m, type PerpsHistoryQuery as n, type PredictionSettledQuery as o, type CurveQuery as p, CURVE_PERIOD_VALUE as q, PerpsPositionSide as r, PredictionBetStatus as s, PredictionResult as t, PredictionSource as u, SpotHistoryType as v, type ChartDataPointDTO as w, type CurvePoint as x, type DistributionItem as y, type GetSpotHoldingsReply as z };
|
|
@@ -257,4 +257,4 @@ interface IPortfolioClient {
|
|
|
257
257
|
getPredictionSettled(query?: PredictionSettledQuery): Promise<PredictionSettledData>;
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
-
export { AssetTab as A, type GetTradeHistoryReply as B, CurveType as C, type DistributionData as D, type
|
|
260
|
+
export { AssetTab as A, type GetTradeHistoryReply as B, CurveType as C, type DistributionData as D, type PerpsTradeRecord as E, type PortfolioOverviewDTO as F, type GetPortfolioChartReply as G, type PredictionSettledRecord as H, type IPortfolioClient as I, type SpotHistoryRecord as J, type TradeRecordDTO as K, type PortfolioQuery as P, type SpotHoldingsData as S, type TokenHoldingDTO as T, type WalletSummary as W, CurvePeriod as a, type PortfolioOverview as b, type CurveData as c, type SpotHistoryData as d, type PerpsPositionsData as e, type PerpsHistoryData as f, type PredictionBetsData as g, type PredictionSettledData as h, type SpotHolding as i, type PerpsPosition as j, type PredictionBet as k, type SpotHistoryQuery as l, type AsyncStatus as m, type PerpsHistoryQuery as n, type PredictionSettledQuery as o, type CurveQuery as p, CURVE_PERIOD_VALUE as q, PerpsPositionSide as r, PredictionBetStatus as s, PredictionResult as t, PredictionSource as u, SpotHistoryType as v, type ChartDataPointDTO as w, type CurvePoint as x, type DistributionItem as y, type GetSpotHoldingsReply as z };
|
package/dist/index.d.mts
CHANGED
|
@@ -3,11 +3,11 @@ import * as react from 'react';
|
|
|
3
3
|
import { ReactNode, PropsWithChildren } from 'react';
|
|
4
4
|
import { PredefinedToken } from '@liberfi.io/utils';
|
|
5
5
|
import { AuthStatus } from '@liberfi.io/wallet-connector';
|
|
6
|
-
import { A as AssetTab, C as CurveType, a as CurvePeriod, P as PortfolioQuery, b as PortfolioOverview, c as CurveData, D as DistributionData, S as SpotHoldingsData, d as SpotHistoryData, e as PerpsPositionsData, f as PerpsHistoryData, g as PredictionBetsData, h as PredictionSettledData, i as SpotHolding, j as PerpsPosition, k as PredictionBet, I as IPortfolioClient,
|
|
7
|
-
export { q as CURVE_PERIOD_VALUE,
|
|
6
|
+
import { A as AssetTab, C as CurveType, a as CurvePeriod, P as PortfolioQuery, b as PortfolioOverview, c as CurveData, D as DistributionData, S as SpotHoldingsData, d as SpotHistoryData, e as PerpsPositionsData, f as PerpsHistoryData, g as PredictionBetsData, h as PredictionSettledData, i as SpotHolding, j as PerpsPosition, k as PredictionBet, I as IPortfolioClient, l as SpotHistoryQuery, W as WalletSummary, m as AsyncStatus, n as PerpsHistoryQuery, o as PredictionSettledQuery, p as CurveQuery } from './index-BK-jWEQ7.mjs';
|
|
7
|
+
export { q as CURVE_PERIOD_VALUE, w as ChartDataPointDTO, x as CurvePoint, y as DistributionItem, G as GetPortfolioChartReply, z as GetSpotHoldingsReply, B as GetTradeHistoryReply, r as PerpsPositionSide, E as PerpsTradeRecord, F as PortfolioOverviewDTO, s as PredictionBetStatus, t as PredictionResult, H as PredictionSettledRecord, u as PredictionSource, J as SpotHistoryRecord, v as SpotHistoryType, T as TokenHoldingDTO, K as TradeRecordDTO } from './index-BK-jWEQ7.mjs';
|
|
8
8
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
9
9
|
import { UseQueryOptions } from '@tanstack/react-query';
|
|
10
|
-
import {
|
|
10
|
+
import { Activity, ActivitiesSortBy, Chain, WalletPortfolios, Portfolio, WalletPortfolioPnls, WalletPnlResolution, PositionState, WalletPnlSortBy, PortfolioPnl } from '@liberfi.io/types';
|
|
11
11
|
export { PositionState } from '@liberfi.io/types';
|
|
12
12
|
|
|
13
13
|
/** Action button rendered in the popover action bar. */
|
|
@@ -514,6 +514,45 @@ declare function PortfolioPnlDetailsWidget({ chain, address, limit, initialResol
|
|
|
514
514
|
|
|
515
515
|
declare const PortfolioClientContext: react.Context<IPortfolioClient | null>;
|
|
516
516
|
|
|
517
|
+
type PortfolioCapability = "holdings" | "net-worth" | "activities" | "perps" | "prediction";
|
|
518
|
+
type PortfolioAdapterResult<T> = {
|
|
519
|
+
kind: "ok";
|
|
520
|
+
data: T;
|
|
521
|
+
} | {
|
|
522
|
+
kind: "unsupported";
|
|
523
|
+
capability: PortfolioCapability;
|
|
524
|
+
} | {
|
|
525
|
+
kind: "error";
|
|
526
|
+
error: Error;
|
|
527
|
+
};
|
|
528
|
+
interface PortfolioActivitiesListener {
|
|
529
|
+
(items: SpotHistoryData["trades"]): void;
|
|
530
|
+
}
|
|
531
|
+
interface PortfolioDataAdapter {
|
|
532
|
+
getHoldings(query?: PortfolioQuery): Promise<PortfolioAdapterResult<SpotHoldingsData>>;
|
|
533
|
+
getNetWorth(query?: PortfolioQuery): Promise<PortfolioAdapterResult<PortfolioOverview>>;
|
|
534
|
+
getActivitiesPage(query?: SpotHistoryQuery): Promise<PortfolioAdapterResult<SpotHistoryData>>;
|
|
535
|
+
getPerpsPositions(query?: PortfolioQuery): Promise<PortfolioAdapterResult<{
|
|
536
|
+
positions: never[];
|
|
537
|
+
totalValue: number;
|
|
538
|
+
}>>;
|
|
539
|
+
getPredictionBets(query?: PortfolioQuery): Promise<PortfolioAdapterResult<{
|
|
540
|
+
bets: never[];
|
|
541
|
+
totalValue: number;
|
|
542
|
+
}>>;
|
|
543
|
+
subscribeActivities(listener: PortfolioActivitiesListener): {
|
|
544
|
+
unsubscribe(): void;
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
interface InMemoryPortfolioData {
|
|
548
|
+
holdings?: SpotHoldingsData;
|
|
549
|
+
netWorth?: PortfolioOverview;
|
|
550
|
+
activities?: SpotHistoryData;
|
|
551
|
+
}
|
|
552
|
+
declare function createInMemoryPortfolioDataAdapter(data?: InMemoryPortfolioData): PortfolioDataAdapter;
|
|
553
|
+
|
|
554
|
+
declare const PortfolioDataAdapterContext: react.Context<PortfolioDataAdapter | null>;
|
|
555
|
+
|
|
517
556
|
/** Refetch function for wallet summary. */
|
|
518
557
|
type RefetchWalletSummaryFn = () => Promise<void>;
|
|
519
558
|
interface PortfolioContextValue {
|
|
@@ -528,8 +567,9 @@ declare const PortfolioContext: react.Context<PortfolioContextValue>;
|
|
|
528
567
|
|
|
529
568
|
type PortfolioClientProviderProps = PropsWithChildren<{
|
|
530
569
|
client: IPortfolioClient;
|
|
570
|
+
adapter?: PortfolioDataAdapter;
|
|
531
571
|
}>;
|
|
532
|
-
declare function PortfolioClientProvider({ client, children, }: PortfolioClientProviderProps): react_jsx_runtime.JSX.Element;
|
|
572
|
+
declare function PortfolioClientProvider({ client, adapter, children, }: PortfolioClientProviderProps): react_jsx_runtime.JSX.Element;
|
|
533
573
|
|
|
534
574
|
type PortfolioProviderProps = PropsWithChildren<{
|
|
535
575
|
chain: Chain;
|
|
@@ -541,6 +581,8 @@ declare function usePortfolioContext(): PortfolioContextValue;
|
|
|
541
581
|
|
|
542
582
|
declare function usePortfolioClient(): IPortfolioClient;
|
|
543
583
|
|
|
584
|
+
declare function usePortfolioDataAdapter(): PortfolioDataAdapter;
|
|
585
|
+
|
|
544
586
|
declare function overviewQueryKey(query?: PortfolioQuery): unknown[];
|
|
545
587
|
declare function useOverviewQuery(query?: PortfolioQuery, queryOptions?: Omit<UseQueryOptions<PortfolioOverview, Error, PortfolioOverview, unknown[]>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<PortfolioOverview, Error>;
|
|
546
588
|
|
|
@@ -614,6 +656,13 @@ declare function useWalletPortfolios({ chain, address, tokenAddresses, pollMs, }
|
|
|
614
656
|
refetch: () => Promise<void>;
|
|
615
657
|
};
|
|
616
658
|
|
|
659
|
+
/**
|
|
660
|
+
* Production adapter over the existing {@link IPortfolioClient}.
|
|
661
|
+
* Perps/prediction stay `unsupported` until a real backend exists —
|
|
662
|
+
* do not translate the current empty-array stubs into success.
|
|
663
|
+
*/
|
|
664
|
+
declare function createClientPortfolioDataAdapter(client: IPortfolioClient): PortfolioDataAdapter;
|
|
665
|
+
|
|
617
666
|
/**
|
|
618
667
|
* Parse a decimal string to a number, returning 0 for empty / invalid values.
|
|
619
668
|
*/
|
|
@@ -658,7 +707,7 @@ declare function formatTokenBalance(value: number): string;
|
|
|
658
707
|
* Build a Solana explorer URL for a transaction hash.
|
|
659
708
|
* Defaults to Solscan. Can be extended for other chains in the future.
|
|
660
709
|
*/
|
|
661
|
-
declare function getExplorerUrl(txHash: string,
|
|
710
|
+
declare function getExplorerUrl(txHash: string, chain?: string): string;
|
|
662
711
|
/**
|
|
663
712
|
* Compute asset distribution from spot holdings for the donut chart.
|
|
664
713
|
* Groups tokens with < 2% into "Other".
|
|
@@ -669,4 +718,4 @@ declare function computeDistribution(holdings: SpotHolding[]): DistributionData;
|
|
|
669
718
|
*/
|
|
670
719
|
declare function formatTime(epochMs: number): string;
|
|
671
720
|
|
|
672
|
-
export { type AccountAction, AccountInfoUI, type AccountInfoUIProps, AccountInfoWidget, type AccountInfoWidgetProps, AddressRowUI, type AddressRowUIProps, AssetTab, AssetTabsUI, type AssetTabsUIProps, AsyncStatus, BalanceRowUI, type BalanceRowUIProps, BatchActionButton, type BatchActionButtonProps, ConfirmDialog, type ConfirmDialogProps, CurveCardUI, type CurveCardUIProps, CurveData, CurvePeriod, CurveQuery, CurveType, DistributionCardUI, type DistributionCardUIProps, DistributionData, HoldingsEmpty, type HoldingsEmptyProps, type HoldingsRenderProps, HoldingsSearch, type HoldingsSearchProps, HoldingsSectionWidget, type HoldingsSectionWidgetProps, HoldingsSubTabs, type HoldingsSubTabsProps, IPortfolioClient, PerpsHistoryData, PerpsHistoryQuery, PerpsPanelUI, type PerpsPanelUIProps, PerpsPosition, PerpsPositionsData, type PerpsSubTab, type PnlResolution, type PnlSortBy, PortfolioActivities, type PortfolioActivitiesProps, type PortfolioActivitiesSortBy, type PortfolioActivitiesTypeFilter, PortfolioActivitiesWidget, type PortfolioActivitiesWidgetProps, PortfolioClientContext, PortfolioClientProvider, type PortfolioClientProviderProps, PortfolioContext, type PortfolioContextValue, PortfolioNetWorthTokens, type PortfolioNetWorthTokensProps, PortfolioNetWorthTokensWidget, type PortfolioNetWorthTokensWidgetProps, PortfolioOverview, PortfolioPageSkeleton, PortfolioPageWidget, type PortfolioPageWidgetProps, PortfolioPnlDetails, type PortfolioPnlDetailsProps, PortfolioPnlDetailsWidget, type PortfolioPnlDetailsWidgetProps, PortfolioProvider, type PortfolioProviderProps, PortfolioQuery, PredictionBet, PredictionBetsData, PredictionPanelUI, type PredictionPanelUIProps, PredictionSettledData, PredictionSettledQuery, type PredictionSubTab, type RefetchWalletSummaryFn, SpotHistoryData, SpotHistoryQuery, SpotHolding, SpotHoldingsData, SpotPanelUI, type SpotPanelUIProps, type SpotSubTab, TagBadge, TagBadgeList, type TagBadgeListProps, type TagBadgeProps, type TokenPortfolio, type UseAccountInfoResult, type UseHoldingsSectionOptions, type UseHoldingsSectionResult, type UsePortfolioActivitiesScriptParams, type UsePortfolioActivitiesScriptResult, type UsePortfolioNetWorthTokensScriptParams, type UsePortfolioNetWorthTokensScriptResult, type UsePortfolioPageOptions, type UsePortfolioPageResult, type UsePortfolioPnlDetailsScriptParams, type UsePortfolioPnlDetailsScriptResult, type UseWalletPortfoliosParams, ViewingBannerUI, type ViewingBannerUIProps, type WalletOption, WalletSummary, computeDistribution, curveDataQueryKey, distributionQueryKey, formatAgeShort, formatPercent, formatSignedUsd, formatTime, formatTokenBalance, formatUsd, getExplorerUrl, overviewQueryKey, parseDecimal, perpsHistoryQueryKey, perpsPositionsQueryKey, predictionBetsQueryKey, predictionSettledQueryKey, splitUsd, spotHistoryQueryKey, spotHoldingsQueryKey, truncateAddress, truncateMiddle, useAccountInfo, useCurveDataQuery, useDistributionQuery, useHoldingsSection, useOverviewQuery, usePerpsHistoryQuery, usePerpsPositionsQuery, usePortfolioActivitiesScript, usePortfolioClient, usePortfolioContext, usePortfolioNetWorthTokensScript, usePortfolioPage, usePortfolioPnlDetailsScript, usePredictionBetsQuery, usePredictionSettledQuery, useRefetchWalletSummary, useSpotHistoryQuery, useSpotHoldingsQuery, useWalletPortfolios, useWalletSummary };
|
|
721
|
+
export { type AccountAction, AccountInfoUI, type AccountInfoUIProps, AccountInfoWidget, type AccountInfoWidgetProps, AddressRowUI, type AddressRowUIProps, AssetTab, AssetTabsUI, type AssetTabsUIProps, AsyncStatus, BalanceRowUI, type BalanceRowUIProps, BatchActionButton, type BatchActionButtonProps, ConfirmDialog, type ConfirmDialogProps, CurveCardUI, type CurveCardUIProps, CurveData, CurvePeriod, CurveQuery, CurveType, DistributionCardUI, type DistributionCardUIProps, DistributionData, HoldingsEmpty, type HoldingsEmptyProps, type HoldingsRenderProps, HoldingsSearch, type HoldingsSearchProps, HoldingsSectionWidget, type HoldingsSectionWidgetProps, HoldingsSubTabs, type HoldingsSubTabsProps, IPortfolioClient, PerpsHistoryData, PerpsHistoryQuery, PerpsPanelUI, type PerpsPanelUIProps, PerpsPosition, PerpsPositionsData, type PerpsSubTab, type PnlResolution, type PnlSortBy, PortfolioActivities, type PortfolioActivitiesProps, type PortfolioActivitiesSortBy, type PortfolioActivitiesTypeFilter, PortfolioActivitiesWidget, type PortfolioActivitiesWidgetProps, type PortfolioAdapterResult, type PortfolioCapability, PortfolioClientContext, PortfolioClientProvider, type PortfolioClientProviderProps, PortfolioContext, type PortfolioContextValue, type PortfolioDataAdapter, PortfolioDataAdapterContext, PortfolioNetWorthTokens, type PortfolioNetWorthTokensProps, PortfolioNetWorthTokensWidget, type PortfolioNetWorthTokensWidgetProps, PortfolioOverview, PortfolioPageSkeleton, PortfolioPageWidget, type PortfolioPageWidgetProps, PortfolioPnlDetails, type PortfolioPnlDetailsProps, PortfolioPnlDetailsWidget, type PortfolioPnlDetailsWidgetProps, PortfolioProvider, type PortfolioProviderProps, PortfolioQuery, PredictionBet, PredictionBetsData, PredictionPanelUI, type PredictionPanelUIProps, PredictionSettledData, PredictionSettledQuery, type PredictionSubTab, type RefetchWalletSummaryFn, SpotHistoryData, SpotHistoryQuery, SpotHolding, SpotHoldingsData, SpotPanelUI, type SpotPanelUIProps, type SpotSubTab, TagBadge, TagBadgeList, type TagBadgeListProps, type TagBadgeProps, type TokenPortfolio, type UseAccountInfoResult, type UseHoldingsSectionOptions, type UseHoldingsSectionResult, type UsePortfolioActivitiesScriptParams, type UsePortfolioActivitiesScriptResult, type UsePortfolioNetWorthTokensScriptParams, type UsePortfolioNetWorthTokensScriptResult, type UsePortfolioPageOptions, type UsePortfolioPageResult, type UsePortfolioPnlDetailsScriptParams, type UsePortfolioPnlDetailsScriptResult, type UseWalletPortfoliosParams, ViewingBannerUI, type ViewingBannerUIProps, type WalletOption, WalletSummary, computeDistribution, createClientPortfolioDataAdapter, createInMemoryPortfolioDataAdapter, curveDataQueryKey, distributionQueryKey, formatAgeShort, formatPercent, formatSignedUsd, formatTime, formatTokenBalance, formatUsd, getExplorerUrl, overviewQueryKey, parseDecimal, perpsHistoryQueryKey, perpsPositionsQueryKey, predictionBetsQueryKey, predictionSettledQueryKey, splitUsd, spotHistoryQueryKey, spotHoldingsQueryKey, truncateAddress, truncateMiddle, useAccountInfo, useCurveDataQuery, useDistributionQuery, useHoldingsSection, useOverviewQuery, usePerpsHistoryQuery, usePerpsPositionsQuery, usePortfolioActivitiesScript, usePortfolioClient, usePortfolioContext, usePortfolioDataAdapter, usePortfolioNetWorthTokensScript, usePortfolioPage, usePortfolioPnlDetailsScript, usePredictionBetsQuery, usePredictionSettledQuery, useRefetchWalletSummary, useSpotHistoryQuery, useSpotHoldingsQuery, useWalletPortfolios, useWalletSummary };
|
package/dist/index.d.ts
CHANGED
|
@@ -3,11 +3,11 @@ import * as react from 'react';
|
|
|
3
3
|
import { ReactNode, PropsWithChildren } from 'react';
|
|
4
4
|
import { PredefinedToken } from '@liberfi.io/utils';
|
|
5
5
|
import { AuthStatus } from '@liberfi.io/wallet-connector';
|
|
6
|
-
import { A as AssetTab, C as CurveType, a as CurvePeriod, P as PortfolioQuery, b as PortfolioOverview, c as CurveData, D as DistributionData, S as SpotHoldingsData, d as SpotHistoryData, e as PerpsPositionsData, f as PerpsHistoryData, g as PredictionBetsData, h as PredictionSettledData, i as SpotHolding, j as PerpsPosition, k as PredictionBet, I as IPortfolioClient,
|
|
7
|
-
export { q as CURVE_PERIOD_VALUE,
|
|
6
|
+
import { A as AssetTab, C as CurveType, a as CurvePeriod, P as PortfolioQuery, b as PortfolioOverview, c as CurveData, D as DistributionData, S as SpotHoldingsData, d as SpotHistoryData, e as PerpsPositionsData, f as PerpsHistoryData, g as PredictionBetsData, h as PredictionSettledData, i as SpotHolding, j as PerpsPosition, k as PredictionBet, I as IPortfolioClient, l as SpotHistoryQuery, W as WalletSummary, m as AsyncStatus, n as PerpsHistoryQuery, o as PredictionSettledQuery, p as CurveQuery } from './index-BK-jWEQ7.js';
|
|
7
|
+
export { q as CURVE_PERIOD_VALUE, w as ChartDataPointDTO, x as CurvePoint, y as DistributionItem, G as GetPortfolioChartReply, z as GetSpotHoldingsReply, B as GetTradeHistoryReply, r as PerpsPositionSide, E as PerpsTradeRecord, F as PortfolioOverviewDTO, s as PredictionBetStatus, t as PredictionResult, H as PredictionSettledRecord, u as PredictionSource, J as SpotHistoryRecord, v as SpotHistoryType, T as TokenHoldingDTO, K as TradeRecordDTO } from './index-BK-jWEQ7.js';
|
|
8
8
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
9
9
|
import { UseQueryOptions } from '@tanstack/react-query';
|
|
10
|
-
import {
|
|
10
|
+
import { Activity, ActivitiesSortBy, Chain, WalletPortfolios, Portfolio, WalletPortfolioPnls, WalletPnlResolution, PositionState, WalletPnlSortBy, PortfolioPnl } from '@liberfi.io/types';
|
|
11
11
|
export { PositionState } from '@liberfi.io/types';
|
|
12
12
|
|
|
13
13
|
/** Action button rendered in the popover action bar. */
|
|
@@ -514,6 +514,45 @@ declare function PortfolioPnlDetailsWidget({ chain, address, limit, initialResol
|
|
|
514
514
|
|
|
515
515
|
declare const PortfolioClientContext: react.Context<IPortfolioClient | null>;
|
|
516
516
|
|
|
517
|
+
type PortfolioCapability = "holdings" | "net-worth" | "activities" | "perps" | "prediction";
|
|
518
|
+
type PortfolioAdapterResult<T> = {
|
|
519
|
+
kind: "ok";
|
|
520
|
+
data: T;
|
|
521
|
+
} | {
|
|
522
|
+
kind: "unsupported";
|
|
523
|
+
capability: PortfolioCapability;
|
|
524
|
+
} | {
|
|
525
|
+
kind: "error";
|
|
526
|
+
error: Error;
|
|
527
|
+
};
|
|
528
|
+
interface PortfolioActivitiesListener {
|
|
529
|
+
(items: SpotHistoryData["trades"]): void;
|
|
530
|
+
}
|
|
531
|
+
interface PortfolioDataAdapter {
|
|
532
|
+
getHoldings(query?: PortfolioQuery): Promise<PortfolioAdapterResult<SpotHoldingsData>>;
|
|
533
|
+
getNetWorth(query?: PortfolioQuery): Promise<PortfolioAdapterResult<PortfolioOverview>>;
|
|
534
|
+
getActivitiesPage(query?: SpotHistoryQuery): Promise<PortfolioAdapterResult<SpotHistoryData>>;
|
|
535
|
+
getPerpsPositions(query?: PortfolioQuery): Promise<PortfolioAdapterResult<{
|
|
536
|
+
positions: never[];
|
|
537
|
+
totalValue: number;
|
|
538
|
+
}>>;
|
|
539
|
+
getPredictionBets(query?: PortfolioQuery): Promise<PortfolioAdapterResult<{
|
|
540
|
+
bets: never[];
|
|
541
|
+
totalValue: number;
|
|
542
|
+
}>>;
|
|
543
|
+
subscribeActivities(listener: PortfolioActivitiesListener): {
|
|
544
|
+
unsubscribe(): void;
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
interface InMemoryPortfolioData {
|
|
548
|
+
holdings?: SpotHoldingsData;
|
|
549
|
+
netWorth?: PortfolioOverview;
|
|
550
|
+
activities?: SpotHistoryData;
|
|
551
|
+
}
|
|
552
|
+
declare function createInMemoryPortfolioDataAdapter(data?: InMemoryPortfolioData): PortfolioDataAdapter;
|
|
553
|
+
|
|
554
|
+
declare const PortfolioDataAdapterContext: react.Context<PortfolioDataAdapter | null>;
|
|
555
|
+
|
|
517
556
|
/** Refetch function for wallet summary. */
|
|
518
557
|
type RefetchWalletSummaryFn = () => Promise<void>;
|
|
519
558
|
interface PortfolioContextValue {
|
|
@@ -528,8 +567,9 @@ declare const PortfolioContext: react.Context<PortfolioContextValue>;
|
|
|
528
567
|
|
|
529
568
|
type PortfolioClientProviderProps = PropsWithChildren<{
|
|
530
569
|
client: IPortfolioClient;
|
|
570
|
+
adapter?: PortfolioDataAdapter;
|
|
531
571
|
}>;
|
|
532
|
-
declare function PortfolioClientProvider({ client, children, }: PortfolioClientProviderProps): react_jsx_runtime.JSX.Element;
|
|
572
|
+
declare function PortfolioClientProvider({ client, adapter, children, }: PortfolioClientProviderProps): react_jsx_runtime.JSX.Element;
|
|
533
573
|
|
|
534
574
|
type PortfolioProviderProps = PropsWithChildren<{
|
|
535
575
|
chain: Chain;
|
|
@@ -541,6 +581,8 @@ declare function usePortfolioContext(): PortfolioContextValue;
|
|
|
541
581
|
|
|
542
582
|
declare function usePortfolioClient(): IPortfolioClient;
|
|
543
583
|
|
|
584
|
+
declare function usePortfolioDataAdapter(): PortfolioDataAdapter;
|
|
585
|
+
|
|
544
586
|
declare function overviewQueryKey(query?: PortfolioQuery): unknown[];
|
|
545
587
|
declare function useOverviewQuery(query?: PortfolioQuery, queryOptions?: Omit<UseQueryOptions<PortfolioOverview, Error, PortfolioOverview, unknown[]>, "queryKey" | "queryFn">): _tanstack_react_query.UseQueryResult<PortfolioOverview, Error>;
|
|
546
588
|
|
|
@@ -614,6 +656,13 @@ declare function useWalletPortfolios({ chain, address, tokenAddresses, pollMs, }
|
|
|
614
656
|
refetch: () => Promise<void>;
|
|
615
657
|
};
|
|
616
658
|
|
|
659
|
+
/**
|
|
660
|
+
* Production adapter over the existing {@link IPortfolioClient}.
|
|
661
|
+
* Perps/prediction stay `unsupported` until a real backend exists —
|
|
662
|
+
* do not translate the current empty-array stubs into success.
|
|
663
|
+
*/
|
|
664
|
+
declare function createClientPortfolioDataAdapter(client: IPortfolioClient): PortfolioDataAdapter;
|
|
665
|
+
|
|
617
666
|
/**
|
|
618
667
|
* Parse a decimal string to a number, returning 0 for empty / invalid values.
|
|
619
668
|
*/
|
|
@@ -658,7 +707,7 @@ declare function formatTokenBalance(value: number): string;
|
|
|
658
707
|
* Build a Solana explorer URL for a transaction hash.
|
|
659
708
|
* Defaults to Solscan. Can be extended for other chains in the future.
|
|
660
709
|
*/
|
|
661
|
-
declare function getExplorerUrl(txHash: string,
|
|
710
|
+
declare function getExplorerUrl(txHash: string, chain?: string): string;
|
|
662
711
|
/**
|
|
663
712
|
* Compute asset distribution from spot holdings for the donut chart.
|
|
664
713
|
* Groups tokens with < 2% into "Other".
|
|
@@ -669,4 +718,4 @@ declare function computeDistribution(holdings: SpotHolding[]): DistributionData;
|
|
|
669
718
|
*/
|
|
670
719
|
declare function formatTime(epochMs: number): string;
|
|
671
720
|
|
|
672
|
-
export { type AccountAction, AccountInfoUI, type AccountInfoUIProps, AccountInfoWidget, type AccountInfoWidgetProps, AddressRowUI, type AddressRowUIProps, AssetTab, AssetTabsUI, type AssetTabsUIProps, AsyncStatus, BalanceRowUI, type BalanceRowUIProps, BatchActionButton, type BatchActionButtonProps, ConfirmDialog, type ConfirmDialogProps, CurveCardUI, type CurveCardUIProps, CurveData, CurvePeriod, CurveQuery, CurveType, DistributionCardUI, type DistributionCardUIProps, DistributionData, HoldingsEmpty, type HoldingsEmptyProps, type HoldingsRenderProps, HoldingsSearch, type HoldingsSearchProps, HoldingsSectionWidget, type HoldingsSectionWidgetProps, HoldingsSubTabs, type HoldingsSubTabsProps, IPortfolioClient, PerpsHistoryData, PerpsHistoryQuery, PerpsPanelUI, type PerpsPanelUIProps, PerpsPosition, PerpsPositionsData, type PerpsSubTab, type PnlResolution, type PnlSortBy, PortfolioActivities, type PortfolioActivitiesProps, type PortfolioActivitiesSortBy, type PortfolioActivitiesTypeFilter, PortfolioActivitiesWidget, type PortfolioActivitiesWidgetProps, PortfolioClientContext, PortfolioClientProvider, type PortfolioClientProviderProps, PortfolioContext, type PortfolioContextValue, PortfolioNetWorthTokens, type PortfolioNetWorthTokensProps, PortfolioNetWorthTokensWidget, type PortfolioNetWorthTokensWidgetProps, PortfolioOverview, PortfolioPageSkeleton, PortfolioPageWidget, type PortfolioPageWidgetProps, PortfolioPnlDetails, type PortfolioPnlDetailsProps, PortfolioPnlDetailsWidget, type PortfolioPnlDetailsWidgetProps, PortfolioProvider, type PortfolioProviderProps, PortfolioQuery, PredictionBet, PredictionBetsData, PredictionPanelUI, type PredictionPanelUIProps, PredictionSettledData, PredictionSettledQuery, type PredictionSubTab, type RefetchWalletSummaryFn, SpotHistoryData, SpotHistoryQuery, SpotHolding, SpotHoldingsData, SpotPanelUI, type SpotPanelUIProps, type SpotSubTab, TagBadge, TagBadgeList, type TagBadgeListProps, type TagBadgeProps, type TokenPortfolio, type UseAccountInfoResult, type UseHoldingsSectionOptions, type UseHoldingsSectionResult, type UsePortfolioActivitiesScriptParams, type UsePortfolioActivitiesScriptResult, type UsePortfolioNetWorthTokensScriptParams, type UsePortfolioNetWorthTokensScriptResult, type UsePortfolioPageOptions, type UsePortfolioPageResult, type UsePortfolioPnlDetailsScriptParams, type UsePortfolioPnlDetailsScriptResult, type UseWalletPortfoliosParams, ViewingBannerUI, type ViewingBannerUIProps, type WalletOption, WalletSummary, computeDistribution, curveDataQueryKey, distributionQueryKey, formatAgeShort, formatPercent, formatSignedUsd, formatTime, formatTokenBalance, formatUsd, getExplorerUrl, overviewQueryKey, parseDecimal, perpsHistoryQueryKey, perpsPositionsQueryKey, predictionBetsQueryKey, predictionSettledQueryKey, splitUsd, spotHistoryQueryKey, spotHoldingsQueryKey, truncateAddress, truncateMiddle, useAccountInfo, useCurveDataQuery, useDistributionQuery, useHoldingsSection, useOverviewQuery, usePerpsHistoryQuery, usePerpsPositionsQuery, usePortfolioActivitiesScript, usePortfolioClient, usePortfolioContext, usePortfolioNetWorthTokensScript, usePortfolioPage, usePortfolioPnlDetailsScript, usePredictionBetsQuery, usePredictionSettledQuery, useRefetchWalletSummary, useSpotHistoryQuery, useSpotHoldingsQuery, useWalletPortfolios, useWalletSummary };
|
|
721
|
+
export { type AccountAction, AccountInfoUI, type AccountInfoUIProps, AccountInfoWidget, type AccountInfoWidgetProps, AddressRowUI, type AddressRowUIProps, AssetTab, AssetTabsUI, type AssetTabsUIProps, AsyncStatus, BalanceRowUI, type BalanceRowUIProps, BatchActionButton, type BatchActionButtonProps, ConfirmDialog, type ConfirmDialogProps, CurveCardUI, type CurveCardUIProps, CurveData, CurvePeriod, CurveQuery, CurveType, DistributionCardUI, type DistributionCardUIProps, DistributionData, HoldingsEmpty, type HoldingsEmptyProps, type HoldingsRenderProps, HoldingsSearch, type HoldingsSearchProps, HoldingsSectionWidget, type HoldingsSectionWidgetProps, HoldingsSubTabs, type HoldingsSubTabsProps, IPortfolioClient, PerpsHistoryData, PerpsHistoryQuery, PerpsPanelUI, type PerpsPanelUIProps, PerpsPosition, PerpsPositionsData, type PerpsSubTab, type PnlResolution, type PnlSortBy, PortfolioActivities, type PortfolioActivitiesProps, type PortfolioActivitiesSortBy, type PortfolioActivitiesTypeFilter, PortfolioActivitiesWidget, type PortfolioActivitiesWidgetProps, type PortfolioAdapterResult, type PortfolioCapability, PortfolioClientContext, PortfolioClientProvider, type PortfolioClientProviderProps, PortfolioContext, type PortfolioContextValue, type PortfolioDataAdapter, PortfolioDataAdapterContext, PortfolioNetWorthTokens, type PortfolioNetWorthTokensProps, PortfolioNetWorthTokensWidget, type PortfolioNetWorthTokensWidgetProps, PortfolioOverview, PortfolioPageSkeleton, PortfolioPageWidget, type PortfolioPageWidgetProps, PortfolioPnlDetails, type PortfolioPnlDetailsProps, PortfolioPnlDetailsWidget, type PortfolioPnlDetailsWidgetProps, PortfolioProvider, type PortfolioProviderProps, PortfolioQuery, PredictionBet, PredictionBetsData, PredictionPanelUI, type PredictionPanelUIProps, PredictionSettledData, PredictionSettledQuery, type PredictionSubTab, type RefetchWalletSummaryFn, SpotHistoryData, SpotHistoryQuery, SpotHolding, SpotHoldingsData, SpotPanelUI, type SpotPanelUIProps, type SpotSubTab, TagBadge, TagBadgeList, type TagBadgeListProps, type TagBadgeProps, type TokenPortfolio, type UseAccountInfoResult, type UseHoldingsSectionOptions, type UseHoldingsSectionResult, type UsePortfolioActivitiesScriptParams, type UsePortfolioActivitiesScriptResult, type UsePortfolioNetWorthTokensScriptParams, type UsePortfolioNetWorthTokensScriptResult, type UsePortfolioPageOptions, type UsePortfolioPageResult, type UsePortfolioPnlDetailsScriptParams, type UsePortfolioPnlDetailsScriptResult, type UseWalletPortfoliosParams, ViewingBannerUI, type ViewingBannerUIProps, type WalletOption, WalletSummary, computeDistribution, createClientPortfolioDataAdapter, createInMemoryPortfolioDataAdapter, curveDataQueryKey, distributionQueryKey, formatAgeShort, formatPercent, formatSignedUsd, formatTime, formatTokenBalance, formatUsd, getExplorerUrl, overviewQueryKey, parseDecimal, perpsHistoryQueryKey, perpsPositionsQueryKey, predictionBetsQueryKey, predictionSettledQueryKey, splitUsd, spotHistoryQueryKey, spotHoldingsQueryKey, truncateAddress, truncateMiddle, useAccountInfo, useCurveDataQuery, useDistributionQuery, useHoldingsSection, useOverviewQuery, usePerpsHistoryQuery, usePerpsPositionsQuery, usePortfolioActivitiesScript, usePortfolioClient, usePortfolioContext, usePortfolioDataAdapter, usePortfolioNetWorthTokensScript, usePortfolioPage, usePortfolioPnlDetailsScript, usePredictionBetsQuery, usePredictionSettledQuery, useRefetchWalletSummary, useSpotHistoryQuery, useSpotHoldingsQuery, useWalletPortfolios, useWalletSummary };
|