@liberfi.io/ui-portfolio 0.1.8 → 0.1.10
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.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +1 -1
- package/dist/client/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
package/dist/client/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var utils=require('@liberfi.io/utils');function i(r){if(!r)return 0;let e=Number(r);return Number.isFinite(e)?e:0}var a=class{constructor(e){this.endpoint=e;}async getOverview(e){let n=l(e),o=await utils.
|
|
1
|
+
'use strict';var utils=require('@liberfi.io/utils');function i(r){if(!r)return 0;let e=Number(r);return Number.isFinite(e)?e:0}var a=class{constructor(e){this.endpoint=e;}async getOverview(e){let n=l(e),o=await utils.httpGet(`${this.endpoint}/portfolio/overview${n}`);return {totalValue:i(o.totalBalanceUsd),uPnl:i(o.unrealizedPnl),realizedPnl:i(o.realizedPnl),totalProfit:i(o.totalProfitUsd),winRate:i(o.winRate)}}async getSpotHoldings(e){let n=l(e);return {holdings:((await utils.httpGet(`${this.endpoint}/portfolio/spot/holdings${n}`)).holdings??[]).map(t=>({tokenAddress:t.tokenAddress,name:t.name,symbol:t.symbol,image:t.imageUrl??"",chain:t.chain??"",balance:i(t.balance),price:i(t.priceUsd),value:i(t.valueUsd),change24h:i(t.priceChange24h),unrealizedPnl:i(t.unrealizedPnl),realizedPnl:i(t.realizedPnl),walletAddress:t.walletAddress??"",verified:false}))}}async getSpotHistory(e){let n=u(e),o=await utils.httpGet(`${this.endpoint}/portfolio/spot/history${n}`);return {trades:(o.trades??[]).map(t=>({type:c(t.type),tokenSymbol:t.tokenSymbol??"",tokenName:t.tokenName??"",tokenImageUrl:t.tokenImageUrl??"",tokenAddress:t.tokenAddress??"",tokenAmount:i(t.tokenAmount),valueUsd:i(t.valueUsd),priceUsd:i(t.priceUsd),sideTokenSymbol:t.sideTokenSymbol??"",sideTokenAmount:i(t.sideTokenAmount),dex:t.dex??"",txHash:t.txHash??"",chain:t.chain??"",walletAddress:t.walletAddress??"",timestamp:d(t.timestamp)})),nextCursor:o.nextCursor??"",hasNext:o.hasNext??false}}async getChartData(e){let n=new URLSearchParams;if(n.set("period",e.period.toString()),e.walletAddresses?.length)for(let t of e.walletAddresses)n.append("walletAddresses",t);return e.chain&&n.set("chain",e.chain),{points:((await utils.httpGet(`${this.endpoint}/portfolio/chart?${n.toString()}`)).dataPoints??[]).map(t=>({timestamp:d(t.timestamp),netWorth:i(t.netWorth),change:i(t.change),changePercent:i(t.changePercent)}))}}async getPerpsPositions(e){return {positions:[],totalValue:0}}async getPerpsHistory(e){return {records:[],hasMore:false}}async getPredictionBets(e){return {bets:[],totalValue:0}}async getPredictionSettled(e){return {records:[],hasMore:false}}};function l(r){if(!r)return "";let e=new URLSearchParams;if(r.walletAddresses?.length)for(let o of r.walletAddresses)e.append("walletAddresses",o);r.chain&&e.set("chain",r.chain);let n=e.toString();return n?`?${n}`:""}function u(r){if(!r)return "";let e=new URLSearchParams;if(r.walletAddresses?.length)for(let o of r.walletAddresses)e.append("walletAddresses",o);r.chain&&e.set("chain",r.chain),r.cursor&&e.set("cursor",r.cursor),r.limit!==void 0&&e.set("limit",r.limit.toString());let n=e.toString();return n?`?${n}`:""}function c(r){let e=r?.toLowerCase();return e==="send"||e==="transfer_out"?"send":e==="receive"||e==="transfer_in"?"receive":"swap"}function d(r){if(!r)return 0;let e=Number(r);if(Number.isFinite(e))return e<1e12?e*1e3:e;let n=Date.parse(r);return Number.isFinite(n)?n:0}exports.PortfolioClient=a;//# sourceMappingURL=index.js.map
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
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","get","h","buildHistoryQuery","parseHistoryType","parseTimestamp","params","addr","p","_query","str","lower","d"],"mappings":"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","file":"index.js","sourcesContent":["import 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 const abs = Math.abs(value);\n const sign = value < 0 ? \"-\" : \"\";\n\n if (abs >= 1_000_000) {\n return `${sign}$${(abs / 1_000_000).toFixed(1)}M`;\n }\n if (abs >= 10_000) {\n return `${sign}$${(abs / 1_000).toFixed(1)}K`;\n }\n if (abs >= 1) {\n return `${sign}$${abs.toLocaleString(\"en-US\", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;\n }\n if (abs >= 0.01) {\n return `${sign}$${abs.toFixed(2)}`;\n }\n if (abs > 0) {\n return `${sign}<$0.01`;\n }\n return \"$0.00\";\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 if (value === 0) return \"0\";\n if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(2)}M`;\n if (value >= 1_000)\n return value.toLocaleString(\"en-US\", { maximumFractionDigits: 2 });\n if (value >= 1) return value.toFixed(2);\n if (value >= 0.0001) return value.toFixed(4);\n return \"<0.0001\";\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 { get } 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 get<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 get<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 get<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 get<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","_query","str","lower","d"],"mappings":"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","file":"index.js","sourcesContent":["import 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 const abs = Math.abs(value);\n const sign = value < 0 ? \"-\" : \"\";\n\n if (abs >= 1_000_000) {\n return `${sign}$${(abs / 1_000_000).toFixed(1)}M`;\n }\n if (abs >= 10_000) {\n return `${sign}$${(abs / 1_000).toFixed(1)}K`;\n }\n if (abs >= 1) {\n return `${sign}$${abs.toLocaleString(\"en-US\", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;\n }\n if (abs >= 0.01) {\n return `${sign}$${abs.toFixed(2)}`;\n }\n if (abs > 0) {\n return `${sign}<$0.01`;\n }\n return \"$0.00\";\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 if (value === 0) return \"0\";\n if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(2)}M`;\n if (value >= 1_000)\n return value.toLocaleString(\"en-US\", { maximumFractionDigits: 2 });\n if (value >= 1) return value.toFixed(2);\n if (value >= 0.0001) return value.toFixed(4);\n return \"<0.0001\";\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"]}
|
package/dist/client/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {httpGet}from'@liberfi.io/utils';function i(r){if(!r)return 0;let e=Number(r);return Number.isFinite(e)?e:0}var a=class{constructor(e){this.endpoint=e;}async getOverview(e){let n=l(e),o=await httpGet(`${this.endpoint}/portfolio/overview${n}`);return {totalValue:i(o.totalBalanceUsd),uPnl:i(o.unrealizedPnl),realizedPnl:i(o.realizedPnl),totalProfit:i(o.totalProfitUsd),winRate:i(o.winRate)}}async getSpotHoldings(e){let n=l(e);return {holdings:((await httpGet(`${this.endpoint}/portfolio/spot/holdings${n}`)).holdings??[]).map(t=>({tokenAddress:t.tokenAddress,name:t.name,symbol:t.symbol,image:t.imageUrl??"",chain:t.chain??"",balance:i(t.balance),price:i(t.priceUsd),value:i(t.valueUsd),change24h:i(t.priceChange24h),unrealizedPnl:i(t.unrealizedPnl),realizedPnl:i(t.realizedPnl),walletAddress:t.walletAddress??"",verified:false}))}}async getSpotHistory(e){let n=u(e),o=await httpGet(`${this.endpoint}/portfolio/spot/history${n}`);return {trades:(o.trades??[]).map(t=>({type:c(t.type),tokenSymbol:t.tokenSymbol??"",tokenName:t.tokenName??"",tokenImageUrl:t.tokenImageUrl??"",tokenAddress:t.tokenAddress??"",tokenAmount:i(t.tokenAmount),valueUsd:i(t.valueUsd),priceUsd:i(t.priceUsd),sideTokenSymbol:t.sideTokenSymbol??"",sideTokenAmount:i(t.sideTokenAmount),dex:t.dex??"",txHash:t.txHash??"",chain:t.chain??"",walletAddress:t.walletAddress??"",timestamp:d(t.timestamp)})),nextCursor:o.nextCursor??"",hasNext:o.hasNext??false}}async getChartData(e){let n=new URLSearchParams;if(n.set("period",e.period.toString()),e.walletAddresses?.length)for(let t of e.walletAddresses)n.append("walletAddresses",t);return e.chain&&n.set("chain",e.chain),{points:((await httpGet(`${this.endpoint}/portfolio/chart?${n.toString()}`)).dataPoints??[]).map(t=>({timestamp:d(t.timestamp),netWorth:i(t.netWorth),change:i(t.change),changePercent:i(t.changePercent)}))}}async getPerpsPositions(e){return {positions:[],totalValue:0}}async getPerpsHistory(e){return {records:[],hasMore:false}}async getPredictionBets(e){return {bets:[],totalValue:0}}async getPredictionSettled(e){return {records:[],hasMore:false}}};function l(r){if(!r)return "";let e=new URLSearchParams;if(r.walletAddresses?.length)for(let o of r.walletAddresses)e.append("walletAddresses",o);r.chain&&e.set("chain",r.chain);let n=e.toString();return n?`?${n}`:""}function u(r){if(!r)return "";let e=new URLSearchParams;if(r.walletAddresses?.length)for(let o of r.walletAddresses)e.append("walletAddresses",o);r.chain&&e.set("chain",r.chain),r.cursor&&e.set("cursor",r.cursor),r.limit!==void 0&&e.set("limit",r.limit.toString());let n=e.toString();return n?`?${n}`:""}function c(r){let e=r?.toLowerCase();return e==="send"||e==="transfer_out"?"send":e==="receive"||e==="transfer_in"?"receive":"swap"}function d(r){if(!r)return 0;let e=Number(r);if(Number.isFinite(e))return e<1e12?e*1e3:e;let n=Date.parse(r);return Number.isFinite(n)?n:0}export{a as PortfolioClient};//# sourceMappingURL=index.mjs.map
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/index.ts","../../src/client/index.ts"],"names":["parseDecimal","raw","n","PortfolioClient","endpoint","query","qs","buildQuery","dto","get","h","buildHistoryQuery","parseHistoryType","parseTimestamp","params","addr","p","_query","str","lower","d"],"mappings":"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","file":"index.mjs","sourcesContent":["import 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 const abs = Math.abs(value);\n const sign = value < 0 ? \"-\" : \"\";\n\n if (abs >= 1_000_000) {\n return `${sign}$${(abs / 1_000_000).toFixed(1)}M`;\n }\n if (abs >= 10_000) {\n return `${sign}$${(abs / 1_000).toFixed(1)}K`;\n }\n if (abs >= 1) {\n return `${sign}$${abs.toLocaleString(\"en-US\", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;\n }\n if (abs >= 0.01) {\n return `${sign}$${abs.toFixed(2)}`;\n }\n if (abs > 0) {\n return `${sign}<$0.01`;\n }\n return \"$0.00\";\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 if (value === 0) return \"0\";\n if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(2)}M`;\n if (value >= 1_000)\n return value.toLocaleString(\"en-US\", { maximumFractionDigits: 2 });\n if (value >= 1) return value.toFixed(2);\n if (value >= 0.0001) return value.toFixed(4);\n return \"<0.0001\";\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 { get } 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 get<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 get<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 get<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 get<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","_query","str","lower","d"],"mappings":"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","file":"index.mjs","sourcesContent":["import 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 const abs = Math.abs(value);\n const sign = value < 0 ? \"-\" : \"\";\n\n if (abs >= 1_000_000) {\n return `${sign}$${(abs / 1_000_000).toFixed(1)}M`;\n }\n if (abs >= 10_000) {\n return `${sign}$${(abs / 1_000).toFixed(1)}K`;\n }\n if (abs >= 1) {\n return `${sign}$${abs.toLocaleString(\"en-US\", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;\n }\n if (abs >= 0.01) {\n return `${sign}$${abs.toFixed(2)}`;\n }\n if (abs > 0) {\n return `${sign}<$0.01`;\n }\n return \"$0.00\";\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 if (value === 0) return \"0\";\n if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(2)}M`;\n if (value >= 1_000)\n return value.toLocaleString(\"en-US\", { maximumFractionDigits: 2 });\n if (value >= 1) return value.toFixed(2);\n if (value >= 0.0001) return value.toFixed(4);\n return \"<0.0001\";\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"]}
|
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var react=require('react'),ui=require('@liberfi.io/ui'),jsxRuntime=require('react/jsx-runtime'),recharts=require('recharts'),reactQuery=require('@tanstack/react-query'),react$1=require('@liberfi.io/react');typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-portfolio"]="0.1.8");var Bt="0.1.8";function Sr(e){if(!e)return 0;let t=Number(e);return Number.isFinite(t)?t:0}function S(e){let t=Math.abs(e),o=e<0?"-":"";return t>=1e6?`${o}$${(t/1e6).toFixed(1)}M`:t>=1e4?`${o}$${(t/1e3).toFixed(1)}K`:t>=1?`${o}$${t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}`:t>=.01?`${o}$${t.toFixed(2)}`:t>0?`${o}<$0.01`:"$0.00"}function te(e){let t=S(Math.abs(e));return e>0?`+${t}`:e<0?`-${t.replace("-","")}`:t}function ot(e){return `${e>0?"+":""}${e.toFixed(2)}%`}function rt(e){let o=Math.abs(e).toFixed(2).split("."),r=Number(o[0]).toLocaleString("en-US"),i=`.${o[1]}`;return {sign:e<0?"-$":"$",integer:r,decimal:i}}function Z(e,t=4,o=4){return e.length<=t+o+3?e:`${e.slice(0,t)}\u2026${e.slice(-o)}`}function Ce(e){return e===0?"0":e>=1e6?`${(e/1e6).toFixed(2)}M`:e>=1e3?e.toLocaleString("en-US",{maximumFractionDigits:2}):e>=1?e.toFixed(2):e>=1e-4?e.toFixed(4):"<0.0001"}function nt(e,t){return `https://solscan.io/tx/${e}`}var tt=["#C8FF00","#00E676","#0066FF","#FF6B9D","#8B7BFF","#FF5252","#FFB74D","#4DD0E1"],Lt="#3A3A4E";function st(e){let t=e.reduce((s,n)=>s+n.value,0);if(t<=0)return {items:[]};let o=[...e].sort((s,n)=>n.value-s.value),r=[],i=0,p=0;for(let s of o){let n=s.value/t*100;n<2?i+=s.value:(r.push({name:s.name,symbol:s.symbol,percent:n,value:s.value,color:tt[p%tt.length]}),p++);}return i>0&&r.push({name:"Other",symbol:"OTHER",percent:i/t*100,value:i,color:Lt}),{items:r}}function it(e){return new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:false})}function Se({walletId:e,wallets:t,isViewing:o,viewingAddress:r,onSelectWallet:i,onCopyAddress:p,onSearch:s}){let[n,a]=react.useState(false),[m,g]=react.useState(""),c=react.useRef(null),h=!e&&!o,C=t.find(P=>P.id===e),T=o?"External":h?"All Wallets":C?.name??"",f=o?Z(r??""):h?"Aggregated":Z(C?.address??""),y=o?"bg-[#5C5C72]":h?"bg-[#C8FF00]":"bg-[#00E676]",x=react.useCallback(()=>{let P=m.trim();P.length>=32&&(s(P),g(""));},[m,s]),A=react.useCallback(P=>{P.key==="Enter"&&x();},[x]);return jsxRuntime.jsxs("div",{className:"flex items-center justify-between gap-4 pb-4",children:[jsxRuntime.jsxs("div",{className:"flex min-w-0 items-center gap-2.5",children:[jsxRuntime.jsxs("div",{className:"relative",ref:c,children:[jsxRuntime.jsxs("button",{type:"button",className:ui.clsx("flex items-center gap-2 rounded-lg border px-2.5 py-1.5 transition-colors",o?"border-[rgba(200,255,0,0.2)] bg-[rgba(200,255,0,0.04)]":"border-[#252530] bg-[#16161E] hover:border-[#35354A] hover:bg-[#1C1C26]",o&&"pointer-events-none"),onClick:()=>!o&&a(P=>!P),children:[jsxRuntime.jsx("span",{className:ui.clsx("h-[7px] w-[7px] flex-shrink-0 rounded-full",y)}),jsxRuntime.jsx("span",{className:"text-[11px] font-medium text-[#A0A0B8]",children:T}),jsxRuntime.jsx("span",{className:"font-mono text-xs text-foreground",children:f}),!o&&jsxRuntime.jsx("svg",{className:ui.clsx("text-[#5C5C72] transition-transform",n&&"rotate-180"),width:"10",height:"10",viewBox:"0 0 12 12",fill:"none",children:jsxRuntime.jsx("path",{d:"M3 4.5L6 7.5L9 4.5",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round"})})]}),n&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{className:"fixed inset-0 z-40",onClick:()=>a(false)}),jsxRuntime.jsxs("div",{className:"absolute left-0 top-[calc(100%+4px)] z-50 min-w-[260px] rounded-lg border border-[#252530] bg-[#16161E] p-1 shadow-[0_8px_32px_rgba(0,0,0,0.4)]",children:[jsxRuntime.jsxs("button",{type:"button",className:ui.clsx("flex w-full items-center gap-2 rounded-[5px] px-2.5 py-2 transition-colors hover:bg-[#1C1C26]",h&&"bg-[rgba(200,255,0,0.07)]"),onClick:()=>{i(void 0),a(false);},children:[jsxRuntime.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[#C8FF00]"}),jsxRuntime.jsx("span",{className:"min-w-[60px] text-[11px] font-medium text-[#A0A0B8]",children:"All Wallets"}),jsxRuntime.jsx("span",{className:"text-[11px] text-[#3A3A4E]",children:"Aggregated"})]}),t.map(P=>jsxRuntime.jsxs("button",{type:"button",className:ui.clsx("flex w-full items-center gap-2 rounded-[5px] px-2.5 py-2 transition-colors hover:bg-[#1C1C26]",e===P.id&&"bg-[rgba(200,255,0,0.07)]"),onClick:()=>{i(P.id),a(false);},children:[jsxRuntime.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[#00E676]"}),jsxRuntime.jsx("span",{className:"min-w-[60px] text-[11px] font-medium text-[#A0A0B8]",children:P.name}),jsxRuntime.jsx("span",{className:"font-mono text-[11px] text-[#5C5C72]",children:Z(P.address)}),jsxRuntime.jsx("span",{className:"ml-auto font-mono text-[11px] font-medium text-foreground",children:P.balance})]},P.id))]})]})]}),jsxRuntime.jsx("button",{type:"button",className:ui.clsx("rounded p-1 text-[#5C5C72] transition-colors hover:bg-[#1C1C26] hover:text-[#C8FF00]",h&&!o&&"pointer-events-none opacity-40"),onClick:p,disabled:h&&!o,children:jsxRuntime.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",children:[jsxRuntime.jsx("rect",{x:"4.5",y:"4.5",width:"7",height:"7",rx:"1.5",stroke:"currentColor",strokeWidth:"1.2"}),jsxRuntime.jsx("path",{d:"M9.5 4.5V3a1.5 1.5 0 0 0-1.5-1.5H3A1.5 1.5 0 0 0 1.5 3v5A1.5 1.5 0 0 0 3 9.5h1.5",stroke:"currentColor",strokeWidth:"1.2"})]})}),jsxRuntime.jsx("span",{className:ui.clsx("flex-shrink-0 rounded-[3px] px-1.5 py-[3px] text-[9px] font-semibold uppercase tracking-wider",o?"bg-[rgba(200,255,0,0.07)] text-[#C8FF00] animate-[pulse-glow_2s_ease-in-out_infinite]":"bg-[rgba(0,230,118,0.1)] text-[#00E676]"),children:o?"Viewing":"Owner"})]}),jsxRuntime.jsxs("div",{className:"flex flex-shrink-0 items-center gap-1.5",children:[jsxRuntime.jsxs("div",{className:"flex h-[34px] w-[240px] items-center gap-1.5 rounded-lg border border-[#252530] bg-[#16161E] px-2.5 transition-all focus-within:w-[300px] focus-within:border-[#C8FF00]",children:[jsxRuntime.jsxs("svg",{className:"flex-shrink-0 text-[#5C5C72]",width:"13",height:"13",viewBox:"0 0 16 16",fill:"none",children:[jsxRuntime.jsx("circle",{cx:"7",cy:"7",r:"5.5",stroke:"currentColor",strokeWidth:"1.5"}),jsxRuntime.jsx("path",{d:"M11 11L14.5 14.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),jsxRuntime.jsx("input",{className:"flex-1 border-none bg-transparent font-mono text-xs text-foreground caret-[#C8FF00] outline-none placeholder:font-sans placeholder:text-[11px] placeholder:text-[#5C5C72]",placeholder:"Search wallet address\u2026",spellCheck:false,value:m,onChange:P=>g(P.target.value),onKeyDown:A})]}),jsxRuntime.jsx("button",{type:"button",className:"whitespace-nowrap rounded-[5px] border border-[#252530] bg-[#1C1C26] px-3 py-1.5 text-[11px] font-medium text-[#A0A0B8] transition-colors hover:border-[#C8FF00] hover:bg-[#C8FF00] hover:text-black",onClick:x,children:"View"})]})]})}var oe=(r=>(r.SPOT="spot",r.PERPS="perps",r.PREDICTION="prediction",r))(oe||{}),Ne=(o=>(o.NET_WORTH="networth",o.PNL="pnl",o))(Ne||{}),we=(i=>(i.ONE_DAY="1D",i.SEVEN_DAY="7D",i.THIRTY_DAY="30D",i.MAX="Max",i))(we||{}),pt={"1D":1,"7D":7,"30D":30,Max:365},dt=(o=>(o.LONG="long",o.SHORT="short",o))(dt||{}),ct=(r=>(r.SWAP="swap",r.SEND="send",r.RECEIVE="receive",r))(ct||{}),ut=(o=>(o.ACTIVE="active",o.PENDING="pending",o))(ut||{}),mt=(o=>(o.WON="won",o.LOST="lost",o))(mt||{}),ft=(r=>(r.POLYMARKET="polymarket",r.DRIFT="drift",r.METADAO="metadao",r))(ft||{});var Mt=[{key:"spot",label:"Spot"},{key:"perps",label:"Perps"},{key:"prediction",label:"Prediction"}];function Kt(e,t,o,r){switch(e){case "spot":return t;case "perps":return o;case "prediction":return r}}function Ae({activeTab:e,onTabChange:t,spotValue:o=0,perpsValue:r=0,predictionValue:i=0}){return jsxRuntime.jsx("div",{className:"flex gap-1 border-b border-[#252530] pb-0 pt-5",children:Mt.map(({key:p,label:s})=>{let n=e===p,a=Kt(p,o,r,i);return jsxRuntime.jsxs("button",{type:"button",className:ui.clsx("relative flex items-center gap-2 border-b-2 px-4 pb-3 pt-2.5 text-[13px] font-medium transition-colors",n?"border-[#C8FF00] text-foreground":"border-transparent text-[#5C5C72] hover:text-[#A0A0B8]"),onClick:()=>t(p),children:[s,!n&&jsxRuntime.jsx("span",{className:"rounded-[10px] bg-[#16161E] px-2 py-0.5 font-mono text-[11px] text-[#5C5C72]",children:S(a)})]},p)})})}function Te({overview:e}){let t=e?.totalValue??0,o=e?.uPnl??0,r=e?.realizedPnl??0,i=e?.totalProfit??0,{sign:p,integer:s,decimal:n}=rt(t);return jsxRuntime.jsxs("div",{className:"flex items-center gap-4 pb-4",children:[jsxRuntime.jsx("div",{className:"flex items-baseline gap-3",children:jsxRuntime.jsxs("div",{className:"font-mono text-[26px] font-bold leading-none tracking-tight",children:[jsxRuntime.jsx("span",{className:"mr-px text-lg font-medium text-[#C8FF00]",children:p}),s,jsxRuntime.jsx("span",{className:"text-base font-normal text-[#5C5C72]",children:n})]})}),jsxRuntime.jsxs("div",{className:"ml-auto flex items-center gap-3",children:[jsxRuntime.jsx(ke,{label:"uPNL",value:o}),jsxRuntime.jsx(gt,{}),jsxRuntime.jsx(ke,{label:"Realized",value:r}),jsxRuntime.jsx(gt,{}),jsxRuntime.jsx(ke,{label:"Total Profit",value:i})]})]})}function ke({label:e,value:t}){return jsxRuntime.jsxs("div",{className:"flex items-center gap-1.5",children:[jsxRuntime.jsx("span",{className:"text-[11px] text-[#5C5C72]",children:e}),jsxRuntime.jsx("span",{className:ui.clsx("font-mono text-xs font-medium",t>0?"text-[#00E676]":t<0?"text-[#FF5252]":"text-[#5C5C72]"),children:te(t)})]})}function gt(){return jsxRuntime.jsx("div",{className:"h-3.5 w-px bg-[#252530]"})}var Zt=["1D","7D","30D","Max"];function yt(e,t){let o=new Date(e);switch(t){case "1D":return o.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",hour12:false});default:return o.toLocaleDateString("en-US",{month:"short",day:"numeric"})}}function eo(e){return e==="pnl"?"change":"netWorth"}function He({curveType:e,curvePeriod:t,data:o,isLoading:r,onTypeChange:i,onPeriodChange:p}){let s=o?.points??[],n=eo(e),a=e==="pnl",m=react.useMemo(()=>s.map(f=>a?f.change:f.netWorth),[s,a]),g=m.some(f=>f<0),{minVal:c,maxVal:h}=react.useMemo(()=>{if(m.length===0)return {minVal:0,maxVal:100};let f=Math.min(...m),y=Math.max(...m),x=y-f||1;return {minVal:f-x*.1,maxVal:y+x*.1}},[m]),C=react.useMemo(()=>{if(s.length===0)return [];let f=Math.min(7,s.length),y=Math.max(1,Math.floor((s.length-1)/(f-1))),x=[];for(let P=0;P<s.length;P+=y)x.push({ts:s[P].timestamp,label:yt(s[P].timestamp,t)});let A=s[s.length-1];return x[x.length-1]?.ts!==A.timestamp&&x.push({ts:A.timestamp,label:yt(A.timestamp,t)}),x},[s,t]),T=m[m.length-1]??0;return jsxRuntime.jsxs("div",{className:"overflow-hidden rounded-lg border border-[#252530] bg-[#0F0F16]",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between px-4 pt-3",children:[jsxRuntime.jsxs("div",{className:"flex gap-0.5 rounded-[5px] bg-[#16161E] p-0.5",children:[jsxRuntime.jsx(Pt,{label:"Net Worth",active:e==="networth",onClick:()=>i("networth")}),jsxRuntime.jsx(Pt,{label:"PNL",active:e==="pnl",onClick:()=>i("pnl")})]}),jsxRuntime.jsx("div",{className:"flex gap-0.5",children:Zt.map(f=>jsxRuntime.jsx("button",{type:"button",className:ui.clsx("rounded-[3px] px-2 py-1 text-[10px] font-medium transition-colors",t===f?"bg-[rgba(200,255,0,0.07)] text-[#C8FF00]":"text-[#5C5C72] hover:bg-[#16161E] hover:text-[#A0A0B8]"),onClick:()=>p(f),children:f},f))})]}),jsxRuntime.jsx("div",{className:"h-[180px] px-4 pt-2",children:r||s.length<2?jsxRuntime.jsx("div",{className:"flex h-full items-center justify-center",children:jsxRuntime.jsx("span",{className:"text-xs text-[#5C5C72]",children:r?"":"Not enough data"})}):jsxRuntime.jsx(recharts.ResponsiveContainer,{width:"100%",height:"100%",children:jsxRuntime.jsxs(recharts.AreaChart,{data:s,margin:{top:8,right:0,left:0,bottom:0},children:[jsxRuntime.jsxs("defs",{children:[jsxRuntime.jsxs("linearGradient",{id:"gradAccent",x1:"0",y1:"0",x2:"0",y2:"1",children:[jsxRuntime.jsx("stop",{offset:"0%",stopColor:"#C8FF00",stopOpacity:.12}),jsxRuntime.jsx("stop",{offset:"100%",stopColor:"#C8FF00",stopOpacity:0})]}),jsxRuntime.jsxs("linearGradient",{id:"gradGreen",x1:"0",y1:"0",x2:"0",y2:"1",children:[jsxRuntime.jsx("stop",{offset:"0%",stopColor:"#00E676",stopOpacity:.12}),jsxRuntime.jsx("stop",{offset:"100%",stopColor:"#00E676",stopOpacity:0})]}),jsxRuntime.jsxs("linearGradient",{id:"gradRed",x1:"0",y1:"0",x2:"0",y2:"1",children:[jsxRuntime.jsx("stop",{offset:"0%",stopColor:"#FF5252",stopOpacity:0}),jsxRuntime.jsx("stop",{offset:"100%",stopColor:"#FF5252",stopOpacity:.1})]})]}),jsxRuntime.jsx(recharts.XAxis,{dataKey:"timestamp",hide:true}),jsxRuntime.jsx(recharts.YAxis,{hide:true,domain:[c,h]}),a&&g&&jsxRuntime.jsx(recharts.ReferenceLine,{y:0,stroke:"rgba(255,255,255,0.06)",strokeDasharray:"4 4"}),jsxRuntime.jsx(recharts.Area,{type:"monotone",dataKey:n,stroke:a?T>=0?"#00E676":"#FF5252":"#C8FF00",strokeWidth:1.5,fill:a?T>=0?"url(#gradGreen)":"url(#gradRed)":"url(#gradAccent)",dot:false,isAnimationActive:false})]})})}),jsxRuntime.jsx("div",{className:"flex justify-between px-4 pb-2.5 pt-1",children:C.map(({ts:f,label:y})=>jsxRuntime.jsx("span",{className:"font-mono text-[9px] text-[#3A3A4E]",children:y},f))})]})}function Pt({label:e,active:t,onClick:o}){return jsxRuntime.jsx("button",{type:"button",className:ui.clsx("rounded px-2.5 py-1 text-[11px] font-medium transition-colors",t?"bg-[#1C1C26] text-foreground":"text-[#5C5C72] hover:text-[#A0A0B8]"),onClick:o,children:e})}function Ee({data:e,isLoading:t}){let o=e?.items??[],r=react.useMemo(()=>o.map(i=>({name:i.name,value:i.percent})),[o]);return jsxRuntime.jsxs("div",{className:"flex flex-col overflow-hidden rounded-lg border border-[#252530] bg-[#0F0F16]",children:[jsxRuntime.jsx("div",{className:"px-4 pb-2 pt-3",children:jsxRuntime.jsx("span",{className:"text-xs font-semibold text-[#A0A0B8]",children:"Distribution"})}),jsxRuntime.jsx("div",{className:"flex flex-1 items-center justify-center px-4",children:t||o.length===0?jsxRuntime.jsx("div",{className:"flex h-[140px] w-[140px] items-center justify-center",children:jsxRuntime.jsx("span",{className:"text-xs text-[#5C5C72]",children:t?"":"No data"})}):jsxRuntime.jsx(recharts.ResponsiveContainer,{width:140,height:140,children:jsxRuntime.jsx(recharts.PieChart,{children:jsxRuntime.jsx(recharts.Pie,{data:r,cx:"50%",cy:"50%",innerRadius:32,outerRadius:55,dataKey:"value",stroke:"none",isAnimationActive:false,children:o.map((i,p)=>jsxRuntime.jsx(recharts.Cell,{fill:i.color},p))})})})}),jsxRuntime.jsx("div",{className:"px-4 pb-3 pt-2",children:o.map((i,p)=>jsxRuntime.jsxs("div",{className:"flex items-center gap-1.5 py-[3px] text-[11px]",children:[jsxRuntime.jsx("span",{className:"h-[7px] w-[7px] flex-shrink-0 rounded-[2px]",style:{background:i.color}}),jsxRuntime.jsx("span",{className:"min-w-0 flex-1 truncate text-[#A0A0B8]",children:i.name}),jsxRuntime.jsxs("span",{className:"font-mono text-[10px] text-[#5C5C72]",children:[i.percent.toFixed(1),"%"]}),jsxRuntime.jsx("span",{className:"min-w-[55px] text-right font-mono text-[10px] text-foreground",children:S(i.value)})]},p))})]})}var re=react.createContext(null);var ne=react.createContext({}),fe=react.createContext({});function se(){let e=react.useContext(ne);if(!e)throw new Error("usePortfolioContext must be used within a PortfolioProvider");return e}function k(){let e=react.useContext(re);if(!e)throw new Error("usePortfolioClient must be used within a PortfolioClientProvider");return e}function vt(e){return ["portfolio","overview",e??{}]}async function co(e,t){return await e.getOverview(t)}function Qe(e,t={}){let o=k();return reactQuery.useQuery({queryKey:vt(e),queryFn:async()=>co(o,e),...t})}function Ct(e){return ["portfolio","spot","holdings",e??{}]}async function mo(e,t){return await e.getSpotHoldings(t)}function ie(e,t={}){let o=k();return reactQuery.useQuery({queryKey:Ct(e),queryFn:async()=>mo(o,e),...t})}function St(e){return ["portfolio","spot","history",e??{}]}async function xo(e,t){return await e.getSpotHistory(t)}function Re(e,t={}){let o=k();return reactQuery.useQuery({queryKey:St(e),queryFn:async()=>xo(o,e),...t})}function Nt(e){return ["portfolio","perps","positions",e??{}]}async function yo(e,t){return await e.getPerpsPositions(t)}function Ue(e,t={}){let o=k();return reactQuery.useQuery({queryKey:Nt(e),queryFn:async()=>yo(o,e),...t})}function wt(e){return ["portfolio","perps","history",e??{}]}async function bo(e,t){return await e.getPerpsHistory(t)}function Ie(e,t={}){let o=k();return reactQuery.useQuery({queryKey:wt(e),queryFn:async()=>bo(o,e),...t})}function At(e){return ["portfolio","prediction","active",e??{}]}async function vo(e,t){return await e.getPredictionBets(t)}function Oe(e,t={}){let o=k();return reactQuery.useQuery({queryKey:At(e),queryFn:async()=>vo(o,e),...t})}function kt(e){return ["portfolio","prediction","settled",e??{}]}async function So(e,t){return await e.getPredictionSettled(t)}function Be(e,t={}){let o=k();return reactQuery.useQuery({queryKey:kt(e),queryFn:async()=>So(o,e),...t})}function Tt(e){return ["portfolio","chart",e]}async function wo(e,t){return await e.getChartData(t)}function Le(e,t={}){let o=k();return reactQuery.useQuery({queryKey:Tt(e),queryFn:async()=>wo(o,e),...t})}function ko(){return ["portfolio","distribution"]}function We(e){return {data:react.useMemo(()=>st(e),[e])}}function To(){let{summary:e,summaryStatus:t}=se();return {data:e,...t}}function Fo(){let{refetchSummary:e}=se();return e}var Oo=15e3;function Ht(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}function Bo({chain:e,address:t,tokenAddresses:o,pollMs:r=Oo}){let i=!!t&&o.length>0,[p,s]=react.useState({}),n=react$1.useWalletPortfoliosByTokensQuery({chain:e,address:t,tokenAddresses:o},{enabled:i,refetchInterval:r}),a=react$1.useWalletPortfolioPnlsByTokensQuery({chain:e,address:t,tokenAddresses:o},{enabled:i,refetchInterval:r});react.useEffect(()=>{let T=n.data??[],f=new Map;if(a.data)for(let x of a.data)f.set(x.address,x);let y={};for(let x of T)y[x.address]={...x,pnl:f.get(x.address)??null};s(y);},[n.data,a.data]);let m=react.useRef(""),g=react.useRef(new Set),c=o.slice().sort().join(",");c!==m.current&&(m.current=c,g.current=new Set(o));let h=g.current;react$1.useWalletPortfoliosSubscription({chain:e,address:t},T=>{s(f=>{let y=f;for(let x of T){if(!h.has(x.tokenAddress))continue;let A=y[x.tokenAddress];if(!A)continue;let{chain:P,walletAddress:L,tokenAddress:_,...Q}=x,V=Ht(Q);Object.keys(V).length!==0&&(y=y===f?{...f}:y,y[x.tokenAddress]={...A,...V});}return y});},{enabled:i}),react$1.useWalletPortfolioPnlsSubscription({chain:e,address:t},T=>{s(f=>{let y=f;for(let x of T){if(!h.has(x.tokenAddress))continue;let A=y[x.tokenAddress];if(!A||!A.pnl)continue;let{walletAddress:P,tokenAddress:L,..._}=x,Q=Ht(_);Object.keys(Q).length!==0&&(y=y===f?{...f}:y,y[x.tokenAddress]={...A,pnl:{...A.pnl,...Q}});}return y});},{enabled:i});let C=react.useCallback(async()=>{await Promise.all([n.refetch(),a.refetch()]);},[n.refetch,a.refetch]);return {tokens:p,isPending:n.isPending,isFetching:n.isFetching||a.isFetching,isError:n.isError,isSuccess:n.isSuccess,error:n.error,refetch:C}}function Ve(e){let{defaultTab:t="spot",walletAddresses:o,chain:r}=e??{},[i,p]=react.useState(t),[s,n]=react.useState(void 0),[a,m]=react.useState(void 0),[g,c]=react.useState("networth"),[h,C]=react.useState("7D"),T=a!==void 0,f=react.useMemo(()=>{if(a)return {walletAddresses:[a],chain:r};if(o?.length)return {walletAddresses:o,chain:r}},[o,a,r]),y=Qe(f),x=ie(f),A=Le({period:pt[h],...f}),P=We(x.data?.holdings??[]),L=react.useMemo(()=>x.data?.holdings.reduce((I,ce)=>I+ce.value,0)??0,[x.data]),_=react.useCallback(I=>{m(I);},[]),Q=react.useCallback(()=>{m(void 0);},[]),V=react.useCallback(I=>{n(I);},[]);return {activeTab:i,setActiveTab:p,walletId:s,selectWallet:V,viewingAddress:a,isViewing:T,curveType:g,setCurveType:c,curvePeriod:h,setCurvePeriod:C,portfolioQuery:f,overviewQuery:y,curveQuery:A,distributionQuery:P,spotHoldingsQuery:x,spotValue:L,perpsValue:0,predictionValue:0,enterViewing:_,exitViewing:Q}}function Me(){return jsxRuntime.jsxs("div",{className:"mx-auto max-w-[1280px] px-6",children:[jsxRuntime.jsxs("div",{className:"flex gap-4 border-b border-[#252530] pb-0 pt-5",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-9 w-16 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-9 w-28 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-9 w-32 rounded-md"})]}),jsxRuntime.jsxs("div",{className:"flex items-center justify-between gap-4 py-4",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2.5",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-8 w-48 rounded-lg"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-6 rounded"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-5 w-14 rounded-[3px]"})]}),jsxRuntime.jsxs("div",{className:"flex items-center gap-1.5",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-[34px] w-[240px] rounded-lg"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-[34px] w-12 rounded-[5px]"})]})]}),jsxRuntime.jsxs("div",{className:"flex items-center gap-4 pb-4",children:[jsxRuntime.jsxs("div",{className:"flex items-baseline gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-8 w-48 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16 rounded"})]}),jsxRuntime.jsxs("div",{className:"ml-auto flex items-center gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-28 rounded"}),jsxRuntime.jsx("div",{className:"h-3.5 w-px bg-[#252530]"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-28 rounded"}),jsxRuntime.jsx("div",{className:"h-3.5 w-px bg-[#252530]"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-20 rounded"})]})]}),jsxRuntime.jsxs("div",{className:"grid grid-cols-[1fr_340px] gap-3 pb-4",children:[jsxRuntime.jsxs("div",{className:"rounded-lg border border-[#252530] bg-[#0F0F16] p-4",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between pb-4",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-7 w-40 rounded-[5px]"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-32 rounded"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-[180px] w-full rounded-md"}),jsxRuntime.jsx("div",{className:"mt-2 flex justify-between",children:Array.from({length:7}).map((e,t)=>jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-8 rounded"},t))})]}),jsxRuntime.jsxs("div",{className:"rounded-lg border border-[#252530] bg-[#0F0F16] p-4",children:[jsxRuntime.jsx(ui.Skeleton,{className:"mb-3 h-4 w-24 rounded"}),jsxRuntime.jsx("div",{className:"flex items-center justify-center py-4",children:jsxRuntime.jsx(ui.Skeleton,{className:"h-[140px] w-[140px] rounded-full"})}),jsxRuntime.jsx("div",{className:"space-y-1.5 pt-2",children:Array.from({length:5}).map((e,t)=>jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-full rounded"},t))})]})]}),jsxRuntime.jsxs("div",{className:"pb-6",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between pb-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-8 w-40 rounded-[5px]"}),jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-7 w-40 rounded-[5px]"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-7 w-24 rounded-[5px]"})]})]}),jsxRuntime.jsx(ui.Skeleton,{className:"mb-3 h-5 w-full rounded"}),Array.from({length:5}).map((e,t)=>jsxRuntime.jsx(ui.Skeleton,{className:"mb-2 h-12 w-full rounded-[5px]"},t))]})]})}function Ke({viewingAddress:e,onBack:t}){return jsxRuntime.jsxs("div",{className:"flex items-center justify-between border-b border-[rgba(200,255,0,0.12)] bg-[rgba(200,255,0,0.06)] px-6 py-2",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsx("div",{className:"flex h-[18px] w-[18px] items-center justify-center rounded-full border border-[rgba(200,255,0,0.25)] bg-[rgba(200,255,0,0.07)]",children:jsxRuntime.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:[jsxRuntime.jsx("path",{d:"M8 3C4.36 3 1.26 5.28 0 8.5c1.26 3.22 4.36 5.5 8 5.5s6.74-2.28 8-5.5C14.74 5.28 11.64 3 8 3z",stroke:"#C8FF00",strokeWidth:"1.3",fill:"none"}),jsxRuntime.jsx("circle",{cx:"8",cy:"8.5",r:"2.5",stroke:"#C8FF00",strokeWidth:"1.3",fill:"none"})]})}),jsxRuntime.jsx("span",{className:"text-xs font-medium text-[#C8FF00]",children:"Viewing external portfolio"}),jsxRuntime.jsx("span",{className:"ml-1 font-mono text-[11px] text-[#A0A0B8]",children:Z(e)})]}),jsxRuntime.jsxs("button",{type:"button",className:"flex items-center gap-1.5 rounded-[5px] border border-[#252530] bg-[#1C1C26] px-3 py-1.5 text-[11px] font-medium text-[#A0A0B8] transition-colors hover:border-[#C8FF00] hover:bg-[#C8FF00] hover:text-black",onClick:t,children:[jsxRuntime.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:jsxRuntime.jsx("path",{d:"M10 2L4 8l6 6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})}),"Back to My Portfolio"]})]})}function Lo({wallets:e=[],onCopyAddress:t,renderHoldings:o,isLoading:r,...i}){let p=Ve(i),{activeTab:s,setActiveTab:n,walletId:a,selectWallet:m,viewingAddress:g,isViewing:c,curveType:h,setCurveType:C,curvePeriod:T,setCurvePeriod:f,portfolioQuery:y,overviewQuery:x,curveQuery:A,distributionQuery:P,spotValue:L,perpsValue:_,predictionValue:Q,enterViewing:V,exitViewing:I}=p;return r||x.isLoading&&!x.data?jsxRuntime.jsx(Me,{}):jsxRuntime.jsxs("div",{children:[c&&g&&jsxRuntime.jsx(Ke,{viewingAddress:g,onBack:I}),jsxRuntime.jsxs("div",{className:"mx-auto max-w-[1280px] px-6",children:[jsxRuntime.jsx(Ae,{activeTab:s,onTabChange:n,spotValue:L,perpsValue:_,predictionValue:Q}),jsxRuntime.jsx(Se,{walletId:a,wallets:e,isViewing:c,viewingAddress:g,onSelectWallet:m,onCopyAddress:()=>{if(c&&g)t?.(g);else {let ue=e.find(ve=>ve.id===a);ue&&t?.(ue.address);}},onSearch:V}),jsxRuntime.jsx(Te,{overview:x.data}),jsxRuntime.jsxs("div",{className:"grid grid-cols-[1fr_340px] gap-3 pb-4",children:[jsxRuntime.jsx(He,{curveType:h,curvePeriod:T,data:A.data,isLoading:A.isLoading,onTypeChange:C,onPeriodChange:f}),jsxRuntime.jsx(Ee,{data:P.data,isLoading:false})]}),o?.({activeTab:s,portfolioQuery:y,isViewing:c})]})]})}function ge({open:e,title:t,message:o,confirmLabel:r,cancelLabel:i,onConfirm:p,onCancel:s}){return e?jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",children:[jsxRuntime.jsx("div",{className:"absolute inset-0 bg-black/60",onClick:s,onKeyDown:n=>{n.key==="Escape"&&s();},role:"button",tabIndex:-1,"aria-label":"Close dialog"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full max-w-sm rounded-xl border border-[#252530] bg-[#12121A] p-6 shadow-2xl",children:[jsxRuntime.jsx("h3",{className:"text-sm font-semibold text-foreground",children:t}),jsxRuntime.jsx("p",{className:"mt-2 text-xs leading-relaxed text-[#A0A0B8]",children:o}),jsxRuntime.jsxs("div",{className:"mt-5 flex items-center justify-end gap-2",children:[jsxRuntime.jsx("button",{type:"button",className:"rounded-lg px-4 py-2 text-xs font-medium text-[#5C5C72] transition-colors hover:bg-[#1C1C26] hover:text-foreground",onClick:s,children:i}),jsxRuntime.jsx("button",{type:"button",className:ui.clsx("rounded-lg border px-4 py-2 text-xs font-medium transition-colors","border-[rgba(255,82,82,0.25)] text-[#FF5252]","hover:border-[#FF5252] hover:bg-[rgba(255,82,82,0.1)]"),onClick:p,children:r})]})]})]}):null}function je({activeTab:e,portfolioQuery:t,isViewing:o}){let[r,i]=react.useState("holdings"),[p,s]=react.useState("positions"),[n,a]=react.useState("active"),[m,g]=react.useState(""),[c,h]=react.useState(""),[C,T]=react.useState(""),[f,y]=react.useState(false),[x,A]=react.useState(false),P=react.useCallback(()=>{A(M=>!M);},[]),L=ie(t,{enabled:e==="spot"}),_=Re(t,{enabled:e==="spot"&&r==="history"}),Q=Ue(t,{enabled:e==="perps"}),V=Ie(t,{enabled:e==="perps"&&p==="history"}),I=Oe(t,{enabled:e==="prediction"}),ce=Be(t,{enabled:e==="prediction"&&n==="settled"}),et=react.useMemo(()=>(L.data?.holdings??[]).filter(K=>{if(f&&K.value<1&&!K.verified)return false;if(m){let J=m.toLowerCase();return K.name.toLowerCase().includes(J)||K.symbol.toLowerCase().includes(J)}return true}),[L.data?.holdings,f,m]),ue=react.useMemo(()=>{let M=Q.data?.positions??[];if(!c)return M;let K=c.toLowerCase();return M.filter(J=>J.pair.toLowerCase().includes(K))},[Q.data?.positions,c]),ve=react.useMemo(()=>{let M=I.data?.bets??[];if(!C)return M;let K=C.toLowerCase();return M.filter(J=>J.market.toLowerCase().includes(K))},[I.data?.bets,C]);return {spotSubTab:r,setSpotSubTab:i,perpsSubTab:p,setPerpsSubTab:s,predictionSubTab:n,setPredictionSubTab:a,spotSearch:m,setSpotSearch:g,perpsSearch:c,setPerpsSearch:h,predictionSearch:C,setPredictionSearch:T,hideSmall:f,setHideSmall:y,groupCollapsed:x,toggleGroupCollapsed:P,spotHoldingsQuery:L,spotHistoryQuery:_,perpsPositionsQuery:Q,perpsHistoryQuery:V,predictionBetsQuery:I,predictionSettledQuery:ce,filteredSpotHoldings:et,filteredPerpsPositions:ue,filteredPredictionBets:ve,isViewing:o}}function G({tabs:e,activeKey:t,onTabChange:o}){return jsxRuntime.jsx("div",{className:"flex gap-0.5",children:e.map(r=>jsxRuntime.jsx("button",{type:"button",className:ui.clsx("rounded-[5px] px-3 py-1.5 text-xs font-medium transition-colors",t===r.key?"bg-[#1C1C26] text-foreground":"text-[#5C5C72] hover:bg-[#16161E] hover:text-[#A0A0B8]"),onClick:()=>o(r.key),children:r.label},r.key))})}function X({value:e,onChange:t,placeholder:o}){return jsxRuntime.jsxs("div",{className:"flex h-7 w-40 items-center gap-1 rounded-[5px] border border-[#252530] bg-[#16161E] px-2 transition-all focus-within:w-[200px] focus-within:border-[#C8FF00]",children:[jsxRuntime.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 16 16",fill:"none",className:"flex-shrink-0 text-[#5C5C72]",children:[jsxRuntime.jsx("circle",{cx:"7",cy:"7",r:"5.5",stroke:"currentColor",strokeWidth:"1.5"}),jsxRuntime.jsx("path",{d:"M11 11L14.5 14.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),jsxRuntime.jsx("input",{type:"text",className:"flex-1 border-none bg-transparent font-mono text-[11px] text-foreground caret-[#C8FF00] outline-none placeholder:font-sans placeholder:text-[10px] placeholder:text-[#5C5C72]",placeholder:o,spellCheck:false,value:e,onChange:r=>t(r.target.value)})]})}function B({title:e,hint:t}){return jsxRuntime.jsxs("div",{className:"flex flex-col items-center justify-center py-16 text-center",children:[jsxRuntime.jsx("span",{className:"text-sm text-[#5C5C72]",children:e}),t&&jsxRuntime.jsx("span",{className:"mt-1 text-xs text-[#3A3A4E]",children:t})]})}function pe({label:e,disabled:t,onClick:o}){return jsxRuntime.jsxs("button",{type:"button",className:ui.clsx("flex items-center gap-1 whitespace-nowrap rounded-[5px] border px-3 py-1.5 text-[11px] font-medium transition-colors",t?"pointer-events-none border-[#252530] text-[#3A3A4E]":"border-[rgba(255,82,82,0.25)] text-[#FF5252] hover:border-[#FF5252] hover:bg-[rgba(255,82,82,0.1)]"),onClick:o,disabled:t,children:[jsxRuntime.jsx("svg",{width:"11",height:"11",viewBox:"0 0 16 16",fill:"none",children:jsxRuntime.jsx("path",{d:"M4 4l8 8M12 4l-8 8",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})}),e]})}function ze({state:e,onClosePosition:t,onCloseAll:o}){let{perpsSubTab:r,setPerpsSubTab:i,perpsSearch:p,setPerpsSearch:s,filteredPerpsPositions:n,perpsHistoryQuery:a,isViewing:m}=e,g=n.length>0;return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between pb-3",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(G,{tabs:[{key:"positions",label:"Open Positions"},{key:"history",label:"Trade History"}],activeKey:r,onTabChange:c=>i(c)}),r==="positions"&&!m&&jsxRuntime.jsx(pe,{label:"Close All",disabled:!g,onClick:()=>o?.()})]}),jsxRuntime.jsx(X,{value:p,onChange:s,placeholder:"Search pair\u2026"})]}),r==="positions"?jsxRuntime.jsx(Vo,{positions:n,isViewing:m,onClose:t}):jsxRuntime.jsx(Ko,{records:a.data?.records??[],isLoading:a.isLoading})]})}function Vo({positions:e,isViewing:t,onClose:o}){return e.length===0?jsxRuntime.jsx(B,{title:"No open positions",hint:"Start trading \u2192"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:t?"2fr 1fr .8fr .8fr 1fr":"2fr 1fr .8fr .8fr 1fr 80px"},children:[jsxRuntime.jsx("span",{children:"Pair / Side"}),jsxRuntime.jsx("span",{className:"text-right",children:"Size"}),jsxRuntime.jsx("span",{className:"text-right",children:"Entry"}),jsxRuntime.jsx("span",{className:"text-right",children:"Mark"}),jsxRuntime.jsx("span",{className:"text-right",children:"uPNL"}),!t&&jsxRuntime.jsx("span",{className:"text-right"})]}),jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(r=>jsxRuntime.jsx(Mo,{position:r,isViewing:t,onClose:o},r.id))})]})}function Mo({position:e,isViewing:t,onClose:o}){let r=e.side==="long",i=e.uPnl>=0;return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:t?"2fr 1fr .8fr .8fr 1fr":"2fr 1fr .8fr .8fr 1fr 80px"},children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[e.icon?jsxRuntime.jsx("img",{src:e.icon,alt:e.pair,className:"h-6 w-6 flex-shrink-0 rounded-full"}):jsxRuntime.jsx("div",{className:"flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-[#1C1C26] text-[9px] font-bold text-[#5C5C72]",children:e.pair.slice(0,2)}),jsxRuntime.jsxs("div",{className:"flex items-center gap-1.5",children:[jsxRuntime.jsx("span",{className:"text-xs font-medium text-foreground",children:e.pair}),jsxRuntime.jsx("span",{className:ui.clsx("rounded px-1.5 py-0.5 text-[10px] font-medium",r?"bg-[rgba(0,230,118,0.12)] text-[#00E676]":"bg-[rgba(255,82,82,0.12)] text-[#FF5252]"),children:r?"Long":"Short"}),jsxRuntime.jsxs("span",{className:"rounded bg-[rgba(200,255,0,0.1)] px-1.5 py-0.5 text-[10px] font-medium text-[#C8FF00]",children:[e.leverage,"\xD7"]})]})]}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:S(e.size)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#A0A0B8]",children:S(e.entryPrice)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#A0A0B8]",children:S(e.markPrice)}),jsxRuntime.jsx("span",{className:ui.clsx("text-right font-mono text-xs",i?"text-[#00E676]":"text-[#FF5252]"),children:te(e.uPnl)}),!t&&jsxRuntime.jsx("div",{className:"flex justify-end",children:jsxRuntime.jsx("button",{type:"button",className:"rounded-[5px] border border-[#252530] px-2.5 py-1 text-[10px] font-medium text-[#5C5C72] transition-colors hover:border-[#FF5252] hover:text-[#FF5252]",onClick:()=>o?.(e),children:"Close"})})]})}function Ko({records:e,isLoading:t}){return t?jsxRuntime.jsx("div",{className:"flex items-center justify-center py-16",children:jsxRuntime.jsx("div",{className:"h-5 w-5 animate-spin rounded-full border-2 border-[#C8FF00] border-t-transparent"})}):e.length===0?jsxRuntime.jsx(B,{title:"No trade history",hint:"Closed positions will appear here"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:"1.5fr 80px 1fr 1fr 1fr 100px"},children:[jsxRuntime.jsx("span",{children:"Pair"}),jsxRuntime.jsx("span",{children:"Side"}),jsxRuntime.jsx("span",{className:"text-right",children:"Size"}),jsxRuntime.jsx("span",{className:"text-right",children:"PNL"}),jsxRuntime.jsx("span",{className:"text-right",children:"Close Price"}),jsxRuntime.jsx("span",{className:"text-right",children:"Time"})]}),jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(o=>jsxRuntime.jsx(qo,{record:o},o.id))})]})}function qo({record:e}){let t=e.side==="long",o=e.pnl>=0;return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:"1.5fr 80px 1fr 1fr 1fr 100px"},children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[e.icon?jsxRuntime.jsx("img",{src:e.icon,alt:e.pair,className:"h-5 w-5 flex-shrink-0 rounded-full"}):jsxRuntime.jsx("div",{className:"flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-[#1C1C26] text-[8px] font-bold text-[#5C5C72]",children:e.pair.slice(0,2)}),jsxRuntime.jsx("span",{className:"text-xs font-medium text-foreground",children:e.pair})]}),jsxRuntime.jsx("span",{children:jsxRuntime.jsx("span",{className:ui.clsx("inline-block rounded px-1.5 py-0.5 text-[10px] font-medium",t?"bg-[rgba(0,230,118,0.12)] text-[#00E676]":"bg-[rgba(255,82,82,0.12)] text-[#FF5252]"),children:t?"Long":"Short"})}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:S(e.size)}),jsxRuntime.jsx("span",{className:ui.clsx("text-right font-mono text-xs",o?"text-[#00E676]":"text-[#FF5252]"),children:te(e.pnl)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#A0A0B8]",children:S(e.closePrice)}),jsxRuntime.jsx("span",{className:"text-right text-[11px] text-[#5C5C72]",children:e.time})]})}function Ge({state:e,onSellBet:t,onSellAll:o}){let{predictionSubTab:r,setPredictionSubTab:i,predictionSearch:p,setPredictionSearch:s,filteredPredictionBets:n,predictionSettledQuery:a,isViewing:m}=e,g=n.length>0;return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between pb-3",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(G,{tabs:[{key:"active",label:"Active Bets"},{key:"settled",label:"Settled"}],activeKey:r,onTabChange:c=>i(c)}),r==="active"&&!m&&jsxRuntime.jsx(pe,{label:"Sell All",disabled:!g,onClick:()=>o?.()})]}),jsxRuntime.jsx(X,{value:p,onChange:s,placeholder:"Search market\u2026"})]}),r==="active"?jsxRuntime.jsx(jo,{bets:n,isViewing:m,onSell:t}):jsxRuntime.jsx(Go,{records:a.data?.records??[],isLoading:a.isLoading})]})}var $o={polymarket:"bg-[rgba(0,102,255,0.12)] text-[#0066FF]",drift:"bg-[rgba(200,255,0,0.1)] text-[#C8FF00]",metadao:"bg-[rgba(255,107,157,0.1)] text-[#FF6B9D]"},Yo={polymarket:"Polymarket",drift:"Drift",metadao:"MetaDAO"};function Qt({source:e}){return jsxRuntime.jsx("span",{className:ui.clsx("inline-block rounded px-1.5 py-0.5 text-[10px] font-medium",$o[e]),children:Yo[e]})}function jo({bets:e,isViewing:t,onSell:o}){return e.length===0?jsxRuntime.jsx(B,{title:"No active bets",hint:"Explore prediction markets \u2192"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:t?"2.2fr .6fr .7fr .7fr .7fr":"2.2fr .6fr .7fr .7fr .7fr 80px"},children:[jsxRuntime.jsx("span",{children:"Market / Source"}),jsxRuntime.jsx("span",{className:"text-right",children:"Position"}),jsxRuntime.jsx("span",{className:"text-right",children:"Stake"}),jsxRuntime.jsx("span",{className:"text-right",children:"Potential"}),jsxRuntime.jsx("span",{className:"text-right",children:"Status"}),!t&&jsxRuntime.jsx("span",{className:"text-right"})]}),jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(r=>jsxRuntime.jsx(zo,{bet:r,isViewing:t,onSell:o},r.id))})]})}function zo({bet:e,isViewing:t,onSell:o}){return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:t?"2.2fr .6fr .7fr .7fr .7fr":"2.2fr .6fr .7fr .7fr .7fr 80px"},children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2 overflow-hidden",children:[e.icon?jsxRuntime.jsx("img",{src:e.icon,alt:e.market,className:"h-6 w-6 flex-shrink-0 rounded-full"}):jsxRuntime.jsx("div",{className:"flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-[#1C1C26] text-[9px] font-bold text-[#5C5C72]",children:"?"}),jsxRuntime.jsxs("div",{className:"flex flex-col overflow-hidden",children:[jsxRuntime.jsx("span",{className:"truncate text-xs font-medium text-foreground",children:e.market}),jsxRuntime.jsx(Qt,{source:e.source})]})]}),jsxRuntime.jsx("span",{className:ui.clsx("text-right text-xs font-medium",e.position==="Yes"?"text-[#00E676]":"text-[#FF5252]"),children:e.position}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:S(e.stake)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#00E676]",children:S(e.potential)}),jsxRuntime.jsx("span",{className:"text-right",children:jsxRuntime.jsx("span",{className:ui.clsx("inline-block rounded px-1.5 py-0.5 text-[10px] font-medium",e.status==="active"?"bg-[rgba(0,230,118,0.12)] text-[#00E676]":"bg-[rgba(200,255,0,0.1)] text-[#C8FF00]"),children:e.status==="active"?"Active":"Pending"})}),!t&&jsxRuntime.jsx("div",{className:"flex justify-end",children:jsxRuntime.jsx("button",{type:"button",className:"rounded-[5px] border border-[#252530] px-2.5 py-1 text-[10px] font-medium text-[#5C5C72] transition-colors hover:border-[#FF5252] hover:text-[#FF5252]",onClick:()=>o?.(e),children:"Sell"})})]})}function Go({records:e,isLoading:t}){return t?jsxRuntime.jsx("div",{className:"flex items-center justify-center py-16",children:jsxRuntime.jsx("div",{className:"h-5 w-5 animate-spin rounded-full border-2 border-[#C8FF00] border-t-transparent"})}):e.length===0?jsxRuntime.jsx(B,{title:"No settled bets",hint:"Settled predictions will appear here"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:"1.5fr .8fr .6fr .7fr .6fr .7fr"},children:[jsxRuntime.jsx("span",{children:"Market"}),jsxRuntime.jsx("span",{children:"Source"}),jsxRuntime.jsx("span",{className:"text-right",children:"Position"}),jsxRuntime.jsx("span",{className:"text-right",children:"Stake"}),jsxRuntime.jsx("span",{className:"text-right",children:"Result"}),jsxRuntime.jsx("span",{className:"text-right",children:"Payout"})]}),jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(o=>jsxRuntime.jsx(Xo,{record:o},o.id))})]})}function Xo({record:e}){let t=e.result==="won";return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:"1.5fr .8fr .6fr .7fr .6fr .7fr"},children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2 overflow-hidden",children:[e.icon?jsxRuntime.jsx("img",{src:e.icon,alt:e.market,className:"h-5 w-5 flex-shrink-0 rounded-full"}):jsxRuntime.jsx("div",{className:"flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-[#1C1C26] text-[8px] font-bold text-[#5C5C72]",children:"?"}),jsxRuntime.jsx("span",{className:"truncate text-xs font-medium text-foreground",children:e.market})]}),jsxRuntime.jsx(Qt,{source:e.source}),jsxRuntime.jsx("span",{className:ui.clsx("text-right text-xs font-medium",e.position==="Yes"?"text-[#00E676]":"text-[#FF5252]"),children:e.position}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:S(e.stake)}),jsxRuntime.jsx("span",{className:"text-right",children:jsxRuntime.jsx("span",{className:ui.clsx("inline-block rounded px-1.5 py-0.5 text-[10px] font-medium",t?"bg-[rgba(0,230,118,0.12)] text-[#00E676]":"bg-[rgba(255,82,82,0.12)] text-[#FF5252]"),children:t?"Won":"Lost"})}),jsxRuntime.jsx("span",{className:ui.clsx("text-right font-mono text-xs",t?"text-[#00E676]":"text-[#5C5C72]"),children:t?`+${S(e.payout)}`:S(e.payout)})]})}function Je({state:e}){let{spotSubTab:t,setSpotSubTab:o,spotSearch:r,setSpotSearch:i,hideSmall:p,setHideSmall:s,groupCollapsed:n,toggleGroupCollapsed:a,filteredSpotHoldings:m,spotHistoryQuery:g}=e;return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between pb-3",children:[jsxRuntime.jsx(G,{tabs:[{key:"holdings",label:"Holdings"},{key:"history",label:"History"}],activeKey:t,onTabChange:c=>o(c)}),jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsx(X,{value:r,onChange:i,placeholder:"Search token\u2026"}),t==="holdings"&&jsxRuntime.jsxs("label",{className:"flex cursor-pointer items-center gap-1.5 text-[11px] text-[#5C5C72] select-none",children:[jsxRuntime.jsx("input",{type:"checkbox",className:"accent-[#C8FF00]",checked:p,onChange:c=>s(c.target.checked)}),"Hide small"]})]})]}),t==="holdings"?jsxRuntime.jsx(Jo,{holdings:m,groupCollapsed:n,onToggleGroup:a}):jsxRuntime.jsx(er,{records:g.data?.trades??[],isLoading:g.isLoading})]})}function Jo({holdings:e,groupCollapsed:t,onToggleGroup:o}){return e.length===0?jsxRuntime.jsx(B,{title:"No tokens found",hint:"Your spot tokens will appear here"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:"2fr 1fr 1fr 1fr 1fr"},children:[jsxRuntime.jsx("span",{children:"Asset"}),jsxRuntime.jsx("span",{className:"text-right",children:"Balance"}),jsxRuntime.jsx("span",{className:"text-right",children:"Price"}),jsxRuntime.jsx("span",{className:"text-right",children:"Value"}),jsxRuntime.jsx("span",{className:"text-right",children:"24h"})]}),jsxRuntime.jsxs("button",{type:"button",className:"flex w-full items-center gap-2 px-3 py-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72] transition-colors hover:text-[#A0A0B8]",onClick:o,children:[jsxRuntime.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",className:ui.clsx("transition-transform",t&&"-rotate-90"),children:jsxRuntime.jsx("path",{d:"M4 6l4 4 4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})}),jsxRuntime.jsx("span",{children:"Tokens"}),jsxRuntime.jsx("span",{className:"text-[#3A3A4E]",children:e.length})]}),!t&&jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(r=>jsxRuntime.jsx(Zo,{holding:r},r.tokenAddress))})]})}function Zo({holding:e}){let t=e.change24h>=0;return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:"2fr 1fr 1fr 1fr 1fr"},children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2.5 overflow-hidden",children:[e.image?jsxRuntime.jsx("img",{src:e.image,alt:e.symbol,className:"h-7 w-7 flex-shrink-0 rounded-full"}):jsxRuntime.jsx("div",{className:"flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full bg-[#1C1C26] text-[10px] font-bold text-[#5C5C72]",children:e.symbol.slice(0,2)}),jsxRuntime.jsxs("div",{className:"flex flex-col overflow-hidden",children:[jsxRuntime.jsx("span",{className:"truncate text-xs font-medium text-foreground",children:e.name}),jsxRuntime.jsx("span",{className:"text-[10px] text-[#5C5C72]",children:e.symbol})]})]}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:Ce(e.balance)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#A0A0B8]",children:S(e.price)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:S(e.value)}),jsxRuntime.jsx("span",{className:ui.clsx("text-right font-mono text-xs",t?"text-[#00E676]":"text-[#FF5252]"),children:ot(e.change24h)})]})}function er({records:e,isLoading:t}){return t?jsxRuntime.jsx("div",{className:"flex items-center justify-center py-16",children:jsxRuntime.jsx("div",{className:"h-5 w-5 animate-spin rounded-full border-2 border-[#C8FF00] border-t-transparent"})}):e.length===0?jsxRuntime.jsx(B,{title:"No history found",hint:"Transaction history will appear here"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:"80px 1.5fr 1fr 1fr 100px 80px"},children:[jsxRuntime.jsx("span",{children:"Type"}),jsxRuntime.jsx("span",{children:"Detail"}),jsxRuntime.jsx("span",{className:"text-right",children:"Amount"}),jsxRuntime.jsx("span",{className:"text-right",children:"Value"}),jsxRuntime.jsx("span",{className:"text-right",children:"Time"}),jsxRuntime.jsx("span",{className:"text-right",children:"TxHash"})]}),jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(o=>jsxRuntime.jsx(nr,{record:o},`${o.txHash}-${o.tokenAddress}`))})]})}var tr={swap:"bg-[rgba(139,123,255,0.12)] text-[#8B7BFF]",send:"bg-[rgba(255,82,82,0.12)] text-[#FF5252]",receive:"bg-[rgba(0,230,118,0.12)] text-[#00E676]"},or={swap:"Swap",send:"Send",receive:"Receive"};function rr(e){return e.type==="swap"&&e.sideTokenSymbol?`${e.tokenSymbol} \u2192 ${e.sideTokenSymbol}`:e.tokenName||e.tokenSymbol}function nr({record:e}){let t=nt(e.txHash,e.chain);return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:"80px 1.5fr 1fr 1fr 100px 80px"},children:[jsxRuntime.jsx("span",{children:jsxRuntime.jsx("span",{className:ui.clsx("inline-block rounded px-1.5 py-0.5 text-[10px] font-medium",tr[e.type]),children:or[e.type]})}),jsxRuntime.jsx("span",{className:"truncate text-xs text-foreground",children:rr(e)}),jsxRuntime.jsxs("span",{className:"text-right font-mono text-xs text-foreground",children:[Ce(e.tokenAmount)," ",e.tokenSymbol]}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#A0A0B8]",children:S(e.valueUsd)}),jsxRuntime.jsx("span",{className:"text-right text-[11px] text-[#5C5C72]",children:e.timestamp?it(e.timestamp):"\u2014"}),jsxRuntime.jsx("span",{className:"text-right",children:e.txHash?jsxRuntime.jsxs("a",{href:t,target:"_blank",rel:"noopener noreferrer",className:"font-mono text-[11px] text-[#5C5C72] transition-colors hover:text-[#C8FF00]",children:[e.txHash.slice(0,4),"\u2026",e.txHash.slice(-3)]}):jsxRuntime.jsx("span",{className:"font-mono text-[11px] text-[#3A3A4E]",children:"\u2014"})})]})}function ir({onClosePosition:e,onCloseAllPositions:t,onSellBet:o,onSellAllBets:r,...i}){let p=je(i),[s,n]=react.useState(null),a=react.useCallback(()=>{n("closeAll");},[]),m=react.useCallback(()=>{n("sellAll");},[]),g=react.useCallback(()=>{s==="closeAll"?t?.():s==="sellAll"&&r?.(),n(null);},[s,t,r]),c=react.useCallback(()=>{n(null);},[]);return jsxRuntime.jsxs("div",{className:"rounded-xl border border-[#1C1C26] bg-[#0E0E16] p-4",children:[(()=>{switch(i.activeTab){case "spot":return jsxRuntime.jsx(Je,{state:p});case "perps":return jsxRuntime.jsx(ze,{state:p,onClosePosition:e,onCloseAll:a});case "prediction":return jsxRuntime.jsx(Ge,{state:p,onSellBet:o,onSellAll:m});default:return null}})(),jsxRuntime.jsx(ge,{open:s==="closeAll",title:"Close All Positions",message:"Close all positions? This will route to each protocol to execute.",confirmLabel:"Confirm Close All",cancelLabel:"Cancel",onConfirm:g,onCancel:c}),jsxRuntime.jsx(ge,{open:s==="sellAll",title:"Sell All Positions",message:"Sell all positions? This will route to each platform to execute.",confirmLabel:"Confirm Sell All",cancelLabel:"Cancel",onConfirm:g,onCancel:c})]})}function lr({client:e,children:t}){return jsxRuntime.jsx(re.Provider,{value:e,children:t})}var xr=15e3;function gr(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}function Rt({chain:e,address:t,enabled:o=true,summaryPollMs:r=xr}){let{setSummary:i,setSummaryStatus:p,setRefetchSummary:s}=react.useContext(fe),n=react$1.useWalletPortfoliosQuery({chain:e,address:t},{enabled:o,refetchInterval:r}),a=react$1.useWalletPnlQuery({chain:e,address:t},{enabled:o,refetchInterval:r});react.useEffect(()=>{let g=n.isPending||a.isPending,c=n.isFetching||a.isFetching,h=n.isError||a.isError,C=n.isSuccess&&a.isSuccess;p({status:h?"error":C?"success":"pending",fetchStatus:c?"fetching":"idle",isLoading:g&&c,isPending:g,isFetching:c,isRefetching:C&&c,isError:h,isSuccess:C,error:n.error??a.error,dataUpdatedAt:Math.max(n.dataUpdatedAt,a.dataUpdatedAt)});},[n.isPending,n.isFetching,n.isError,n.isSuccess,n.error,n.dataUpdatedAt,a.isPending,a.isFetching,a.isError,a.isSuccess,a.error,a.dataUpdatedAt,p]),react.useEffect(()=>{let g=n.data,c=a.data;!g||!c||i({...c,balanceInUsd:g.balanceInUsd,balanceInNative:g.balanceInNative});},[n.data,a.data,i]),react$1.useWalletPnlSubscription({chain:e,address:t},g=>{i(c=>{if(!c)return c;let h=c;for(let C of g)h={...h,...gr(C)};return h});},{enabled:o});let m=react.useCallback(async()=>{await Promise.all([n.refetch(),a.refetch()]);},[n,a]);react.useEffect(()=>{s(m);},[m,s]);}function Pr({chain:e,address:t,children:o}){let[r,i]=react.useState(null),[p,s]=react.useState(hr),n=react.useRef(()=>Promise.resolve()),a=react.useCallback(()=>n.current(),[]),m=react.useCallback(h=>{n.current=h;},[]),g=react.useMemo(()=>({summary:r,summaryStatus:p,refetchSummary:a}),[r,p,a]),c=react.useMemo(()=>({setSummary:i,setSummaryStatus:s,setRefetchSummary:m}),[i,s,m]);return jsxRuntime.jsx(fe.Provider,{value:c,children:jsxRuntime.jsx(ne.Provider,{value:g,children:jsxRuntime.jsx(br,{chain:e,address:t,children:o})})})}function br({chain:e,address:t,children:o}){return Rt({chain:e,address:t,enabled:!!t}),jsxRuntime.jsx(jsxRuntime.Fragment,{children:o})}var hr={status:"pending",fetchStatus:"idle",isLoading:false,isPending:true,isFetching:false,isRefetching:false,isError:false,isSuccess:false,error:null,dataUpdatedAt:0};
|
|
1
|
+
'use strict';var react=require('react'),ui=require('@liberfi.io/ui'),jsxRuntime=require('react/jsx-runtime'),recharts=require('recharts'),reactQuery=require('@tanstack/react-query'),react$1=require('@liberfi.io/react');typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-portfolio"]="0.1.10");var Bt="0.1.10";function Sr(e){if(!e)return 0;let t=Number(e);return Number.isFinite(t)?t:0}function S(e){let t=Math.abs(e),o=e<0?"-":"";return t>=1e6?`${o}$${(t/1e6).toFixed(1)}M`:t>=1e4?`${o}$${(t/1e3).toFixed(1)}K`:t>=1?`${o}$${t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}`:t>=.01?`${o}$${t.toFixed(2)}`:t>0?`${o}<$0.01`:"$0.00"}function te(e){let t=S(Math.abs(e));return e>0?`+${t}`:e<0?`-${t.replace("-","")}`:t}function ot(e){return `${e>0?"+":""}${e.toFixed(2)}%`}function rt(e){let o=Math.abs(e).toFixed(2).split("."),r=Number(o[0]).toLocaleString("en-US"),i=`.${o[1]}`;return {sign:e<0?"-$":"$",integer:r,decimal:i}}function Z(e,t=4,o=4){return e.length<=t+o+3?e:`${e.slice(0,t)}\u2026${e.slice(-o)}`}function Ce(e){return e===0?"0":e>=1e6?`${(e/1e6).toFixed(2)}M`:e>=1e3?e.toLocaleString("en-US",{maximumFractionDigits:2}):e>=1?e.toFixed(2):e>=1e-4?e.toFixed(4):"<0.0001"}function nt(e,t){return `https://solscan.io/tx/${e}`}var tt=["#C8FF00","#00E676","#0066FF","#FF6B9D","#8B7BFF","#FF5252","#FFB74D","#4DD0E1"],Lt="#3A3A4E";function st(e){let t=e.reduce((s,n)=>s+n.value,0);if(t<=0)return {items:[]};let o=[...e].sort((s,n)=>n.value-s.value),r=[],i=0,p=0;for(let s of o){let n=s.value/t*100;n<2?i+=s.value:(r.push({name:s.name,symbol:s.symbol,percent:n,value:s.value,color:tt[p%tt.length]}),p++);}return i>0&&r.push({name:"Other",symbol:"OTHER",percent:i/t*100,value:i,color:Lt}),{items:r}}function it(e){return new Date(e).toLocaleDateString("en-US",{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:false})}function Se({walletId:e,wallets:t,isViewing:o,viewingAddress:r,onSelectWallet:i,onCopyAddress:p,onSearch:s}){let[n,a]=react.useState(false),[m,g]=react.useState(""),c=react.useRef(null),h=!e&&!o,C=t.find(P=>P.id===e),T=o?"External":h?"All Wallets":C?.name??"",f=o?Z(r??""):h?"Aggregated":Z(C?.address??""),y=o?"bg-[#5C5C72]":h?"bg-[#C8FF00]":"bg-[#00E676]",x=react.useCallback(()=>{let P=m.trim();P.length>=32&&(s(P),g(""));},[m,s]),A=react.useCallback(P=>{P.key==="Enter"&&x();},[x]);return jsxRuntime.jsxs("div",{className:"flex items-center justify-between gap-4 pb-4",children:[jsxRuntime.jsxs("div",{className:"flex min-w-0 items-center gap-2.5",children:[jsxRuntime.jsxs("div",{className:"relative",ref:c,children:[jsxRuntime.jsxs("button",{type:"button",className:ui.clsx("flex items-center gap-2 rounded-lg border px-2.5 py-1.5 transition-colors",o?"border-[rgba(200,255,0,0.2)] bg-[rgba(200,255,0,0.04)]":"border-[#252530] bg-[#16161E] hover:border-[#35354A] hover:bg-[#1C1C26]",o&&"pointer-events-none"),onClick:()=>!o&&a(P=>!P),children:[jsxRuntime.jsx("span",{className:ui.clsx("h-[7px] w-[7px] flex-shrink-0 rounded-full",y)}),jsxRuntime.jsx("span",{className:"text-[11px] font-medium text-[#A0A0B8]",children:T}),jsxRuntime.jsx("span",{className:"font-mono text-xs text-foreground",children:f}),!o&&jsxRuntime.jsx("svg",{className:ui.clsx("text-[#5C5C72] transition-transform",n&&"rotate-180"),width:"10",height:"10",viewBox:"0 0 12 12",fill:"none",children:jsxRuntime.jsx("path",{d:"M3 4.5L6 7.5L9 4.5",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round"})})]}),n&&jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{className:"fixed inset-0 z-40",onClick:()=>a(false)}),jsxRuntime.jsxs("div",{className:"absolute left-0 top-[calc(100%+4px)] z-50 min-w-[260px] rounded-lg border border-[#252530] bg-[#16161E] p-1 shadow-[0_8px_32px_rgba(0,0,0,0.4)]",children:[jsxRuntime.jsxs("button",{type:"button",className:ui.clsx("flex w-full items-center gap-2 rounded-[5px] px-2.5 py-2 transition-colors hover:bg-[#1C1C26]",h&&"bg-[rgba(200,255,0,0.07)]"),onClick:()=>{i(void 0),a(false);},children:[jsxRuntime.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[#C8FF00]"}),jsxRuntime.jsx("span",{className:"min-w-[60px] text-[11px] font-medium text-[#A0A0B8]",children:"All Wallets"}),jsxRuntime.jsx("span",{className:"text-[11px] text-[#3A3A4E]",children:"Aggregated"})]}),t.map(P=>jsxRuntime.jsxs("button",{type:"button",className:ui.clsx("flex w-full items-center gap-2 rounded-[5px] px-2.5 py-2 transition-colors hover:bg-[#1C1C26]",e===P.id&&"bg-[rgba(200,255,0,0.07)]"),onClick:()=>{i(P.id),a(false);},children:[jsxRuntime.jsx("span",{className:"h-1.5 w-1.5 rounded-full bg-[#00E676]"}),jsxRuntime.jsx("span",{className:"min-w-[60px] text-[11px] font-medium text-[#A0A0B8]",children:P.name}),jsxRuntime.jsx("span",{className:"font-mono text-[11px] text-[#5C5C72]",children:Z(P.address)}),jsxRuntime.jsx("span",{className:"ml-auto font-mono text-[11px] font-medium text-foreground",children:P.balance})]},P.id))]})]})]}),jsxRuntime.jsx("button",{type:"button",className:ui.clsx("rounded p-1 text-[#5C5C72] transition-colors hover:bg-[#1C1C26] hover:text-[#C8FF00]",h&&!o&&"pointer-events-none opacity-40"),onClick:p,disabled:h&&!o,children:jsxRuntime.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",children:[jsxRuntime.jsx("rect",{x:"4.5",y:"4.5",width:"7",height:"7",rx:"1.5",stroke:"currentColor",strokeWidth:"1.2"}),jsxRuntime.jsx("path",{d:"M9.5 4.5V3a1.5 1.5 0 0 0-1.5-1.5H3A1.5 1.5 0 0 0 1.5 3v5A1.5 1.5 0 0 0 3 9.5h1.5",stroke:"currentColor",strokeWidth:"1.2"})]})}),jsxRuntime.jsx("span",{className:ui.clsx("flex-shrink-0 rounded-[3px] px-1.5 py-[3px] text-[9px] font-semibold uppercase tracking-wider",o?"bg-[rgba(200,255,0,0.07)] text-[#C8FF00] animate-[pulse-glow_2s_ease-in-out_infinite]":"bg-[rgba(0,230,118,0.1)] text-[#00E676]"),children:o?"Viewing":"Owner"})]}),jsxRuntime.jsxs("div",{className:"flex flex-shrink-0 items-center gap-1.5",children:[jsxRuntime.jsxs("div",{className:"flex h-[34px] w-[240px] items-center gap-1.5 rounded-lg border border-[#252530] bg-[#16161E] px-2.5 transition-all focus-within:w-[300px] focus-within:border-[#C8FF00]",children:[jsxRuntime.jsxs("svg",{className:"flex-shrink-0 text-[#5C5C72]",width:"13",height:"13",viewBox:"0 0 16 16",fill:"none",children:[jsxRuntime.jsx("circle",{cx:"7",cy:"7",r:"5.5",stroke:"currentColor",strokeWidth:"1.5"}),jsxRuntime.jsx("path",{d:"M11 11L14.5 14.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),jsxRuntime.jsx("input",{className:"flex-1 border-none bg-transparent font-mono text-xs text-foreground caret-[#C8FF00] outline-none placeholder:font-sans placeholder:text-[11px] placeholder:text-[#5C5C72]",placeholder:"Search wallet address\u2026",spellCheck:false,value:m,onChange:P=>g(P.target.value),onKeyDown:A})]}),jsxRuntime.jsx("button",{type:"button",className:"whitespace-nowrap rounded-[5px] border border-[#252530] bg-[#1C1C26] px-3 py-1.5 text-[11px] font-medium text-[#A0A0B8] transition-colors hover:border-[#C8FF00] hover:bg-[#C8FF00] hover:text-black",onClick:x,children:"View"})]})]})}var oe=(r=>(r.SPOT="spot",r.PERPS="perps",r.PREDICTION="prediction",r))(oe||{}),Ne=(o=>(o.NET_WORTH="networth",o.PNL="pnl",o))(Ne||{}),we=(i=>(i.ONE_DAY="1D",i.SEVEN_DAY="7D",i.THIRTY_DAY="30D",i.MAX="Max",i))(we||{}),pt={"1D":1,"7D":7,"30D":30,Max:365},dt=(o=>(o.LONG="long",o.SHORT="short",o))(dt||{}),ct=(r=>(r.SWAP="swap",r.SEND="send",r.RECEIVE="receive",r))(ct||{}),ut=(o=>(o.ACTIVE="active",o.PENDING="pending",o))(ut||{}),mt=(o=>(o.WON="won",o.LOST="lost",o))(mt||{}),ft=(r=>(r.POLYMARKET="polymarket",r.DRIFT="drift",r.METADAO="metadao",r))(ft||{});var Mt=[{key:"spot",label:"Spot"},{key:"perps",label:"Perps"},{key:"prediction",label:"Prediction"}];function Kt(e,t,o,r){switch(e){case "spot":return t;case "perps":return o;case "prediction":return r}}function Ae({activeTab:e,onTabChange:t,spotValue:o=0,perpsValue:r=0,predictionValue:i=0}){return jsxRuntime.jsx("div",{className:"flex gap-1 border-b border-[#252530] pb-0 pt-5",children:Mt.map(({key:p,label:s})=>{let n=e===p,a=Kt(p,o,r,i);return jsxRuntime.jsxs("button",{type:"button",className:ui.clsx("relative flex items-center gap-2 border-b-2 px-4 pb-3 pt-2.5 text-[13px] font-medium transition-colors",n?"border-[#C8FF00] text-foreground":"border-transparent text-[#5C5C72] hover:text-[#A0A0B8]"),onClick:()=>t(p),children:[s,!n&&jsxRuntime.jsx("span",{className:"rounded-[10px] bg-[#16161E] px-2 py-0.5 font-mono text-[11px] text-[#5C5C72]",children:S(a)})]},p)})})}function Te({overview:e}){let t=e?.totalValue??0,o=e?.uPnl??0,r=e?.realizedPnl??0,i=e?.totalProfit??0,{sign:p,integer:s,decimal:n}=rt(t);return jsxRuntime.jsxs("div",{className:"flex items-center gap-4 pb-4",children:[jsxRuntime.jsx("div",{className:"flex items-baseline gap-3",children:jsxRuntime.jsxs("div",{className:"font-mono text-[26px] font-bold leading-none tracking-tight",children:[jsxRuntime.jsx("span",{className:"mr-px text-lg font-medium text-[#C8FF00]",children:p}),s,jsxRuntime.jsx("span",{className:"text-base font-normal text-[#5C5C72]",children:n})]})}),jsxRuntime.jsxs("div",{className:"ml-auto flex items-center gap-3",children:[jsxRuntime.jsx(ke,{label:"uPNL",value:o}),jsxRuntime.jsx(gt,{}),jsxRuntime.jsx(ke,{label:"Realized",value:r}),jsxRuntime.jsx(gt,{}),jsxRuntime.jsx(ke,{label:"Total Profit",value:i})]})]})}function ke({label:e,value:t}){return jsxRuntime.jsxs("div",{className:"flex items-center gap-1.5",children:[jsxRuntime.jsx("span",{className:"text-[11px] text-[#5C5C72]",children:e}),jsxRuntime.jsx("span",{className:ui.clsx("font-mono text-xs font-medium",t>0?"text-[#00E676]":t<0?"text-[#FF5252]":"text-[#5C5C72]"),children:te(t)})]})}function gt(){return jsxRuntime.jsx("div",{className:"h-3.5 w-px bg-[#252530]"})}var Zt=["1D","7D","30D","Max"];function yt(e,t){let o=new Date(e);switch(t){case "1D":return o.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",hour12:false});default:return o.toLocaleDateString("en-US",{month:"short",day:"numeric"})}}function eo(e){return e==="pnl"?"change":"netWorth"}function He({curveType:e,curvePeriod:t,data:o,isLoading:r,onTypeChange:i,onPeriodChange:p}){let s=o?.points??[],n=eo(e),a=e==="pnl",m=react.useMemo(()=>s.map(f=>a?f.change:f.netWorth),[s,a]),g=m.some(f=>f<0),{minVal:c,maxVal:h}=react.useMemo(()=>{if(m.length===0)return {minVal:0,maxVal:100};let f=Math.min(...m),y=Math.max(...m),x=y-f||1;return {minVal:f-x*.1,maxVal:y+x*.1}},[m]),C=react.useMemo(()=>{if(s.length===0)return [];let f=Math.min(7,s.length),y=Math.max(1,Math.floor((s.length-1)/(f-1))),x=[];for(let P=0;P<s.length;P+=y)x.push({ts:s[P].timestamp,label:yt(s[P].timestamp,t)});let A=s[s.length-1];return x[x.length-1]?.ts!==A.timestamp&&x.push({ts:A.timestamp,label:yt(A.timestamp,t)}),x},[s,t]),T=m[m.length-1]??0;return jsxRuntime.jsxs("div",{className:"overflow-hidden rounded-lg border border-[#252530] bg-[#0F0F16]",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between px-4 pt-3",children:[jsxRuntime.jsxs("div",{className:"flex gap-0.5 rounded-[5px] bg-[#16161E] p-0.5",children:[jsxRuntime.jsx(Pt,{label:"Net Worth",active:e==="networth",onClick:()=>i("networth")}),jsxRuntime.jsx(Pt,{label:"PNL",active:e==="pnl",onClick:()=>i("pnl")})]}),jsxRuntime.jsx("div",{className:"flex gap-0.5",children:Zt.map(f=>jsxRuntime.jsx("button",{type:"button",className:ui.clsx("rounded-[3px] px-2 py-1 text-[10px] font-medium transition-colors",t===f?"bg-[rgba(200,255,0,0.07)] text-[#C8FF00]":"text-[#5C5C72] hover:bg-[#16161E] hover:text-[#A0A0B8]"),onClick:()=>p(f),children:f},f))})]}),jsxRuntime.jsx("div",{className:"h-[180px] px-4 pt-2",children:r||s.length<2?jsxRuntime.jsx("div",{className:"flex h-full items-center justify-center",children:jsxRuntime.jsx("span",{className:"text-xs text-[#5C5C72]",children:r?"":"Not enough data"})}):jsxRuntime.jsx(recharts.ResponsiveContainer,{width:"100%",height:"100%",children:jsxRuntime.jsxs(recharts.AreaChart,{data:s,margin:{top:8,right:0,left:0,bottom:0},children:[jsxRuntime.jsxs("defs",{children:[jsxRuntime.jsxs("linearGradient",{id:"gradAccent",x1:"0",y1:"0",x2:"0",y2:"1",children:[jsxRuntime.jsx("stop",{offset:"0%",stopColor:"#C8FF00",stopOpacity:.12}),jsxRuntime.jsx("stop",{offset:"100%",stopColor:"#C8FF00",stopOpacity:0})]}),jsxRuntime.jsxs("linearGradient",{id:"gradGreen",x1:"0",y1:"0",x2:"0",y2:"1",children:[jsxRuntime.jsx("stop",{offset:"0%",stopColor:"#00E676",stopOpacity:.12}),jsxRuntime.jsx("stop",{offset:"100%",stopColor:"#00E676",stopOpacity:0})]}),jsxRuntime.jsxs("linearGradient",{id:"gradRed",x1:"0",y1:"0",x2:"0",y2:"1",children:[jsxRuntime.jsx("stop",{offset:"0%",stopColor:"#FF5252",stopOpacity:0}),jsxRuntime.jsx("stop",{offset:"100%",stopColor:"#FF5252",stopOpacity:.1})]})]}),jsxRuntime.jsx(recharts.XAxis,{dataKey:"timestamp",hide:true}),jsxRuntime.jsx(recharts.YAxis,{hide:true,domain:[c,h]}),a&&g&&jsxRuntime.jsx(recharts.ReferenceLine,{y:0,stroke:"rgba(255,255,255,0.06)",strokeDasharray:"4 4"}),jsxRuntime.jsx(recharts.Area,{type:"monotone",dataKey:n,stroke:a?T>=0?"#00E676":"#FF5252":"#C8FF00",strokeWidth:1.5,fill:a?T>=0?"url(#gradGreen)":"url(#gradRed)":"url(#gradAccent)",dot:false,isAnimationActive:false})]})})}),jsxRuntime.jsx("div",{className:"flex justify-between px-4 pb-2.5 pt-1",children:C.map(({ts:f,label:y})=>jsxRuntime.jsx("span",{className:"font-mono text-[9px] text-[#3A3A4E]",children:y},f))})]})}function Pt({label:e,active:t,onClick:o}){return jsxRuntime.jsx("button",{type:"button",className:ui.clsx("rounded px-2.5 py-1 text-[11px] font-medium transition-colors",t?"bg-[#1C1C26] text-foreground":"text-[#5C5C72] hover:text-[#A0A0B8]"),onClick:o,children:e})}function Ee({data:e,isLoading:t}){let o=e?.items??[],r=react.useMemo(()=>o.map(i=>({name:i.name,value:i.percent})),[o]);return jsxRuntime.jsxs("div",{className:"flex flex-col overflow-hidden rounded-lg border border-[#252530] bg-[#0F0F16]",children:[jsxRuntime.jsx("div",{className:"px-4 pb-2 pt-3",children:jsxRuntime.jsx("span",{className:"text-xs font-semibold text-[#A0A0B8]",children:"Distribution"})}),jsxRuntime.jsx("div",{className:"flex flex-1 items-center justify-center px-4",children:t||o.length===0?jsxRuntime.jsx("div",{className:"flex h-[140px] w-[140px] items-center justify-center",children:jsxRuntime.jsx("span",{className:"text-xs text-[#5C5C72]",children:t?"":"No data"})}):jsxRuntime.jsx(recharts.ResponsiveContainer,{width:140,height:140,children:jsxRuntime.jsx(recharts.PieChart,{children:jsxRuntime.jsx(recharts.Pie,{data:r,cx:"50%",cy:"50%",innerRadius:32,outerRadius:55,dataKey:"value",stroke:"none",isAnimationActive:false,children:o.map((i,p)=>jsxRuntime.jsx(recharts.Cell,{fill:i.color},p))})})})}),jsxRuntime.jsx("div",{className:"px-4 pb-3 pt-2",children:o.map((i,p)=>jsxRuntime.jsxs("div",{className:"flex items-center gap-1.5 py-[3px] text-[11px]",children:[jsxRuntime.jsx("span",{className:"h-[7px] w-[7px] flex-shrink-0 rounded-[2px]",style:{background:i.color}}),jsxRuntime.jsx("span",{className:"min-w-0 flex-1 truncate text-[#A0A0B8]",children:i.name}),jsxRuntime.jsxs("span",{className:"font-mono text-[10px] text-[#5C5C72]",children:[i.percent.toFixed(1),"%"]}),jsxRuntime.jsx("span",{className:"min-w-[55px] text-right font-mono text-[10px] text-foreground",children:S(i.value)})]},p))})]})}var re=react.createContext(null);var ne=react.createContext({}),fe=react.createContext({});function se(){let e=react.useContext(ne);if(!e)throw new Error("usePortfolioContext must be used within a PortfolioProvider");return e}function k(){let e=react.useContext(re);if(!e)throw new Error("usePortfolioClient must be used within a PortfolioClientProvider");return e}function vt(e){return ["portfolio","overview",e??{}]}async function co(e,t){return await e.getOverview(t)}function Qe(e,t={}){let o=k();return reactQuery.useQuery({queryKey:vt(e),queryFn:async()=>co(o,e),...t})}function Ct(e){return ["portfolio","spot","holdings",e??{}]}async function mo(e,t){return await e.getSpotHoldings(t)}function ie(e,t={}){let o=k();return reactQuery.useQuery({queryKey:Ct(e),queryFn:async()=>mo(o,e),...t})}function St(e){return ["portfolio","spot","history",e??{}]}async function xo(e,t){return await e.getSpotHistory(t)}function Re(e,t={}){let o=k();return reactQuery.useQuery({queryKey:St(e),queryFn:async()=>xo(o,e),...t})}function Nt(e){return ["portfolio","perps","positions",e??{}]}async function yo(e,t){return await e.getPerpsPositions(t)}function Ue(e,t={}){let o=k();return reactQuery.useQuery({queryKey:Nt(e),queryFn:async()=>yo(o,e),...t})}function wt(e){return ["portfolio","perps","history",e??{}]}async function bo(e,t){return await e.getPerpsHistory(t)}function Ie(e,t={}){let o=k();return reactQuery.useQuery({queryKey:wt(e),queryFn:async()=>bo(o,e),...t})}function At(e){return ["portfolio","prediction","active",e??{}]}async function vo(e,t){return await e.getPredictionBets(t)}function Oe(e,t={}){let o=k();return reactQuery.useQuery({queryKey:At(e),queryFn:async()=>vo(o,e),...t})}function kt(e){return ["portfolio","prediction","settled",e??{}]}async function So(e,t){return await e.getPredictionSettled(t)}function Be(e,t={}){let o=k();return reactQuery.useQuery({queryKey:kt(e),queryFn:async()=>So(o,e),...t})}function Tt(e){return ["portfolio","chart",e]}async function wo(e,t){return await e.getChartData(t)}function Le(e,t={}){let o=k();return reactQuery.useQuery({queryKey:Tt(e),queryFn:async()=>wo(o,e),...t})}function ko(){return ["portfolio","distribution"]}function We(e){return {data:react.useMemo(()=>st(e),[e])}}function To(){let{summary:e,summaryStatus:t}=se();return {data:e,...t}}function Fo(){let{refetchSummary:e}=se();return e}var Oo=15e3;function Ht(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}function Bo({chain:e,address:t,tokenAddresses:o,pollMs:r=Oo}){let i=!!t&&o.length>0,[p,s]=react.useState({}),n=react$1.useWalletPortfoliosByTokensQuery({chain:e,address:t,tokenAddresses:o},{enabled:i,refetchInterval:r}),a=react$1.useWalletPortfolioPnlsByTokensQuery({chain:e,address:t,tokenAddresses:o},{enabled:i,refetchInterval:r});react.useEffect(()=>{let T=n.data??[],f=new Map;if(a.data)for(let x of a.data)f.set(x.address,x);let y={};for(let x of T)y[x.address]={...x,pnl:f.get(x.address)??null};s(y);},[n.data,a.data]);let m=react.useRef(""),g=react.useRef(new Set),c=o.slice().sort().join(",");c!==m.current&&(m.current=c,g.current=new Set(o));let h=g.current;react$1.useWalletPortfoliosSubscription({chain:e,address:t},T=>{s(f=>{let y=f;for(let x of T){if(!h.has(x.tokenAddress))continue;let A=y[x.tokenAddress];if(!A)continue;let{chain:P,walletAddress:L,tokenAddress:_,...Q}=x,V=Ht(Q);Object.keys(V).length!==0&&(y=y===f?{...f}:y,y[x.tokenAddress]={...A,...V});}return y});},{enabled:i}),react$1.useWalletPortfolioPnlsSubscription({chain:e,address:t},T=>{s(f=>{let y=f;for(let x of T){if(!h.has(x.tokenAddress))continue;let A=y[x.tokenAddress];if(!A||!A.pnl)continue;let{walletAddress:P,tokenAddress:L,..._}=x,Q=Ht(_);Object.keys(Q).length!==0&&(y=y===f?{...f}:y,y[x.tokenAddress]={...A,pnl:{...A.pnl,...Q}});}return y});},{enabled:i});let C=react.useCallback(async()=>{await Promise.all([n.refetch(),a.refetch()]);},[n.refetch,a.refetch]);return {tokens:p,isPending:n.isPending,isFetching:n.isFetching||a.isFetching,isError:n.isError,isSuccess:n.isSuccess,error:n.error,refetch:C}}function Ve(e){let{defaultTab:t="spot",walletAddresses:o,chain:r}=e??{},[i,p]=react.useState(t),[s,n]=react.useState(void 0),[a,m]=react.useState(void 0),[g,c]=react.useState("networth"),[h,C]=react.useState("7D"),T=a!==void 0,f=react.useMemo(()=>{if(a)return {walletAddresses:[a],chain:r};if(o?.length)return {walletAddresses:o,chain:r}},[o,a,r]),y=Qe(f),x=ie(f),A=Le({period:pt[h],...f}),P=We(x.data?.holdings??[]),L=react.useMemo(()=>x.data?.holdings.reduce((I,ce)=>I+ce.value,0)??0,[x.data]),_=react.useCallback(I=>{m(I);},[]),Q=react.useCallback(()=>{m(void 0);},[]),V=react.useCallback(I=>{n(I);},[]);return {activeTab:i,setActiveTab:p,walletId:s,selectWallet:V,viewingAddress:a,isViewing:T,curveType:g,setCurveType:c,curvePeriod:h,setCurvePeriod:C,portfolioQuery:f,overviewQuery:y,curveQuery:A,distributionQuery:P,spotHoldingsQuery:x,spotValue:L,perpsValue:0,predictionValue:0,enterViewing:_,exitViewing:Q}}function Me(){return jsxRuntime.jsxs("div",{className:"mx-auto max-w-[1280px] px-6",children:[jsxRuntime.jsxs("div",{className:"flex gap-4 border-b border-[#252530] pb-0 pt-5",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-9 w-16 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-9 w-28 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-9 w-32 rounded-md"})]}),jsxRuntime.jsxs("div",{className:"flex items-center justify-between gap-4 py-4",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2.5",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-8 w-48 rounded-lg"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-6 rounded"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-5 w-14 rounded-[3px]"})]}),jsxRuntime.jsxs("div",{className:"flex items-center gap-1.5",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-[34px] w-[240px] rounded-lg"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-[34px] w-12 rounded-[5px]"})]})]}),jsxRuntime.jsxs("div",{className:"flex items-center gap-4 pb-4",children:[jsxRuntime.jsxs("div",{className:"flex items-baseline gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-8 w-48 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16 rounded"})]}),jsxRuntime.jsxs("div",{className:"ml-auto flex items-center gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-28 rounded"}),jsxRuntime.jsx("div",{className:"h-3.5 w-px bg-[#252530]"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-28 rounded"}),jsxRuntime.jsx("div",{className:"h-3.5 w-px bg-[#252530]"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-20 rounded"})]})]}),jsxRuntime.jsxs("div",{className:"grid grid-cols-[1fr_340px] gap-3 pb-4",children:[jsxRuntime.jsxs("div",{className:"rounded-lg border border-[#252530] bg-[#0F0F16] p-4",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between pb-4",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-7 w-40 rounded-[5px]"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-32 rounded"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-[180px] w-full rounded-md"}),jsxRuntime.jsx("div",{className:"mt-2 flex justify-between",children:Array.from({length:7}).map((e,t)=>jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-8 rounded"},t))})]}),jsxRuntime.jsxs("div",{className:"rounded-lg border border-[#252530] bg-[#0F0F16] p-4",children:[jsxRuntime.jsx(ui.Skeleton,{className:"mb-3 h-4 w-24 rounded"}),jsxRuntime.jsx("div",{className:"flex items-center justify-center py-4",children:jsxRuntime.jsx(ui.Skeleton,{className:"h-[140px] w-[140px] rounded-full"})}),jsxRuntime.jsx("div",{className:"space-y-1.5 pt-2",children:Array.from({length:5}).map((e,t)=>jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-full rounded"},t))})]})]}),jsxRuntime.jsxs("div",{className:"pb-6",children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between pb-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-8 w-40 rounded-[5px]"}),jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-7 w-40 rounded-[5px]"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-7 w-24 rounded-[5px]"})]})]}),jsxRuntime.jsx(ui.Skeleton,{className:"mb-3 h-5 w-full rounded"}),Array.from({length:5}).map((e,t)=>jsxRuntime.jsx(ui.Skeleton,{className:"mb-2 h-12 w-full rounded-[5px]"},t))]})]})}function Ke({viewingAddress:e,onBack:t}){return jsxRuntime.jsxs("div",{className:"flex items-center justify-between border-b border-[rgba(200,255,0,0.12)] bg-[rgba(200,255,0,0.06)] px-6 py-2",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsx("div",{className:"flex h-[18px] w-[18px] items-center justify-center rounded-full border border-[rgba(200,255,0,0.25)] bg-[rgba(200,255,0,0.07)]",children:jsxRuntime.jsxs("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:[jsxRuntime.jsx("path",{d:"M8 3C4.36 3 1.26 5.28 0 8.5c1.26 3.22 4.36 5.5 8 5.5s6.74-2.28 8-5.5C14.74 5.28 11.64 3 8 3z",stroke:"#C8FF00",strokeWidth:"1.3",fill:"none"}),jsxRuntime.jsx("circle",{cx:"8",cy:"8.5",r:"2.5",stroke:"#C8FF00",strokeWidth:"1.3",fill:"none"})]})}),jsxRuntime.jsx("span",{className:"text-xs font-medium text-[#C8FF00]",children:"Viewing external portfolio"}),jsxRuntime.jsx("span",{className:"ml-1 font-mono text-[11px] text-[#A0A0B8]",children:Z(e)})]}),jsxRuntime.jsxs("button",{type:"button",className:"flex items-center gap-1.5 rounded-[5px] border border-[#252530] bg-[#1C1C26] px-3 py-1.5 text-[11px] font-medium text-[#A0A0B8] transition-colors hover:border-[#C8FF00] hover:bg-[#C8FF00] hover:text-black",onClick:t,children:[jsxRuntime.jsx("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:jsxRuntime.jsx("path",{d:"M10 2L4 8l6 6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})}),"Back to My Portfolio"]})]})}function Lo({wallets:e=[],onCopyAddress:t,renderHoldings:o,isLoading:r,...i}){let p=Ve(i),{activeTab:s,setActiveTab:n,walletId:a,selectWallet:m,viewingAddress:g,isViewing:c,curveType:h,setCurveType:C,curvePeriod:T,setCurvePeriod:f,portfolioQuery:y,overviewQuery:x,curveQuery:A,distributionQuery:P,spotValue:L,perpsValue:_,predictionValue:Q,enterViewing:V,exitViewing:I}=p;return r||x.isLoading&&!x.data?jsxRuntime.jsx(Me,{}):jsxRuntime.jsxs("div",{children:[c&&g&&jsxRuntime.jsx(Ke,{viewingAddress:g,onBack:I}),jsxRuntime.jsxs("div",{className:"mx-auto max-w-[1280px] px-6",children:[jsxRuntime.jsx(Ae,{activeTab:s,onTabChange:n,spotValue:L,perpsValue:_,predictionValue:Q}),jsxRuntime.jsx(Se,{walletId:a,wallets:e,isViewing:c,viewingAddress:g,onSelectWallet:m,onCopyAddress:()=>{if(c&&g)t?.(g);else {let ue=e.find(ve=>ve.id===a);ue&&t?.(ue.address);}},onSearch:V}),jsxRuntime.jsx(Te,{overview:x.data}),jsxRuntime.jsxs("div",{className:"grid grid-cols-[1fr_340px] gap-3 pb-4",children:[jsxRuntime.jsx(He,{curveType:h,curvePeriod:T,data:A.data,isLoading:A.isLoading,onTypeChange:C,onPeriodChange:f}),jsxRuntime.jsx(Ee,{data:P.data,isLoading:false})]}),o?.({activeTab:s,portfolioQuery:y,isViewing:c})]})]})}function ge({open:e,title:t,message:o,confirmLabel:r,cancelLabel:i,onConfirm:p,onCancel:s}){return e?jsxRuntime.jsxs("div",{className:"fixed inset-0 z-50 flex items-center justify-center",children:[jsxRuntime.jsx("div",{className:"absolute inset-0 bg-black/60",onClick:s,onKeyDown:n=>{n.key==="Escape"&&s();},role:"button",tabIndex:-1,"aria-label":"Close dialog"}),jsxRuntime.jsxs("div",{className:"relative z-10 w-full max-w-sm rounded-xl border border-[#252530] bg-[#12121A] p-6 shadow-2xl",children:[jsxRuntime.jsx("h3",{className:"text-sm font-semibold text-foreground",children:t}),jsxRuntime.jsx("p",{className:"mt-2 text-xs leading-relaxed text-[#A0A0B8]",children:o}),jsxRuntime.jsxs("div",{className:"mt-5 flex items-center justify-end gap-2",children:[jsxRuntime.jsx("button",{type:"button",className:"rounded-lg px-4 py-2 text-xs font-medium text-[#5C5C72] transition-colors hover:bg-[#1C1C26] hover:text-foreground",onClick:s,children:i}),jsxRuntime.jsx("button",{type:"button",className:ui.clsx("rounded-lg border px-4 py-2 text-xs font-medium transition-colors","border-[rgba(255,82,82,0.25)] text-[#FF5252]","hover:border-[#FF5252] hover:bg-[rgba(255,82,82,0.1)]"),onClick:p,children:r})]})]})]}):null}function je({activeTab:e,portfolioQuery:t,isViewing:o}){let[r,i]=react.useState("holdings"),[p,s]=react.useState("positions"),[n,a]=react.useState("active"),[m,g]=react.useState(""),[c,h]=react.useState(""),[C,T]=react.useState(""),[f,y]=react.useState(false),[x,A]=react.useState(false),P=react.useCallback(()=>{A(M=>!M);},[]),L=ie(t,{enabled:e==="spot"}),_=Re(t,{enabled:e==="spot"&&r==="history"}),Q=Ue(t,{enabled:e==="perps"}),V=Ie(t,{enabled:e==="perps"&&p==="history"}),I=Oe(t,{enabled:e==="prediction"}),ce=Be(t,{enabled:e==="prediction"&&n==="settled"}),et=react.useMemo(()=>(L.data?.holdings??[]).filter(K=>{if(f&&K.value<1&&!K.verified)return false;if(m){let J=m.toLowerCase();return K.name.toLowerCase().includes(J)||K.symbol.toLowerCase().includes(J)}return true}),[L.data?.holdings,f,m]),ue=react.useMemo(()=>{let M=Q.data?.positions??[];if(!c)return M;let K=c.toLowerCase();return M.filter(J=>J.pair.toLowerCase().includes(K))},[Q.data?.positions,c]),ve=react.useMemo(()=>{let M=I.data?.bets??[];if(!C)return M;let K=C.toLowerCase();return M.filter(J=>J.market.toLowerCase().includes(K))},[I.data?.bets,C]);return {spotSubTab:r,setSpotSubTab:i,perpsSubTab:p,setPerpsSubTab:s,predictionSubTab:n,setPredictionSubTab:a,spotSearch:m,setSpotSearch:g,perpsSearch:c,setPerpsSearch:h,predictionSearch:C,setPredictionSearch:T,hideSmall:f,setHideSmall:y,groupCollapsed:x,toggleGroupCollapsed:P,spotHoldingsQuery:L,spotHistoryQuery:_,perpsPositionsQuery:Q,perpsHistoryQuery:V,predictionBetsQuery:I,predictionSettledQuery:ce,filteredSpotHoldings:et,filteredPerpsPositions:ue,filteredPredictionBets:ve,isViewing:o}}function G({tabs:e,activeKey:t,onTabChange:o}){return jsxRuntime.jsx("div",{className:"flex gap-0.5",children:e.map(r=>jsxRuntime.jsx("button",{type:"button",className:ui.clsx("rounded-[5px] px-3 py-1.5 text-xs font-medium transition-colors",t===r.key?"bg-[#1C1C26] text-foreground":"text-[#5C5C72] hover:bg-[#16161E] hover:text-[#A0A0B8]"),onClick:()=>o(r.key),children:r.label},r.key))})}function X({value:e,onChange:t,placeholder:o}){return jsxRuntime.jsxs("div",{className:"flex h-7 w-40 items-center gap-1 rounded-[5px] border border-[#252530] bg-[#16161E] px-2 transition-all focus-within:w-[200px] focus-within:border-[#C8FF00]",children:[jsxRuntime.jsxs("svg",{width:"11",height:"11",viewBox:"0 0 16 16",fill:"none",className:"flex-shrink-0 text-[#5C5C72]",children:[jsxRuntime.jsx("circle",{cx:"7",cy:"7",r:"5.5",stroke:"currentColor",strokeWidth:"1.5"}),jsxRuntime.jsx("path",{d:"M11 11L14.5 14.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]}),jsxRuntime.jsx("input",{type:"text",className:"flex-1 border-none bg-transparent font-mono text-[11px] text-foreground caret-[#C8FF00] outline-none placeholder:font-sans placeholder:text-[10px] placeholder:text-[#5C5C72]",placeholder:o,spellCheck:false,value:e,onChange:r=>t(r.target.value)})]})}function B({title:e,hint:t}){return jsxRuntime.jsxs("div",{className:"flex flex-col items-center justify-center py-16 text-center",children:[jsxRuntime.jsx("span",{className:"text-sm text-[#5C5C72]",children:e}),t&&jsxRuntime.jsx("span",{className:"mt-1 text-xs text-[#3A3A4E]",children:t})]})}function pe({label:e,disabled:t,onClick:o}){return jsxRuntime.jsxs("button",{type:"button",className:ui.clsx("flex items-center gap-1 whitespace-nowrap rounded-[5px] border px-3 py-1.5 text-[11px] font-medium transition-colors",t?"pointer-events-none border-[#252530] text-[#3A3A4E]":"border-[rgba(255,82,82,0.25)] text-[#FF5252] hover:border-[#FF5252] hover:bg-[rgba(255,82,82,0.1)]"),onClick:o,disabled:t,children:[jsxRuntime.jsx("svg",{width:"11",height:"11",viewBox:"0 0 16 16",fill:"none",children:jsxRuntime.jsx("path",{d:"M4 4l8 8M12 4l-8 8",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})}),e]})}function ze({state:e,onClosePosition:t,onCloseAll:o}){let{perpsSubTab:r,setPerpsSubTab:i,perpsSearch:p,setPerpsSearch:s,filteredPerpsPositions:n,perpsHistoryQuery:a,isViewing:m}=e,g=n.length>0;return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between pb-3",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(G,{tabs:[{key:"positions",label:"Open Positions"},{key:"history",label:"Trade History"}],activeKey:r,onTabChange:c=>i(c)}),r==="positions"&&!m&&jsxRuntime.jsx(pe,{label:"Close All",disabled:!g,onClick:()=>o?.()})]}),jsxRuntime.jsx(X,{value:p,onChange:s,placeholder:"Search pair\u2026"})]}),r==="positions"?jsxRuntime.jsx(Vo,{positions:n,isViewing:m,onClose:t}):jsxRuntime.jsx(Ko,{records:a.data?.records??[],isLoading:a.isLoading})]})}function Vo({positions:e,isViewing:t,onClose:o}){return e.length===0?jsxRuntime.jsx(B,{title:"No open positions",hint:"Start trading \u2192"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:t?"2fr 1fr .8fr .8fr 1fr":"2fr 1fr .8fr .8fr 1fr 80px"},children:[jsxRuntime.jsx("span",{children:"Pair / Side"}),jsxRuntime.jsx("span",{className:"text-right",children:"Size"}),jsxRuntime.jsx("span",{className:"text-right",children:"Entry"}),jsxRuntime.jsx("span",{className:"text-right",children:"Mark"}),jsxRuntime.jsx("span",{className:"text-right",children:"uPNL"}),!t&&jsxRuntime.jsx("span",{className:"text-right"})]}),jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(r=>jsxRuntime.jsx(Mo,{position:r,isViewing:t,onClose:o},r.id))})]})}function Mo({position:e,isViewing:t,onClose:o}){let r=e.side==="long",i=e.uPnl>=0;return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:t?"2fr 1fr .8fr .8fr 1fr":"2fr 1fr .8fr .8fr 1fr 80px"},children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[e.icon?jsxRuntime.jsx("img",{src:e.icon,alt:e.pair,className:"h-6 w-6 flex-shrink-0 rounded-full"}):jsxRuntime.jsx("div",{className:"flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-[#1C1C26] text-[9px] font-bold text-[#5C5C72]",children:e.pair.slice(0,2)}),jsxRuntime.jsxs("div",{className:"flex items-center gap-1.5",children:[jsxRuntime.jsx("span",{className:"text-xs font-medium text-foreground",children:e.pair}),jsxRuntime.jsx("span",{className:ui.clsx("rounded px-1.5 py-0.5 text-[10px] font-medium",r?"bg-[rgba(0,230,118,0.12)] text-[#00E676]":"bg-[rgba(255,82,82,0.12)] text-[#FF5252]"),children:r?"Long":"Short"}),jsxRuntime.jsxs("span",{className:"rounded bg-[rgba(200,255,0,0.1)] px-1.5 py-0.5 text-[10px] font-medium text-[#C8FF00]",children:[e.leverage,"\xD7"]})]})]}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:S(e.size)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#A0A0B8]",children:S(e.entryPrice)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#A0A0B8]",children:S(e.markPrice)}),jsxRuntime.jsx("span",{className:ui.clsx("text-right font-mono text-xs",i?"text-[#00E676]":"text-[#FF5252]"),children:te(e.uPnl)}),!t&&jsxRuntime.jsx("div",{className:"flex justify-end",children:jsxRuntime.jsx("button",{type:"button",className:"rounded-[5px] border border-[#252530] px-2.5 py-1 text-[10px] font-medium text-[#5C5C72] transition-colors hover:border-[#FF5252] hover:text-[#FF5252]",onClick:()=>o?.(e),children:"Close"})})]})}function Ko({records:e,isLoading:t}){return t?jsxRuntime.jsx("div",{className:"flex items-center justify-center py-16",children:jsxRuntime.jsx("div",{className:"h-5 w-5 animate-spin rounded-full border-2 border-[#C8FF00] border-t-transparent"})}):e.length===0?jsxRuntime.jsx(B,{title:"No trade history",hint:"Closed positions will appear here"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:"1.5fr 80px 1fr 1fr 1fr 100px"},children:[jsxRuntime.jsx("span",{children:"Pair"}),jsxRuntime.jsx("span",{children:"Side"}),jsxRuntime.jsx("span",{className:"text-right",children:"Size"}),jsxRuntime.jsx("span",{className:"text-right",children:"PNL"}),jsxRuntime.jsx("span",{className:"text-right",children:"Close Price"}),jsxRuntime.jsx("span",{className:"text-right",children:"Time"})]}),jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(o=>jsxRuntime.jsx(qo,{record:o},o.id))})]})}function qo({record:e}){let t=e.side==="long",o=e.pnl>=0;return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:"1.5fr 80px 1fr 1fr 1fr 100px"},children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[e.icon?jsxRuntime.jsx("img",{src:e.icon,alt:e.pair,className:"h-5 w-5 flex-shrink-0 rounded-full"}):jsxRuntime.jsx("div",{className:"flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-[#1C1C26] text-[8px] font-bold text-[#5C5C72]",children:e.pair.slice(0,2)}),jsxRuntime.jsx("span",{className:"text-xs font-medium text-foreground",children:e.pair})]}),jsxRuntime.jsx("span",{children:jsxRuntime.jsx("span",{className:ui.clsx("inline-block rounded px-1.5 py-0.5 text-[10px] font-medium",t?"bg-[rgba(0,230,118,0.12)] text-[#00E676]":"bg-[rgba(255,82,82,0.12)] text-[#FF5252]"),children:t?"Long":"Short"})}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:S(e.size)}),jsxRuntime.jsx("span",{className:ui.clsx("text-right font-mono text-xs",o?"text-[#00E676]":"text-[#FF5252]"),children:te(e.pnl)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#A0A0B8]",children:S(e.closePrice)}),jsxRuntime.jsx("span",{className:"text-right text-[11px] text-[#5C5C72]",children:e.time})]})}function Ge({state:e,onSellBet:t,onSellAll:o}){let{predictionSubTab:r,setPredictionSubTab:i,predictionSearch:p,setPredictionSearch:s,filteredPredictionBets:n,predictionSettledQuery:a,isViewing:m}=e,g=n.length>0;return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between pb-3",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(G,{tabs:[{key:"active",label:"Active Bets"},{key:"settled",label:"Settled"}],activeKey:r,onTabChange:c=>i(c)}),r==="active"&&!m&&jsxRuntime.jsx(pe,{label:"Sell All",disabled:!g,onClick:()=>o?.()})]}),jsxRuntime.jsx(X,{value:p,onChange:s,placeholder:"Search market\u2026"})]}),r==="active"?jsxRuntime.jsx(jo,{bets:n,isViewing:m,onSell:t}):jsxRuntime.jsx(Go,{records:a.data?.records??[],isLoading:a.isLoading})]})}var $o={polymarket:"bg-[rgba(0,102,255,0.12)] text-[#0066FF]",drift:"bg-[rgba(200,255,0,0.1)] text-[#C8FF00]",metadao:"bg-[rgba(255,107,157,0.1)] text-[#FF6B9D]"},Yo={polymarket:"Polymarket",drift:"Drift",metadao:"MetaDAO"};function Qt({source:e}){return jsxRuntime.jsx("span",{className:ui.clsx("inline-block rounded px-1.5 py-0.5 text-[10px] font-medium",$o[e]),children:Yo[e]})}function jo({bets:e,isViewing:t,onSell:o}){return e.length===0?jsxRuntime.jsx(B,{title:"No active bets",hint:"Explore prediction markets \u2192"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:t?"2.2fr .6fr .7fr .7fr .7fr":"2.2fr .6fr .7fr .7fr .7fr 80px"},children:[jsxRuntime.jsx("span",{children:"Market / Source"}),jsxRuntime.jsx("span",{className:"text-right",children:"Position"}),jsxRuntime.jsx("span",{className:"text-right",children:"Stake"}),jsxRuntime.jsx("span",{className:"text-right",children:"Potential"}),jsxRuntime.jsx("span",{className:"text-right",children:"Status"}),!t&&jsxRuntime.jsx("span",{className:"text-right"})]}),jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(r=>jsxRuntime.jsx(zo,{bet:r,isViewing:t,onSell:o},r.id))})]})}function zo({bet:e,isViewing:t,onSell:o}){return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:t?"2.2fr .6fr .7fr .7fr .7fr":"2.2fr .6fr .7fr .7fr .7fr 80px"},children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2 overflow-hidden",children:[e.icon?jsxRuntime.jsx("img",{src:e.icon,alt:e.market,className:"h-6 w-6 flex-shrink-0 rounded-full"}):jsxRuntime.jsx("div",{className:"flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-full bg-[#1C1C26] text-[9px] font-bold text-[#5C5C72]",children:"?"}),jsxRuntime.jsxs("div",{className:"flex flex-col overflow-hidden",children:[jsxRuntime.jsx("span",{className:"truncate text-xs font-medium text-foreground",children:e.market}),jsxRuntime.jsx(Qt,{source:e.source})]})]}),jsxRuntime.jsx("span",{className:ui.clsx("text-right text-xs font-medium",e.position==="Yes"?"text-[#00E676]":"text-[#FF5252]"),children:e.position}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:S(e.stake)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#00E676]",children:S(e.potential)}),jsxRuntime.jsx("span",{className:"text-right",children:jsxRuntime.jsx("span",{className:ui.clsx("inline-block rounded px-1.5 py-0.5 text-[10px] font-medium",e.status==="active"?"bg-[rgba(0,230,118,0.12)] text-[#00E676]":"bg-[rgba(200,255,0,0.1)] text-[#C8FF00]"),children:e.status==="active"?"Active":"Pending"})}),!t&&jsxRuntime.jsx("div",{className:"flex justify-end",children:jsxRuntime.jsx("button",{type:"button",className:"rounded-[5px] border border-[#252530] px-2.5 py-1 text-[10px] font-medium text-[#5C5C72] transition-colors hover:border-[#FF5252] hover:text-[#FF5252]",onClick:()=>o?.(e),children:"Sell"})})]})}function Go({records:e,isLoading:t}){return t?jsxRuntime.jsx("div",{className:"flex items-center justify-center py-16",children:jsxRuntime.jsx("div",{className:"h-5 w-5 animate-spin rounded-full border-2 border-[#C8FF00] border-t-transparent"})}):e.length===0?jsxRuntime.jsx(B,{title:"No settled bets",hint:"Settled predictions will appear here"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:"1.5fr .8fr .6fr .7fr .6fr .7fr"},children:[jsxRuntime.jsx("span",{children:"Market"}),jsxRuntime.jsx("span",{children:"Source"}),jsxRuntime.jsx("span",{className:"text-right",children:"Position"}),jsxRuntime.jsx("span",{className:"text-right",children:"Stake"}),jsxRuntime.jsx("span",{className:"text-right",children:"Result"}),jsxRuntime.jsx("span",{className:"text-right",children:"Payout"})]}),jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(o=>jsxRuntime.jsx(Xo,{record:o},o.id))})]})}function Xo({record:e}){let t=e.result==="won";return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:"1.5fr .8fr .6fr .7fr .6fr .7fr"},children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2 overflow-hidden",children:[e.icon?jsxRuntime.jsx("img",{src:e.icon,alt:e.market,className:"h-5 w-5 flex-shrink-0 rounded-full"}):jsxRuntime.jsx("div",{className:"flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full bg-[#1C1C26] text-[8px] font-bold text-[#5C5C72]",children:"?"}),jsxRuntime.jsx("span",{className:"truncate text-xs font-medium text-foreground",children:e.market})]}),jsxRuntime.jsx(Qt,{source:e.source}),jsxRuntime.jsx("span",{className:ui.clsx("text-right text-xs font-medium",e.position==="Yes"?"text-[#00E676]":"text-[#FF5252]"),children:e.position}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:S(e.stake)}),jsxRuntime.jsx("span",{className:"text-right",children:jsxRuntime.jsx("span",{className:ui.clsx("inline-block rounded px-1.5 py-0.5 text-[10px] font-medium",t?"bg-[rgba(0,230,118,0.12)] text-[#00E676]":"bg-[rgba(255,82,82,0.12)] text-[#FF5252]"),children:t?"Won":"Lost"})}),jsxRuntime.jsx("span",{className:ui.clsx("text-right font-mono text-xs",t?"text-[#00E676]":"text-[#5C5C72]"),children:t?`+${S(e.payout)}`:S(e.payout)})]})}function Je({state:e}){let{spotSubTab:t,setSpotSubTab:o,spotSearch:r,setSpotSearch:i,hideSmall:p,setHideSmall:s,groupCollapsed:n,toggleGroupCollapsed:a,filteredSpotHoldings:m,spotHistoryQuery:g}=e;return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"flex items-center justify-between pb-3",children:[jsxRuntime.jsx(G,{tabs:[{key:"holdings",label:"Holdings"},{key:"history",label:"History"}],activeKey:t,onTabChange:c=>o(c)}),jsxRuntime.jsxs("div",{className:"flex items-center gap-2",children:[jsxRuntime.jsx(X,{value:r,onChange:i,placeholder:"Search token\u2026"}),t==="holdings"&&jsxRuntime.jsxs("label",{className:"flex cursor-pointer items-center gap-1.5 text-[11px] text-[#5C5C72] select-none",children:[jsxRuntime.jsx("input",{type:"checkbox",className:"accent-[#C8FF00]",checked:p,onChange:c=>s(c.target.checked)}),"Hide small"]})]})]}),t==="holdings"?jsxRuntime.jsx(Jo,{holdings:m,groupCollapsed:n,onToggleGroup:a}):jsxRuntime.jsx(er,{records:g.data?.trades??[],isLoading:g.isLoading})]})}function Jo({holdings:e,groupCollapsed:t,onToggleGroup:o}){return e.length===0?jsxRuntime.jsx(B,{title:"No tokens found",hint:"Your spot tokens will appear here"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:"2fr 1fr 1fr 1fr 1fr"},children:[jsxRuntime.jsx("span",{children:"Asset"}),jsxRuntime.jsx("span",{className:"text-right",children:"Balance"}),jsxRuntime.jsx("span",{className:"text-right",children:"Price"}),jsxRuntime.jsx("span",{className:"text-right",children:"Value"}),jsxRuntime.jsx("span",{className:"text-right",children:"24h"})]}),jsxRuntime.jsxs("button",{type:"button",className:"flex w-full items-center gap-2 px-3 py-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72] transition-colors hover:text-[#A0A0B8]",onClick:o,children:[jsxRuntime.jsx("svg",{width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",className:ui.clsx("transition-transform",t&&"-rotate-90"),children:jsxRuntime.jsx("path",{d:"M4 6l4 4 4-4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})}),jsxRuntime.jsx("span",{children:"Tokens"}),jsxRuntime.jsx("span",{className:"text-[#3A3A4E]",children:e.length})]}),!t&&jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(r=>jsxRuntime.jsx(Zo,{holding:r},r.tokenAddress))})]})}function Zo({holding:e}){let t=e.change24h>=0;return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:"2fr 1fr 1fr 1fr 1fr"},children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-2.5 overflow-hidden",children:[e.image?jsxRuntime.jsx("img",{src:e.image,alt:e.symbol,className:"h-7 w-7 flex-shrink-0 rounded-full"}):jsxRuntime.jsx("div",{className:"flex h-7 w-7 flex-shrink-0 items-center justify-center rounded-full bg-[#1C1C26] text-[10px] font-bold text-[#5C5C72]",children:e.symbol.slice(0,2)}),jsxRuntime.jsxs("div",{className:"flex flex-col overflow-hidden",children:[jsxRuntime.jsx("span",{className:"truncate text-xs font-medium text-foreground",children:e.name}),jsxRuntime.jsx("span",{className:"text-[10px] text-[#5C5C72]",children:e.symbol})]})]}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:Ce(e.balance)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#A0A0B8]",children:S(e.price)}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-foreground",children:S(e.value)}),jsxRuntime.jsx("span",{className:ui.clsx("text-right font-mono text-xs",t?"text-[#00E676]":"text-[#FF5252]"),children:ot(e.change24h)})]})}function er({records:e,isLoading:t}){return t?jsxRuntime.jsx("div",{className:"flex items-center justify-center py-16",children:jsxRuntime.jsx("div",{className:"h-5 w-5 animate-spin rounded-full border-2 border-[#C8FF00] border-t-transparent"})}):e.length===0?jsxRuntime.jsx(B,{title:"No history found",hint:"Transaction history will appear here"}):jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("div",{className:"grid gap-2 px-3 pb-2 text-[10px] font-medium uppercase tracking-wider text-[#5C5C72]",style:{gridTemplateColumns:"80px 1.5fr 1fr 1fr 100px 80px"},children:[jsxRuntime.jsx("span",{children:"Type"}),jsxRuntime.jsx("span",{children:"Detail"}),jsxRuntime.jsx("span",{className:"text-right",children:"Amount"}),jsxRuntime.jsx("span",{className:"text-right",children:"Value"}),jsxRuntime.jsx("span",{className:"text-right",children:"Time"}),jsxRuntime.jsx("span",{className:"text-right",children:"TxHash"})]}),jsxRuntime.jsx("div",{className:"flex flex-col",children:e.map(o=>jsxRuntime.jsx(nr,{record:o},`${o.txHash}-${o.tokenAddress}`))})]})}var tr={swap:"bg-[rgba(139,123,255,0.12)] text-[#8B7BFF]",send:"bg-[rgba(255,82,82,0.12)] text-[#FF5252]",receive:"bg-[rgba(0,230,118,0.12)] text-[#00E676]"},or={swap:"Swap",send:"Send",receive:"Receive"};function rr(e){return e.type==="swap"&&e.sideTokenSymbol?`${e.tokenSymbol} \u2192 ${e.sideTokenSymbol}`:e.tokenName||e.tokenSymbol}function nr({record:e}){let t=nt(e.txHash,e.chain);return jsxRuntime.jsxs("div",{className:"grid items-center gap-2 rounded-[5px] px-3 py-2.5 transition-colors hover:bg-[#16161E]",style:{gridTemplateColumns:"80px 1.5fr 1fr 1fr 100px 80px"},children:[jsxRuntime.jsx("span",{children:jsxRuntime.jsx("span",{className:ui.clsx("inline-block rounded px-1.5 py-0.5 text-[10px] font-medium",tr[e.type]),children:or[e.type]})}),jsxRuntime.jsx("span",{className:"truncate text-xs text-foreground",children:rr(e)}),jsxRuntime.jsxs("span",{className:"text-right font-mono text-xs text-foreground",children:[Ce(e.tokenAmount)," ",e.tokenSymbol]}),jsxRuntime.jsx("span",{className:"text-right font-mono text-xs text-[#A0A0B8]",children:S(e.valueUsd)}),jsxRuntime.jsx("span",{className:"text-right text-[11px] text-[#5C5C72]",children:e.timestamp?it(e.timestamp):"\u2014"}),jsxRuntime.jsx("span",{className:"text-right",children:e.txHash?jsxRuntime.jsxs("a",{href:t,target:"_blank",rel:"noopener noreferrer",className:"font-mono text-[11px] text-[#5C5C72] transition-colors hover:text-[#C8FF00]",children:[e.txHash.slice(0,4),"\u2026",e.txHash.slice(-3)]}):jsxRuntime.jsx("span",{className:"font-mono text-[11px] text-[#3A3A4E]",children:"\u2014"})})]})}function ir({onClosePosition:e,onCloseAllPositions:t,onSellBet:o,onSellAllBets:r,...i}){let p=je(i),[s,n]=react.useState(null),a=react.useCallback(()=>{n("closeAll");},[]),m=react.useCallback(()=>{n("sellAll");},[]),g=react.useCallback(()=>{s==="closeAll"?t?.():s==="sellAll"&&r?.(),n(null);},[s,t,r]),c=react.useCallback(()=>{n(null);},[]);return jsxRuntime.jsxs("div",{className:"rounded-xl border border-[#1C1C26] bg-[#0E0E16] p-4",children:[(()=>{switch(i.activeTab){case "spot":return jsxRuntime.jsx(Je,{state:p});case "perps":return jsxRuntime.jsx(ze,{state:p,onClosePosition:e,onCloseAll:a});case "prediction":return jsxRuntime.jsx(Ge,{state:p,onSellBet:o,onSellAll:m});default:return null}})(),jsxRuntime.jsx(ge,{open:s==="closeAll",title:"Close All Positions",message:"Close all positions? This will route to each protocol to execute.",confirmLabel:"Confirm Close All",cancelLabel:"Cancel",onConfirm:g,onCancel:c}),jsxRuntime.jsx(ge,{open:s==="sellAll",title:"Sell All Positions",message:"Sell all positions? This will route to each platform to execute.",confirmLabel:"Confirm Sell All",cancelLabel:"Cancel",onConfirm:g,onCancel:c})]})}function lr({client:e,children:t}){return jsxRuntime.jsx(re.Provider,{value:e,children:t})}var xr=15e3;function gr(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}function Rt({chain:e,address:t,enabled:o=true,summaryPollMs:r=xr}){let{setSummary:i,setSummaryStatus:p,setRefetchSummary:s}=react.useContext(fe),n=react$1.useWalletPortfoliosQuery({chain:e,address:t},{enabled:o,refetchInterval:r}),a=react$1.useWalletPnlQuery({chain:e,address:t},{enabled:o,refetchInterval:r});react.useEffect(()=>{let g=n.isPending||a.isPending,c=n.isFetching||a.isFetching,h=n.isError||a.isError,C=n.isSuccess&&a.isSuccess;p({status:h?"error":C?"success":"pending",fetchStatus:c?"fetching":"idle",isLoading:g&&c,isPending:g,isFetching:c,isRefetching:C&&c,isError:h,isSuccess:C,error:n.error??a.error,dataUpdatedAt:Math.max(n.dataUpdatedAt,a.dataUpdatedAt)});},[n.isPending,n.isFetching,n.isError,n.isSuccess,n.error,n.dataUpdatedAt,a.isPending,a.isFetching,a.isError,a.isSuccess,a.error,a.dataUpdatedAt,p]),react.useEffect(()=>{let g=n.data,c=a.data;!g||!c||i({...c,balanceInUsd:g.balanceInUsd,balanceInNative:g.balanceInNative});},[n.data,a.data,i]),react$1.useWalletPnlSubscription({chain:e,address:t},g=>{i(c=>{if(!c)return c;let h=c;for(let C of g)h={...h,...gr(C)};return h});},{enabled:o});let m=react.useCallback(async()=>{await Promise.all([n.refetch(),a.refetch()]);},[n,a]);react.useEffect(()=>{s(m);},[m,s]);}function Pr({chain:e,address:t,children:o}){let[r,i]=react.useState(null),[p,s]=react.useState(hr),n=react.useRef(()=>Promise.resolve()),a=react.useCallback(()=>n.current(),[]),m=react.useCallback(h=>{n.current=h;},[]),g=react.useMemo(()=>({summary:r,summaryStatus:p,refetchSummary:a}),[r,p,a]),c=react.useMemo(()=>({setSummary:i,setSummaryStatus:s,setRefetchSummary:m}),[i,s,m]);return jsxRuntime.jsx(fe.Provider,{value:c,children:jsxRuntime.jsx(ne.Provider,{value:g,children:jsxRuntime.jsx(br,{chain:e,address:t,children:o})})})}function br({chain:e,address:t,children:o}){return Rt({chain:e,address:t,enabled:!!t}),jsxRuntime.jsx(jsxRuntime.Fragment,{children:o})}var hr={status:"pending",fetchStatus:"idle",isLoading:false,isPending:true,isFetching:false,isRefetching:false,isError:false,isSuccess:false,error:null,dataUpdatedAt:0};
|
|
2
2
|
exports.AddressRowUI=Se;exports.AssetTab=oe;exports.AssetTabsUI=Ae;exports.BalanceRowUI=Te;exports.BatchActionButton=pe;exports.CURVE_PERIOD_VALUE=pt;exports.ConfirmDialog=ge;exports.CurveCardUI=He;exports.CurvePeriod=we;exports.CurveType=Ne;exports.DistributionCardUI=Ee;exports.HoldingsEmpty=B;exports.HoldingsSearch=X;exports.HoldingsSectionWidget=ir;exports.HoldingsSubTabs=G;exports.PerpsPanelUI=ze;exports.PerpsPositionSide=dt;exports.PortfolioClientContext=re;exports.PortfolioClientProvider=lr;exports.PortfolioContext=ne;exports.PortfolioPageSkeleton=Me;exports.PortfolioPageWidget=Lo;exports.PortfolioProvider=Pr;exports.PredictionBetStatus=ut;exports.PredictionPanelUI=Ge;exports.PredictionResult=mt;exports.PredictionSource=ft;exports.SpotHistoryType=ct;exports.SpotPanelUI=Je;exports.ViewingBannerUI=Ke;exports.computeDistribution=st;exports.curveDataQueryKey=Tt;exports.distributionQueryKey=ko;exports.formatPercent=ot;exports.formatSignedUsd=te;exports.formatTime=it;exports.formatTokenBalance=Ce;exports.formatUsd=S;exports.getExplorerUrl=nt;exports.overviewQueryKey=vt;exports.parseDecimal=Sr;exports.perpsHistoryQueryKey=wt;exports.perpsPositionsQueryKey=Nt;exports.predictionBetsQueryKey=At;exports.predictionSettledQueryKey=kt;exports.splitUsd=rt;exports.spotHistoryQueryKey=St;exports.spotHoldingsQueryKey=Ct;exports.truncateAddress=Z;exports.useCurveDataQuery=Le;exports.useDistributionQuery=We;exports.useHoldingsSection=je;exports.useOverviewQuery=Qe;exports.usePerpsHistoryQuery=Ie;exports.usePerpsPositionsQuery=Ue;exports.usePortfolioClient=k;exports.usePortfolioContext=se;exports.usePortfolioPage=Ve;exports.usePredictionBetsQuery=Oe;exports.usePredictionSettledQuery=Be;exports.useRefetchWalletSummary=Fo;exports.useSpotHistoryQuery=Re;exports.useSpotHoldingsQuery=ie;exports.useWalletPortfolios=Bo;exports.useWalletSummary=To;exports.version=Bt;//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|