@elizaos/plugin-polymarket-app 2.0.3-beta.6 → 2.0.3-beta.7
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/PolymarketAppView.d.ts +3 -0
- package/dist/PolymarketAppView.d.ts.map +1 -0
- package/dist/PolymarketAppView.helpers.d.ts +10 -0
- package/dist/PolymarketAppView.helpers.d.ts.map +1 -0
- package/dist/PolymarketAppView.helpers.js +30 -0
- package/dist/PolymarketAppView.helpers.js.map +1 -0
- package/dist/PolymarketAppView.interact.d.ts +3 -0
- package/dist/PolymarketAppView.interact.d.ts.map +1 -0
- package/dist/PolymarketAppView.interact.js +70 -0
- package/dist/PolymarketAppView.interact.js.map +1 -0
- package/dist/PolymarketAppView.js +704 -0
- package/dist/PolymarketAppView.js.map +1 -0
- package/dist/PolymarketPositionsPanel.d.ts +13 -0
- package/dist/PolymarketPositionsPanel.d.ts.map +1 -0
- package/dist/PolymarketPositionsPanel.js +349 -0
- package/dist/PolymarketPositionsPanel.js.map +1 -0
- package/dist/PolymarketView.d.ts +13 -0
- package/dist/PolymarketView.d.ts.map +1 -0
- package/dist/PolymarketView.js +58 -0
- package/dist/PolymarketView.js.map +1 -0
- package/dist/__fixtures__/contract.d.ts +9 -0
- package/dist/__fixtures__/contract.d.ts.map +1 -0
- package/dist/__fixtures__/contract.js +263 -0
- package/dist/__fixtures__/contract.js.map +1 -0
- package/dist/actions.d.ts +39 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +661 -0
- package/dist/actions.js.map +1 -0
- package/dist/client.d.ts +25 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +42 -0
- package/dist/client.js.map +1 -0
- package/dist/components/PolymarketSpatialView.d.ts +34 -0
- package/dist/components/PolymarketSpatialView.d.ts.map +1 -0
- package/dist/components/PolymarketSpatialView.js +248 -0
- package/dist/components/PolymarketSpatialView.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/orderbook.d.ts +15 -0
- package/dist/orderbook.d.ts.map +1 -0
- package/dist/orderbook.js +45 -0
- package/dist/orderbook.js.map +1 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +108 -0
- package/dist/plugin.js.map +1 -0
- package/dist/polymarket-app.d.ts +4 -0
- package/dist/polymarket-app.d.ts.map +1 -0
- package/dist/polymarket-app.js +18 -0
- package/dist/polymarket-app.js.map +1 -0
- package/dist/polymarket-contracts.d.ts +162 -0
- package/dist/polymarket-contracts.d.ts.map +1 -0
- package/dist/polymarket-contracts.js +16 -0
- package/dist/polymarket-contracts.js.map +1 -0
- package/dist/polymarket-view-bundle.d.ts +3 -0
- package/dist/polymarket-view-bundle.d.ts.map +1 -0
- package/dist/polymarket-view-bundle.js +7 -0
- package/dist/polymarket-view-bundle.js.map +1 -0
- package/dist/provider-text.d.ts +5 -0
- package/dist/provider-text.d.ts.map +1 -0
- package/dist/provider-text.js +44 -0
- package/dist/provider-text.js.map +1 -0
- package/dist/provider.d.ts +3 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +21 -0
- package/dist/provider.js.map +1 -0
- package/dist/register-routes.d.ts +2 -0
- package/dist/register-routes.d.ts.map +1 -0
- package/dist/register-routes.js +6 -0
- package/dist/register-routes.js.map +1 -0
- package/dist/register-terminal-view.d.ts +15 -0
- package/dist/register-terminal-view.d.ts.map +1 -0
- package/dist/register-terminal-view.js +25 -0
- package/dist/register-terminal-view.js.map +1 -0
- package/dist/register.d.ts +2 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +17 -0
- package/dist/register.js.map +1 -0
- package/dist/routes.d.ts +7 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +455 -0
- package/dist/routes.js.map +1 -0
- package/dist/ui.d.ts +6 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +11 -0
- package/dist/ui.js.map +1 -0
- package/dist/usePolymarketState.d.ts +13 -0
- package/dist/usePolymarketState.d.ts.map +1 -0
- package/dist/usePolymarketState.js +59 -0
- package/dist/usePolymarketState.js.map +1 -0
- package/dist/views/bundle.js +535 -0
- package/dist/views/bundle.js.map +1 -0
- package/package.json +6 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/PolymarketAppView.tsx"],"sourcesContent":["import type { OverlayAppContext } from \"@elizaos/app-core\";\nimport { Button } from \"@elizaos/app-core\";\nimport { useAgentElement } from \"@elizaos/ui/agent-surface\";\nimport { ArrowLeft } from \"lucide-react\";\nimport { useEffect } from \"react\";\nimport { PolymarketPositionsPanel } from \"./PolymarketPositionsPanel.js\";\nimport type {\n PolymarketMarket,\n PolymarketStatusResponse,\n} from \"./polymarket-contracts.js\";\nimport { usePolymarketState } from \"./usePolymarketState.js\";\n\nconst ACCENT = \"var(--accent, #ff8a24)\";\nconst ACCENT_LIGHT = \"#ffb066\";\nconst ACCENT_SUBTLE = \"var(--accent-subtle, rgba(255,138,36,0.12))\";\nconst TXT = \"var(--txt, #111)\";\nconst MUTED = \"var(--muted, rgba(0,0,0,0.58))\";\nconst BORDER = \"var(--border, rgba(0,0,0,0.12))\";\nconst SURFACE = \"var(--surface, rgba(0,0,0,0.04))\";\n\nfunction priceToPercent(price: string | null): number | null {\n if (price == null) return null;\n const n = Number(price);\n if (!Number.isFinite(n)) return null;\n return Math.round(n * 100);\n}\n\nfunction shortNumber(value: string | null): string | null {\n if (value == null) return null;\n const n = Number(value);\n if (!Number.isFinite(n)) return value;\n if (n >= 1_000_000) return `$${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `$${(n / 1_000).toFixed(1)}K`;\n return `$${n.toFixed(0)}`;\n}\n\nexport function PolymarketAppView({ exitToApps, t }: OverlayAppContext) {\n const {\n status,\n markets,\n selectedMarket,\n setSelectedMarket,\n positions,\n loading,\n error,\n refresh,\n } = usePolymarketState();\n\n const selectedMarketId = selectedMarket?.id;\n\n // The view has no live subscription, so keep the market list fresh with a\n // quiet background poll instead of a manual Refresh button.\n useEffect(() => {\n const interval = setInterval(() => {\n void refresh();\n }, 20000);\n return () => clearInterval(interval);\n }, [refresh]);\n\n const backLabel = t(\"nav.back\", { defaultValue: \"Back\" });\n const back = useAgentElement<HTMLButtonElement>({\n id: \"action-back\",\n role: \"button\",\n label: backLabel,\n group: \"polymarket-nav\",\n description: \"Exit Polymarket and return to the apps list\",\n });\n\n const showEmpty = !loading && markets.length === 0;\n\n return (\n <div\n data-testid=\"polymarket-shell\"\n className=\"fixed inset-0 z-50 flex h-[100vh] flex-col overflow-hidden bg-bg supports-[height:100dvh]:h-[100dvh]\"\n >\n <style>\n {\n \"@keyframes pmShimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}\"\n }\n </style>\n <div className=\"flex shrink-0 items-center justify-between px-3 py-2\">\n <div className=\"flex min-w-0 items-center gap-3\">\n <Button\n ref={back.ref}\n {...back.agentProps}\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-9 w-9 shrink-0 text-muted hover:text-txt\"\n onClick={exitToApps}\n aria-label={backLabel}\n >\n <ArrowLeft className=\"h-4 w-4\" />\n </Button>\n <div\n className=\"min-w-0\"\n style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}\n >\n <PolymarketGlyph size={22} />\n <h1 className=\"truncate text-base font-semibold text-txt\">\n Polymarket\n </h1>\n </div>\n </div>\n </div>\n\n <div className=\"chat-native-scrollbar flex-1 overflow-y-auto px-3 py-3 sm:px-5\">\n <div className=\"mx-auto flex max-w-3xl flex-col gap-3\">\n {selectedMarket ? (\n <MarketDetail\n market={selectedMarket}\n onBack={() => setSelectedMarket(null)}\n />\n ) : showEmpty ? (\n <DisconnectedState status={status} error={error} />\n ) : (\n <section\n style={{ display: \"flex\", flexDirection: \"column\", gap: 12 }}\n >\n <ReadinessStrip status={status} />\n {status?.account?.ready ? (\n <PolymarketPositionsPanel\n positions={positions?.positions ?? []}\n summary={positions?.summary ?? null}\n blockedReason={status.account?.reason ?? null}\n />\n ) : null}\n {loading && markets.length === 0 ? (\n <div style={{ display: \"grid\", gap: 10 }}>\n {[0, 1, 2, 3].map((i) => (\n <MarketSkeleton key={i} />\n ))}\n </div>\n ) : (\n <div style={{ display: \"grid\", gap: 10 }}>\n {markets.slice(0, 24).map((market) => (\n <MarketCard\n key={market.id}\n market={market}\n active={selectedMarketId === market.id}\n onSelect={setSelectedMarket}\n />\n ))}\n </div>\n )}\n </section>\n )}\n </div>\n </div>\n </div>\n );\n}\n\nfunction PolymarketGlyph({ size = 28 }: { size?: number }) {\n return (\n <svg\n width={size}\n height={size}\n viewBox=\"0 0 32 32\"\n role=\"img\"\n aria-hidden=\"true\"\n style={{ display: \"block\" }}\n >\n <title>Polymarket</title>\n <defs>\n <linearGradient id=\"pmYes\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\">\n <stop offset=\"0%\" stopColor={ACCENT} />\n <stop offset=\"100%\" stopColor={ACCENT_LIGHT} />\n </linearGradient>\n </defs>\n <circle\n cx=\"16\"\n cy=\"16\"\n r=\"15\"\n fill=\"none\"\n stroke={BORDER}\n strokeWidth=\"2\"\n />\n <path\n d=\"M16 1 A15 15 0 0 1 31 16 L16 16 Z\"\n fill=\"url(#pmYes)\"\n opacity=\"0.85\"\n />\n <circle cx=\"16\" cy=\"16\" r=\"6\" fill=\"var(--bg, #fff)\" />\n <circle cx=\"16\" cy=\"16\" r=\"2.5\" fill={ACCENT} />\n </svg>\n );\n}\n\nfunction StateDot({ ready }: { ready: boolean }) {\n return (\n <span\n style={{\n width: 8,\n height: 8,\n borderRadius: 99,\n background: ready ? ACCENT : MUTED,\n boxShadow: ready ? `0 0 0 3px ${ACCENT_SUBTLE}` : \"none\",\n flexShrink: 0,\n }}\n />\n );\n}\n\nfunction CapabilityChip({\n label,\n ready,\n hint,\n}: {\n label: string;\n ready: boolean;\n hint: string;\n}) {\n return (\n <div\n title={hint}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 7,\n padding: \"4px 2px\",\n fontSize: 13,\n fontWeight: 600,\n color: TXT,\n }}\n >\n <StateDot ready={ready} />\n {label}\n <span style={{ color: MUTED, fontWeight: 500, fontSize: 12 }}>\n {ready ? \"on\" : \"off\"}\n </span>\n </div>\n );\n}\n\nfunction ReadinessStrip({\n status,\n}: {\n status: PolymarketStatusResponse | null;\n}) {\n const reads = status?.publicReads.ready ?? false;\n const trading = status?.trading.ready ?? false;\n return (\n <div\n style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: 8,\n alignItems: \"center\",\n }}\n >\n <CapabilityChip\n label=\"Read-only\"\n ready={reads}\n hint=\"Public market data (no credentials needed)\"\n />\n <CapabilityChip\n label=\"Trading\"\n ready={trading}\n hint={status?.trading.reason ?? \"Signed order placement\"}\n />\n </div>\n );\n}\n\nfunction DisconnectedState({\n status,\n error,\n}: {\n status: PolymarketStatusResponse | null;\n error: string | null;\n}) {\n const reads = status?.publicReads.ready ?? false;\n const trading = status?.trading.ready ?? false;\n return (\n <section\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n textAlign: \"center\",\n gap: 16,\n padding: \"48px 20px\",\n margin: \"auto 0\",\n }}\n >\n <div>\n <PolymarketGlyph size={52} />\n </div>\n <div style={{ maxWidth: 360 }}>\n <h2\n title={error ? \"Markets unavailable\" : \"None\"}\n style={{\n margin: 0,\n fontSize: 19,\n fontWeight: 700,\n color: TXT,\n }}\n >\n {error ? \"Unavailable\" : \"None\"}\n </h2>\n {error ? (\n <p\n className=\"sr-only\"\n style={{\n margin: \"8px 0 0\",\n fontSize: 14,\n color: MUTED,\n lineHeight: 1.5,\n }}\n >\n Couldn't reach Polymarket right now. Try again in a moment.\n </p>\n ) : null}\n </div>\n <div\n style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n gap: 8,\n justifyContent: \"center\",\n }}\n >\n <CapabilityChip\n label=\"Read-only\"\n ready={reads}\n hint=\"Public market data (no credentials needed)\"\n />\n <CapabilityChip\n label=\"Trading\"\n ready={trading}\n hint={status?.trading.reason ?? \"Signed order placement\"}\n />\n </div>\n {!trading && status?.trading.missing.length ? (\n <p\n className=\"sr-only\"\n style={{\n margin: 0,\n fontSize: 12,\n color: MUTED,\n maxWidth: 360,\n }}\n >\n To enable trading, configure{\" \"}\n <code style={{ fontSize: 11, color: MUTED }}>\n {status.trading.missing.join(\", \")}\n </code>{\" \"}\n in Settings.\n </p>\n ) : null}\n </section>\n );\n}\n\nfunction MarketSkeleton() {\n return (\n <div\n style={{\n height: 66,\n background: `linear-gradient(90deg, ${SURFACE} 0%, var(--bg-hover, rgba(0,0,0,0.06)) 50%, ${SURFACE} 100%)`,\n backgroundSize: \"200% 100%\",\n animation: \"pmShimmer 1.4s ease-in-out infinite\",\n }}\n />\n );\n}\n\nfunction OutcomeChip({\n name,\n percent,\n rank,\n}: {\n name: string;\n percent: number | null;\n rank: number;\n}) {\n const lead = rank === 0;\n return (\n <div\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n padding: \"2px 0\",\n fontSize: 12.5,\n fontWeight: 600,\n color: TXT,\n maxWidth: \"100%\",\n }}\n >\n <span\n style={{\n maxWidth: 130,\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {name}\n </span>\n {percent != null ? (\n <span\n style={{\n color: lead ? ACCENT : MUTED,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {percent}%\n </span>\n ) : null}\n </div>\n );\n}\n\nfunction MarketCard({\n market,\n active,\n onSelect,\n}: {\n market: PolymarketMarket;\n active: boolean;\n onSelect: (market: PolymarketMarket) => void;\n}) {\n const label = market.question ?? market.slug ?? market.id;\n const { ref, agentProps } = useAgentElement<HTMLButtonElement>({\n id: `market-${market.id}`,\n role: \"list-item\",\n label,\n group: \"polymarket-markets\",\n status: active ? \"active\" : \"inactive\",\n description: `Select the ${label} market`,\n });\n const volume = shortNumber(market.volume24hr ?? market.volume);\n const liquidity = shortNumber(market.liquidity);\n const outcomes = market.outcomes.slice(0, 3);\n return (\n <button\n ref={ref}\n {...agentProps}\n type=\"button\"\n onClick={() => onSelect(market)}\n aria-current={active ? \"true\" : undefined}\n style={{\n display: \"flex\",\n gap: 12,\n width: \"100%\",\n textAlign: \"left\",\n padding: \"10px 4px\",\n border: \"none\",\n borderLeft: active ? `2px solid ${ACCENT}` : \"2px solid transparent\",\n background: \"transparent\",\n cursor: \"pointer\",\n font: \"inherit\",\n color: TXT,\n alignItems: \"flex-start\",\n }}\n >\n <span\n style={{\n width: 40,\n height: 40,\n flexShrink: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n overflow: \"hidden\",\n }}\n >\n {market.icon || market.image ? (\n <img\n src={market.icon ?? market.image ?? \"\"}\n alt=\"\"\n style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }}\n />\n ) : (\n <PolymarketGlyph size={24} />\n )}\n </span>\n <span\n style={{\n minWidth: 0,\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 8,\n }}\n >\n <span\n style={{\n fontSize: 14,\n fontWeight: 600,\n lineHeight: 1.35,\n color: TXT,\n display: \"-webkit-box\",\n WebkitLineClamp: 2,\n WebkitBoxOrient: \"vertical\",\n overflow: \"hidden\",\n }}\n >\n {label}\n </span>\n <span style={{ display: \"flex\", flexWrap: \"wrap\", gap: 6 }}>\n {outcomes.map((outcome, i) => (\n <OutcomeChip\n key={outcome.name}\n name={outcome.name}\n percent={priceToPercent(outcome.price)}\n rank={i}\n />\n ))}\n </span>\n <span style={{ display: \"flex\", gap: 14, fontSize: 12, color: MUTED }}>\n {volume ? <span>Vol {volume}</span> : null}\n {liquidity ? <span>Liq {liquidity}</span> : null}\n {market.category ? <span>{market.category}</span> : null}\n </span>\n </span>\n </button>\n );\n}\n\nfunction MarketDetail({\n market,\n onBack,\n}: {\n market: PolymarketMarket;\n onBack: () => void;\n}) {\n return (\n <section style={{ minWidth: 0 }}>\n <button\n type=\"button\"\n onClick={onBack}\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 6,\n marginBottom: 16,\n background: \"transparent\",\n border: \"none\",\n font: \"inherit\",\n fontSize: 12.5,\n fontWeight: 600,\n color: MUTED,\n cursor: \"pointer\",\n }}\n >\n <ArrowLeft style={{ width: 14, height: 14 }} />\n Markets\n </button>\n <div style={{ display: \"flex\", alignItems: \"flex-start\", gap: 12 }}>\n <span\n style={{\n width: 44,\n height: 44,\n flexShrink: 0,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n overflow: \"hidden\",\n }}\n >\n {market.icon || market.image ? (\n <img\n src={market.icon ?? market.image ?? \"\"}\n alt=\"\"\n style={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }}\n />\n ) : (\n <PolymarketGlyph size={26} />\n )}\n </span>\n <h2\n style={{\n margin: 0,\n fontSize: 19,\n fontWeight: 700,\n lineHeight: 1.3,\n color: TXT,\n }}\n >\n {market.question ?? market.slug}\n </h2>\n </div>\n\n <div\n style={{ display: \"flex\", gap: 24, marginTop: 18, flexWrap: \"wrap\" }}\n >\n <Metric label=\"Volume\" value={shortNumber(market.volume) ?? \"—\"} />\n <Metric\n label=\"Liquidity\"\n value={shortNumber(market.liquidity) ?? \"—\"}\n />\n <Metric\n label=\"Last trade\"\n value={\n priceToPercent(market.lastTradePrice) != null\n ? `${priceToPercent(market.lastTradePrice)}%`\n : \"—\"\n }\n />\n </div>\n\n <div style={{ marginTop: 24 }}>\n <div\n style={{\n paddingBottom: 4,\n fontSize: 12,\n fontWeight: 600,\n color: MUTED,\n }}\n >\n Outcomes\n </div>\n {market.outcomes.map((outcome, i) => {\n const pct = priceToPercent(outcome.price);\n return (\n <div\n key={outcome.name}\n style={{\n padding: \"11px 0\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n }}\n >\n <div\n style={{\n display: \"flex\",\n justifyContent: \"space-between\",\n gap: 12,\n fontSize: 13.5,\n }}\n >\n <span style={{ fontWeight: 600, color: TXT }}>\n {outcome.name}\n </span>\n <span\n style={{ fontWeight: 700, color: i === 0 ? ACCENT : MUTED }}\n >\n {pct != null ? `${pct}%` : \"n/a\"}\n </span>\n </div>\n {pct != null ? (\n <div\n style={{\n height: 6,\n background: SURFACE,\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n width: `${pct}%`,\n height: \"100%\",\n background: i === 0 ? ACCENT : MUTED,\n }}\n />\n </div>\n ) : null}\n </div>\n );\n })}\n </div>\n </section>\n );\n}\n\nfunction Metric({ label, value }: { label: string; value: string }) {\n return (\n <div style={{ flex: \"1 1 90px\", minWidth: 90 }}>\n <div style={{ fontSize: 11.5, color: MUTED }}>{label}</div>\n <div\n style={{\n marginTop: 4,\n fontSize: 15,\n fontWeight: 700,\n color: TXT,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {value}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PolymarketPosition, PolymarketPositionsSummary } from "./polymarket-contracts";
|
|
2
|
+
export interface PolymarketPositionsPanelProps {
|
|
3
|
+
positions: readonly PolymarketPosition[];
|
|
4
|
+
summary: PolymarketPositionsSummary | null;
|
|
5
|
+
/** Account-read blocked reason (e.g. no wallet configured). Null when ready. */
|
|
6
|
+
blockedReason?: string | null;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The live positions + PnL surface. Renders the account-health hero strip and a
|
|
10
|
+
* dense per-position table, or an honest empty/blocked state. Display only.
|
|
11
|
+
*/
|
|
12
|
+
export declare function PolymarketPositionsPanel({ positions, summary, blockedReason, }: PolymarketPositionsPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=PolymarketPositionsPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PolymarketPositionsPanel.d.ts","sourceRoot":"","sources":["../src/PolymarketPositionsPanel.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EACV,kBAAkB,EAClB,0BAA0B,EAC3B,MAAM,wBAAwB,CAAC;AAoRhC,MAAM,WAAW,6BAA6B;IAC5C,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACzC,OAAO,EAAE,0BAA0B,GAAG,IAAI,CAAC;IAC3C,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,EACvC,SAAS,EACT,OAAO,EACP,aAAoB,GACrB,EAAE,6BAA6B,2CAiF/B"}
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { TrendingDown, TrendingUp } from "lucide-react";
|
|
3
|
+
const ACCENT = "var(--accent, #ff8a24)";
|
|
4
|
+
const TXT = "var(--txt, #111)";
|
|
5
|
+
const MUTED = "var(--muted, rgba(0,0,0,0.58))";
|
|
6
|
+
const BORDER = "var(--border, rgba(0,0,0,0.12))";
|
|
7
|
+
const SURFACE = "var(--surface, rgba(0,0,0,0.04))";
|
|
8
|
+
const OK = "var(--ok, #22c55e)";
|
|
9
|
+
const DANGER = "var(--danger, #ef4444)";
|
|
10
|
+
const EMPTY_CELL = "\u2014";
|
|
11
|
+
function parseNumber(value) {
|
|
12
|
+
if (value === null) return null;
|
|
13
|
+
const parsed = Number(value);
|
|
14
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
15
|
+
}
|
|
16
|
+
function formatUsd(value, options = {}) {
|
|
17
|
+
if (value === null) return EMPTY_CELL;
|
|
18
|
+
const sign = options.withSign && value > 0 ? "+" : value < 0 ? "-" : "";
|
|
19
|
+
const abs = Math.abs(value);
|
|
20
|
+
if (abs >= 1e6) return `${sign}$${(abs / 1e6).toFixed(2)}M`;
|
|
21
|
+
if (abs >= 1e3) return `${sign}$${(abs / 1e3).toFixed(1)}K`;
|
|
22
|
+
return `${sign}$${abs.toFixed(2)}`;
|
|
23
|
+
}
|
|
24
|
+
function formatShares(value) {
|
|
25
|
+
const parsed = parseNumber(value);
|
|
26
|
+
if (parsed === null) return EMPTY_CELL;
|
|
27
|
+
return Math.abs(parsed).toLocaleString("en-US", {
|
|
28
|
+
maximumFractionDigits: 2,
|
|
29
|
+
minimumFractionDigits: 0
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function formatPercent(value) {
|
|
33
|
+
if (value === null) return EMPTY_CELL;
|
|
34
|
+
const sign = value > 0 ? "+" : "";
|
|
35
|
+
return `${sign}${(value * 100).toFixed(1)}%`;
|
|
36
|
+
}
|
|
37
|
+
function pnlColor(value) {
|
|
38
|
+
if (value === null || value === 0) return MUTED;
|
|
39
|
+
return value > 0 ? OK : DANGER;
|
|
40
|
+
}
|
|
41
|
+
function OutcomePill({ outcome }) {
|
|
42
|
+
const label = outcome ?? "\u2014";
|
|
43
|
+
const normalized = label.trim().toLowerCase();
|
|
44
|
+
const isYes = normalized === "yes";
|
|
45
|
+
const isNo = normalized === "no";
|
|
46
|
+
const color = isYes ? ACCENT : isNo ? MUTED : TXT;
|
|
47
|
+
const background = isYes ? "var(--accent-subtle, rgba(255,138,36,0.14))" : SURFACE;
|
|
48
|
+
return /* @__PURE__ */ jsx(
|
|
49
|
+
"span",
|
|
50
|
+
{
|
|
51
|
+
style: {
|
|
52
|
+
display: "inline-flex",
|
|
53
|
+
alignItems: "center",
|
|
54
|
+
padding: "2px 8px",
|
|
55
|
+
borderRadius: 99,
|
|
56
|
+
border: `1px solid ${isYes ? "var(--accent-subtle, rgba(255,138,36,0.3))" : BORDER}`,
|
|
57
|
+
background,
|
|
58
|
+
fontSize: 11,
|
|
59
|
+
fontWeight: 700,
|
|
60
|
+
textTransform: "uppercase",
|
|
61
|
+
letterSpacing: "0.02em",
|
|
62
|
+
color,
|
|
63
|
+
flexShrink: 0
|
|
64
|
+
},
|
|
65
|
+
children: label
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
function StatTile({
|
|
70
|
+
label,
|
|
71
|
+
value,
|
|
72
|
+
color = TXT
|
|
73
|
+
}) {
|
|
74
|
+
return /* @__PURE__ */ jsxs(
|
|
75
|
+
"div",
|
|
76
|
+
{
|
|
77
|
+
style: {
|
|
78
|
+
flex: "1 1 90px",
|
|
79
|
+
minWidth: 90,
|
|
80
|
+
borderRadius: 12,
|
|
81
|
+
border: `1px solid ${BORDER}`,
|
|
82
|
+
background: SURFACE,
|
|
83
|
+
padding: "10px 12px"
|
|
84
|
+
},
|
|
85
|
+
children: [
|
|
86
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: 11.5, color: MUTED }, children: label }),
|
|
87
|
+
/* @__PURE__ */ jsx(
|
|
88
|
+
"div",
|
|
89
|
+
{
|
|
90
|
+
style: {
|
|
91
|
+
marginTop: 4,
|
|
92
|
+
fontSize: 16,
|
|
93
|
+
fontWeight: 700,
|
|
94
|
+
color,
|
|
95
|
+
fontVariantNumeric: "tabular-nums"
|
|
96
|
+
},
|
|
97
|
+
children: value
|
|
98
|
+
}
|
|
99
|
+
)
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
function AccountHealthStrip({
|
|
105
|
+
summary
|
|
106
|
+
}) {
|
|
107
|
+
const totalValue = parseNumber(summary?.totalValue ?? null);
|
|
108
|
+
const totalPnl = parseNumber(summary?.totalCashPnl ?? null);
|
|
109
|
+
const totalPercent = parseNumber(summary?.totalPercentPnl ?? null);
|
|
110
|
+
const openPositions = summary?.openPositions ?? 0;
|
|
111
|
+
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
|
|
112
|
+
/* @__PURE__ */ jsx(StatTile, { label: "Portfolio", value: formatUsd(totalValue) }),
|
|
113
|
+
/* @__PURE__ */ jsx(
|
|
114
|
+
StatTile,
|
|
115
|
+
{
|
|
116
|
+
label: "Total PnL",
|
|
117
|
+
value: formatUsd(totalPnl, { withSign: true }),
|
|
118
|
+
color: pnlColor(totalPnl)
|
|
119
|
+
}
|
|
120
|
+
),
|
|
121
|
+
/* @__PURE__ */ jsx(
|
|
122
|
+
StatTile,
|
|
123
|
+
{
|
|
124
|
+
label: "Return",
|
|
125
|
+
value: formatPercent(totalPercent),
|
|
126
|
+
color: pnlColor(totalPercent)
|
|
127
|
+
}
|
|
128
|
+
),
|
|
129
|
+
/* @__PURE__ */ jsx(StatTile, { label: "Open", value: String(openPositions) })
|
|
130
|
+
] });
|
|
131
|
+
}
|
|
132
|
+
function PositionRow({ position }) {
|
|
133
|
+
const label = position.question ?? position.slug ?? position.marketId ?? "\u2014";
|
|
134
|
+
const value = parseNumber(position.currentValue);
|
|
135
|
+
const cashPnl = parseNumber(position.cashPnl);
|
|
136
|
+
const percentPnl = parseNumber(position.percentPnl);
|
|
137
|
+
return /* @__PURE__ */ jsxs(
|
|
138
|
+
"div",
|
|
139
|
+
{
|
|
140
|
+
style: {
|
|
141
|
+
display: "grid",
|
|
142
|
+
gridTemplateColumns: "minmax(0, 1.6fr) minmax(0, 0.8fr) minmax(0, 0.8fr) minmax(0, 1fr)",
|
|
143
|
+
gap: 10,
|
|
144
|
+
alignItems: "center",
|
|
145
|
+
padding: "11px 14px",
|
|
146
|
+
borderTop: `1px solid ${BORDER}`
|
|
147
|
+
},
|
|
148
|
+
children: [
|
|
149
|
+
/* @__PURE__ */ jsxs(
|
|
150
|
+
"div",
|
|
151
|
+
{
|
|
152
|
+
style: {
|
|
153
|
+
display: "flex",
|
|
154
|
+
flexDirection: "column",
|
|
155
|
+
gap: 5,
|
|
156
|
+
minWidth: 0
|
|
157
|
+
},
|
|
158
|
+
children: [
|
|
159
|
+
/* @__PURE__ */ jsx(
|
|
160
|
+
"span",
|
|
161
|
+
{
|
|
162
|
+
style: {
|
|
163
|
+
fontSize: 13,
|
|
164
|
+
fontWeight: 600,
|
|
165
|
+
color: TXT,
|
|
166
|
+
lineHeight: 1.3,
|
|
167
|
+
display: "-webkit-box",
|
|
168
|
+
WebkitLineClamp: 2,
|
|
169
|
+
WebkitBoxOrient: "vertical",
|
|
170
|
+
overflow: "hidden"
|
|
171
|
+
},
|
|
172
|
+
children: label
|
|
173
|
+
}
|
|
174
|
+
),
|
|
175
|
+
/* @__PURE__ */ jsx(OutcomePill, { outcome: position.outcome })
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
),
|
|
179
|
+
/* @__PURE__ */ jsx(
|
|
180
|
+
"span",
|
|
181
|
+
{
|
|
182
|
+
style: {
|
|
183
|
+
textAlign: "right",
|
|
184
|
+
fontSize: 12.5,
|
|
185
|
+
color: MUTED,
|
|
186
|
+
fontVariantNumeric: "tabular-nums"
|
|
187
|
+
},
|
|
188
|
+
children: formatShares(position.size)
|
|
189
|
+
}
|
|
190
|
+
),
|
|
191
|
+
/* @__PURE__ */ jsx(
|
|
192
|
+
"span",
|
|
193
|
+
{
|
|
194
|
+
style: {
|
|
195
|
+
textAlign: "right",
|
|
196
|
+
fontSize: 12.5,
|
|
197
|
+
color: TXT,
|
|
198
|
+
fontVariantNumeric: "tabular-nums"
|
|
199
|
+
},
|
|
200
|
+
children: formatUsd(value)
|
|
201
|
+
}
|
|
202
|
+
),
|
|
203
|
+
/* @__PURE__ */ jsxs(
|
|
204
|
+
"div",
|
|
205
|
+
{
|
|
206
|
+
style: {
|
|
207
|
+
display: "flex",
|
|
208
|
+
flexDirection: "column",
|
|
209
|
+
alignItems: "flex-end",
|
|
210
|
+
lineHeight: 1.25
|
|
211
|
+
},
|
|
212
|
+
children: [
|
|
213
|
+
/* @__PURE__ */ jsx(
|
|
214
|
+
"span",
|
|
215
|
+
{
|
|
216
|
+
style: {
|
|
217
|
+
fontSize: 12.5,
|
|
218
|
+
fontWeight: 700,
|
|
219
|
+
color: pnlColor(cashPnl),
|
|
220
|
+
fontVariantNumeric: "tabular-nums"
|
|
221
|
+
},
|
|
222
|
+
children: formatUsd(cashPnl, { withSign: true })
|
|
223
|
+
}
|
|
224
|
+
),
|
|
225
|
+
percentPnl !== null ? /* @__PURE__ */ jsx(
|
|
226
|
+
"span",
|
|
227
|
+
{
|
|
228
|
+
style: {
|
|
229
|
+
fontSize: 11,
|
|
230
|
+
color: pnlColor(percentPnl),
|
|
231
|
+
fontVariantNumeric: "tabular-nums"
|
|
232
|
+
},
|
|
233
|
+
children: formatPercent(percentPnl)
|
|
234
|
+
}
|
|
235
|
+
) : null
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
)
|
|
239
|
+
]
|
|
240
|
+
}
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
function HeaderRow() {
|
|
244
|
+
const cellStyle = {
|
|
245
|
+
fontSize: 10.5,
|
|
246
|
+
fontWeight: 600,
|
|
247
|
+
textTransform: "uppercase",
|
|
248
|
+
letterSpacing: "0.04em",
|
|
249
|
+
color: MUTED
|
|
250
|
+
};
|
|
251
|
+
return /* @__PURE__ */ jsxs(
|
|
252
|
+
"div",
|
|
253
|
+
{
|
|
254
|
+
style: {
|
|
255
|
+
display: "grid",
|
|
256
|
+
gridTemplateColumns: "minmax(0, 1.6fr) minmax(0, 0.8fr) minmax(0, 0.8fr) minmax(0, 1fr)",
|
|
257
|
+
gap: 10,
|
|
258
|
+
padding: "9px 14px",
|
|
259
|
+
borderBottom: `1px solid ${BORDER}`
|
|
260
|
+
},
|
|
261
|
+
children: [
|
|
262
|
+
/* @__PURE__ */ jsx("span", { style: cellStyle, children: "Market / Outcome" }),
|
|
263
|
+
/* @__PURE__ */ jsx("span", { style: { ...cellStyle, textAlign: "right" }, children: "Shares" }),
|
|
264
|
+
/* @__PURE__ */ jsx("span", { style: { ...cellStyle, textAlign: "right" }, children: "Value" }),
|
|
265
|
+
/* @__PURE__ */ jsx("span", { style: { ...cellStyle, textAlign: "right" }, children: "PnL" })
|
|
266
|
+
]
|
|
267
|
+
}
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
function PolymarketPositionsPanel({
|
|
271
|
+
positions,
|
|
272
|
+
summary,
|
|
273
|
+
blockedReason = null
|
|
274
|
+
}) {
|
|
275
|
+
const openPositions = positions.filter((position) => {
|
|
276
|
+
const size = parseNumber(position.size);
|
|
277
|
+
return size !== null && Math.abs(size) > 1e-9;
|
|
278
|
+
});
|
|
279
|
+
const totalPnl = parseNumber(summary?.totalCashPnl ?? null);
|
|
280
|
+
return /* @__PURE__ */ jsxs("section", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: [
|
|
281
|
+
/* @__PURE__ */ jsx(AccountHealthStrip, { summary }),
|
|
282
|
+
/* @__PURE__ */ jsxs(
|
|
283
|
+
"div",
|
|
284
|
+
{
|
|
285
|
+
style: {
|
|
286
|
+
borderRadius: 16,
|
|
287
|
+
border: `1px solid ${BORDER}`,
|
|
288
|
+
background: "var(--card, #fff)",
|
|
289
|
+
overflow: "hidden"
|
|
290
|
+
},
|
|
291
|
+
children: [
|
|
292
|
+
/* @__PURE__ */ jsxs(
|
|
293
|
+
"div",
|
|
294
|
+
{
|
|
295
|
+
style: {
|
|
296
|
+
display: "flex",
|
|
297
|
+
alignItems: "center",
|
|
298
|
+
gap: 8,
|
|
299
|
+
padding: "11px 14px",
|
|
300
|
+
borderBottom: blockedReason || openPositions.length === 0 ? "none" : `1px solid ${BORDER}`
|
|
301
|
+
},
|
|
302
|
+
children: [
|
|
303
|
+
totalPnl !== null && totalPnl < 0 ? /* @__PURE__ */ jsx(TrendingDown, { style: { width: 16, height: 16, color: DANGER } }) : /* @__PURE__ */ jsx(TrendingUp, { style: { width: 16, height: 16, color: MUTED } }),
|
|
304
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 13, fontWeight: 600, color: TXT }, children: "Positions" }),
|
|
305
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: MUTED }, children: openPositions.length })
|
|
306
|
+
]
|
|
307
|
+
}
|
|
308
|
+
),
|
|
309
|
+
blockedReason ? /* @__PURE__ */ jsx(
|
|
310
|
+
"div",
|
|
311
|
+
{
|
|
312
|
+
style: {
|
|
313
|
+
padding: "22px 16px",
|
|
314
|
+
textAlign: "center",
|
|
315
|
+
fontSize: 12.5,
|
|
316
|
+
color: MUTED
|
|
317
|
+
},
|
|
318
|
+
children: blockedReason
|
|
319
|
+
}
|
|
320
|
+
) : openPositions.length === 0 ? /* @__PURE__ */ jsx(
|
|
321
|
+
"div",
|
|
322
|
+
{
|
|
323
|
+
style: {
|
|
324
|
+
padding: "26px 16px",
|
|
325
|
+
textAlign: "center",
|
|
326
|
+
fontSize: 12.5,
|
|
327
|
+
color: MUTED
|
|
328
|
+
},
|
|
329
|
+
children: "None"
|
|
330
|
+
}
|
|
331
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
332
|
+
/* @__PURE__ */ jsx(HeaderRow, {}),
|
|
333
|
+
openPositions.map((position) => /* @__PURE__ */ jsx(
|
|
334
|
+
PositionRow,
|
|
335
|
+
{
|
|
336
|
+
position
|
|
337
|
+
},
|
|
338
|
+
`${position.conditionId ?? position.marketId ?? position.slug}-${position.outcome}`
|
|
339
|
+
))
|
|
340
|
+
] })
|
|
341
|
+
]
|
|
342
|
+
}
|
|
343
|
+
)
|
|
344
|
+
] });
|
|
345
|
+
}
|
|
346
|
+
export {
|
|
347
|
+
PolymarketPositionsPanel
|
|
348
|
+
};
|
|
349
|
+
//# sourceMappingURL=PolymarketPositionsPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/PolymarketPositionsPanel.tsx"],"sourcesContent":["// Live Polymarket positions + PnL surface for the native AppView.\n//\n// Phase 2 of moving a waifu agent's surfaces into its own ElizaOS web UI: this\n// is the prediction-market analogue of the sibling plugin-hyperliquid-app\n// HyperliquidPositionsPanel. The existing PolymarketAppView fetches rich\n// market data but never surfaced the agent's OWN positions — the `/positions`\n// route returns market question, outcome (YES/NO), shares, current value, and\n// cash/percent PnL, yet only a count ever reached the view (and only in the\n// TUI). This panel renders that data: an account-health hero strip (portfolio\n// value, total PnL, open count) over a dense per-position table (market /\n// outcome / shares / value / unrealized PnL). Read-only — no trade execution\n// lives here.\n//\n// Visual language matches PolymarketAppView exactly: that view styles with\n// inline CSS-variable theme tokens (--accent, --txt, --muted, --border,\n// --surface, --ok) rather than Tailwind utility classes, so this panel uses the\n// same tokens to stay visually consistent with the surrounding markets list.\n// The single non-neutral accents are profit-green and loss-red, mirroring the\n// HL panel's one-green-one-red discipline.\n\nimport { TrendingDown, TrendingUp } from \"lucide-react\";\nimport type {\n PolymarketPosition,\n PolymarketPositionsSummary,\n} from \"./polymarket-contracts.js\";\n\nconst ACCENT = \"var(--accent, #ff8a24)\";\nconst TXT = \"var(--txt, #111)\";\nconst MUTED = \"var(--muted, rgba(0,0,0,0.58))\";\nconst BORDER = \"var(--border, rgba(0,0,0,0.12))\";\nconst SURFACE = \"var(--surface, rgba(0,0,0,0.04))\";\nconst OK = \"var(--ok, #22c55e)\";\nconst DANGER = \"var(--danger, #ef4444)\";\n\nconst EMPTY_CELL = \"—\";\n\nfunction parseNumber(value: string | null): number | null {\n if (value === null) return null;\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nfunction formatUsd(\n value: number | null,\n options: { withSign?: boolean } = {},\n): string {\n if (value === null) return EMPTY_CELL;\n const sign = options.withSign && value > 0 ? \"+\" : value < 0 ? \"-\" : \"\";\n const abs = Math.abs(value);\n if (abs >= 1_000_000) return `${sign}$${(abs / 1_000_000).toFixed(2)}M`;\n if (abs >= 1_000) return `${sign}$${(abs / 1_000).toFixed(1)}K`;\n return `${sign}$${abs.toFixed(2)}`;\n}\n\nfunction formatShares(value: string | null): string {\n const parsed = parseNumber(value);\n if (parsed === null) return EMPTY_CELL;\n return Math.abs(parsed).toLocaleString(\"en-US\", {\n maximumFractionDigits: 2,\n minimumFractionDigits: 0,\n });\n}\n\nfunction formatPercent(value: number | null): string {\n if (value === null) return EMPTY_CELL;\n const sign = value > 0 ? \"+\" : \"\";\n return `${sign}${(value * 100).toFixed(1)}%`;\n}\n\nfunction pnlColor(value: number | null): string {\n if (value === null || value === 0) return MUTED;\n return value > 0 ? OK : DANGER;\n}\n\n/**\n * The YES/NO (or named) outcome pill. Binary YES leans accent, NO leans muted;\n * any other outcome name renders neutral. Mirrors the OutcomeChip language in\n * PolymarketAppView without importing it (that one is market-list specific).\n */\nfunction OutcomePill({ outcome }: { outcome: string | null }) {\n const label = outcome ?? \"—\";\n const normalized = label.trim().toLowerCase();\n const isYes = normalized === \"yes\";\n const isNo = normalized === \"no\";\n const color = isYes ? ACCENT : isNo ? MUTED : TXT;\n const background = isYes\n ? \"var(--accent-subtle, rgba(255,138,36,0.14))\"\n : SURFACE;\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n padding: \"2px 8px\",\n borderRadius: 99,\n border: `1px solid ${isYes ? \"var(--accent-subtle, rgba(255,138,36,0.3))\" : BORDER}`,\n background,\n fontSize: 11,\n fontWeight: 700,\n textTransform: \"uppercase\",\n letterSpacing: \"0.02em\",\n color,\n flexShrink: 0,\n }}\n >\n {label}\n </span>\n );\n}\n\nfunction StatTile({\n label,\n value,\n color = TXT,\n}: {\n label: string;\n value: string;\n color?: string;\n}) {\n return (\n <div\n style={{\n flex: \"1 1 90px\",\n minWidth: 90,\n borderRadius: 12,\n border: `1px solid ${BORDER}`,\n background: SURFACE,\n padding: \"10px 12px\",\n }}\n >\n <div style={{ fontSize: 11.5, color: MUTED }}>{label}</div>\n <div\n style={{\n marginTop: 4,\n fontSize: 16,\n fontWeight: 700,\n color,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {value}\n </div>\n </div>\n );\n}\n\nfunction AccountHealthStrip({\n summary,\n}: {\n summary: PolymarketPositionsSummary | null;\n}) {\n const totalValue = parseNumber(summary?.totalValue ?? null);\n const totalPnl = parseNumber(summary?.totalCashPnl ?? null);\n const totalPercent = parseNumber(summary?.totalPercentPnl ?? null);\n const openPositions = summary?.openPositions ?? 0;\n\n return (\n <div style={{ display: \"flex\", gap: 8, flexWrap: \"wrap\" }}>\n <StatTile label=\"Portfolio\" value={formatUsd(totalValue)} />\n <StatTile\n label=\"Total PnL\"\n value={formatUsd(totalPnl, { withSign: true })}\n color={pnlColor(totalPnl)}\n />\n <StatTile\n label=\"Return\"\n value={formatPercent(totalPercent)}\n color={pnlColor(totalPercent)}\n />\n <StatTile label=\"Open\" value={String(openPositions)} />\n </div>\n );\n}\n\nfunction PositionRow({ position }: { position: PolymarketPosition }) {\n const label = position.question ?? position.slug ?? position.marketId ?? \"—\";\n const value = parseNumber(position.currentValue);\n const cashPnl = parseNumber(position.cashPnl);\n const percentPnl = parseNumber(position.percentPnl);\n\n return (\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns:\n \"minmax(0, 1.6fr) minmax(0, 0.8fr) minmax(0, 0.8fr) minmax(0, 1fr)\",\n gap: 10,\n alignItems: \"center\",\n padding: \"11px 14px\",\n borderTop: `1px solid ${BORDER}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: 5,\n minWidth: 0,\n }}\n >\n <span\n style={{\n fontSize: 13,\n fontWeight: 600,\n color: TXT,\n lineHeight: 1.3,\n display: \"-webkit-box\",\n WebkitLineClamp: 2,\n WebkitBoxOrient: \"vertical\",\n overflow: \"hidden\",\n }}\n >\n {label}\n </span>\n <OutcomePill outcome={position.outcome} />\n </div>\n\n <span\n style={{\n textAlign: \"right\",\n fontSize: 12.5,\n color: MUTED,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {formatShares(position.size)}\n </span>\n\n <span\n style={{\n textAlign: \"right\",\n fontSize: 12.5,\n color: TXT,\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {formatUsd(value)}\n </span>\n\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"flex-end\",\n lineHeight: 1.25,\n }}\n >\n <span\n style={{\n fontSize: 12.5,\n fontWeight: 700,\n color: pnlColor(cashPnl),\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {formatUsd(cashPnl, { withSign: true })}\n </span>\n {percentPnl !== null ? (\n <span\n style={{\n fontSize: 11,\n color: pnlColor(percentPnl),\n fontVariantNumeric: \"tabular-nums\",\n }}\n >\n {formatPercent(percentPnl)}\n </span>\n ) : null}\n </div>\n </div>\n );\n}\n\nfunction HeaderRow() {\n const cellStyle: React.CSSProperties = {\n fontSize: 10.5,\n fontWeight: 600,\n textTransform: \"uppercase\",\n letterSpacing: \"0.04em\",\n color: MUTED,\n };\n return (\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns:\n \"minmax(0, 1.6fr) minmax(0, 0.8fr) minmax(0, 0.8fr) minmax(0, 1fr)\",\n gap: 10,\n padding: \"9px 14px\",\n borderBottom: `1px solid ${BORDER}`,\n }}\n >\n <span style={cellStyle}>Market / Outcome</span>\n <span style={{ ...cellStyle, textAlign: \"right\" }}>Shares</span>\n <span style={{ ...cellStyle, textAlign: \"right\" }}>Value</span>\n <span style={{ ...cellStyle, textAlign: \"right\" }}>PnL</span>\n </div>\n );\n}\n\nexport interface PolymarketPositionsPanelProps {\n positions: readonly PolymarketPosition[];\n summary: PolymarketPositionsSummary | null;\n /** Account-read blocked reason (e.g. no wallet configured). Null when ready. */\n blockedReason?: string | null;\n}\n\n/**\n * The live positions + PnL surface. Renders the account-health hero strip and a\n * dense per-position table, or an honest empty/blocked state. Display only.\n */\nexport function PolymarketPositionsPanel({\n positions,\n summary,\n blockedReason = null,\n}: PolymarketPositionsPanelProps) {\n // Show only positions that still hold shares — closed/dust rows are noise.\n const openPositions = positions.filter((position) => {\n const size = parseNumber(position.size);\n return size !== null && Math.abs(size) > 1e-9;\n });\n const totalPnl = parseNumber(summary?.totalCashPnl ?? null);\n\n return (\n <section style={{ display: \"flex\", flexDirection: \"column\", gap: 12 }}>\n <AccountHealthStrip summary={summary} />\n\n <div\n style={{\n borderRadius: 16,\n border: `1px solid ${BORDER}`,\n background: \"var(--card, #fff)\",\n overflow: \"hidden\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: 8,\n padding: \"11px 14px\",\n borderBottom:\n blockedReason || openPositions.length === 0\n ? \"none\"\n : `1px solid ${BORDER}`,\n }}\n >\n {totalPnl !== null && totalPnl < 0 ? (\n <TrendingDown style={{ width: 16, height: 16, color: DANGER }} />\n ) : (\n <TrendingUp style={{ width: 16, height: 16, color: MUTED }} />\n )}\n <span style={{ fontSize: 13, fontWeight: 600, color: TXT }}>\n Positions\n </span>\n <span style={{ fontSize: 12, color: MUTED }}>\n {openPositions.length}\n </span>\n </div>\n\n {blockedReason ? (\n <div\n style={{\n padding: \"22px 16px\",\n textAlign: \"center\",\n fontSize: 12.5,\n color: MUTED,\n }}\n >\n {blockedReason}\n </div>\n ) : openPositions.length === 0 ? (\n <div\n style={{\n padding: \"26px 16px\",\n textAlign: \"center\",\n fontSize: 12.5,\n color: MUTED,\n }}\n >\n None\n </div>\n ) : (\n <>\n <HeaderRow />\n {openPositions.map((position) => (\n <PositionRow\n key={`${position.conditionId ?? position.marketId ?? position.slug}-${position.outcome}`}\n position={position}\n />\n ))}\n </>\n )}\n </div>\n </section>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PolymarketView — the single GUI/XR data wrapper for the Polymarket surface.
|
|
3
|
+
*
|
|
4
|
+
* It owns the live data (status + markets + the agent's own positions, plus a
|
|
5
|
+
* quiet background poll) and renders the one presentational
|
|
6
|
+
* {@link PolymarketSpatialView} inside a {@link SpatialSurface}. Omitting the
|
|
7
|
+
* `modality` prop lets `SpatialSurface` auto-detect GUI vs XR via
|
|
8
|
+
* `window.__elizaXRContext`, so the SAME component serves both surfaces. The
|
|
9
|
+
* TUI surface renders the same `PolymarketSpatialView` through the terminal
|
|
10
|
+
* registry (see `register-terminal-view.tsx`).
|
|
11
|
+
*/
|
|
12
|
+
export declare function PolymarketView(): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=PolymarketView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PolymarketView.d.ts","sourceRoot":"","sources":["../src/PolymarketView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,wBAAgB,cAAc,4CAwD7B"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { SpatialSurface } from "@elizaos/ui/spatial";
|
|
3
|
+
import { useCallback, useEffect } from "react";
|
|
4
|
+
import {
|
|
5
|
+
PolymarketSpatialView
|
|
6
|
+
} from "./components/PolymarketSpatialView.js";
|
|
7
|
+
import { usePolymarketState } from "./usePolymarketState.js";
|
|
8
|
+
function PolymarketView() {
|
|
9
|
+
const {
|
|
10
|
+
status,
|
|
11
|
+
markets,
|
|
12
|
+
selectedMarket,
|
|
13
|
+
setSelectedMarket,
|
|
14
|
+
positions,
|
|
15
|
+
loading,
|
|
16
|
+
error,
|
|
17
|
+
refresh
|
|
18
|
+
} = usePolymarketState();
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const interval = setInterval(() => {
|
|
21
|
+
void refresh();
|
|
22
|
+
}, 2e4);
|
|
23
|
+
return () => clearInterval(interval);
|
|
24
|
+
}, [refresh]);
|
|
25
|
+
const onAction = useCallback(
|
|
26
|
+
(action) => {
|
|
27
|
+
if (action.startsWith("market:")) {
|
|
28
|
+
const id = action.slice("market:".length);
|
|
29
|
+
const next = markets.find((market) => market.id === id) ?? null;
|
|
30
|
+
setSelectedMarket(next);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
switch (action) {
|
|
34
|
+
case "detail-back":
|
|
35
|
+
setSelectedMarket(null);
|
|
36
|
+
return;
|
|
37
|
+
case "refresh":
|
|
38
|
+
void refresh();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
[markets, refresh, setSelectedMarket]
|
|
43
|
+
);
|
|
44
|
+
const snapshot = {
|
|
45
|
+
status,
|
|
46
|
+
markets,
|
|
47
|
+
selectedMarket,
|
|
48
|
+
positions: positions?.positions ?? [],
|
|
49
|
+
positionsSummary: positions?.summary ?? null,
|
|
50
|
+
loading,
|
|
51
|
+
error
|
|
52
|
+
};
|
|
53
|
+
return /* @__PURE__ */ jsx(SpatialSurface, { children: /* @__PURE__ */ jsx(PolymarketSpatialView, { snapshot, onAction }) });
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
PolymarketView
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=PolymarketView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/PolymarketView.tsx"],"sourcesContent":["/**\n * PolymarketView — the single GUI/XR data wrapper for the Polymarket surface.\n *\n * It owns the live data (status + markets + the agent's own positions, plus a\n * quiet background poll) and renders the one presentational\n * {@link PolymarketSpatialView} inside a {@link SpatialSurface}. Omitting the\n * `modality` prop lets `SpatialSurface` auto-detect GUI vs XR via\n * `window.__elizaXRContext`, so the SAME component serves both surfaces. The\n * TUI surface renders the same `PolymarketSpatialView` through the terminal\n * registry (see `register-terminal-view.tsx`).\n */\n\nimport { SpatialSurface } from \"@elizaos/ui/spatial\";\nimport { useCallback, useEffect } from \"react\";\nimport {\n type PolymarketSnapshot,\n PolymarketSpatialView,\n} from \"./components/PolymarketSpatialView.js\";\nimport { usePolymarketState } from \"./usePolymarketState.js\";\n\nexport function PolymarketView() {\n const {\n status,\n markets,\n selectedMarket,\n setSelectedMarket,\n positions,\n loading,\n error,\n refresh,\n } = usePolymarketState();\n\n // The view has no live subscription, so keep the market list fresh with a\n // quiet background poll. Torn down on unmount.\n useEffect(() => {\n const interval = setInterval(() => {\n void refresh();\n }, 20000);\n return () => clearInterval(interval);\n }, [refresh]);\n\n const onAction = useCallback(\n (action: string) => {\n if (action.startsWith(\"market:\")) {\n const id = action.slice(\"market:\".length);\n const next = markets.find((market) => market.id === id) ?? null;\n setSelectedMarket(next);\n return;\n }\n switch (action) {\n case \"detail-back\":\n setSelectedMarket(null);\n return;\n case \"refresh\":\n void refresh();\n return;\n }\n },\n [markets, refresh, setSelectedMarket],\n );\n\n const snapshot: PolymarketSnapshot = {\n status,\n markets,\n selectedMarket,\n positions: positions?.positions ?? [],\n positionsSummary: positions?.summary ?? null,\n loading,\n error,\n };\n\n return (\n <SpatialSurface>\n <PolymarketSpatialView snapshot={snapshot} onAction={onAction} />\n </SpatialSurface>\n );\n}\n"],"mappings":"AAyEM;AA7DN,SAAS,sBAAsB;AAC/B,SAAS,aAAa,iBAAiB;AACvC;AAAA,EAEE;AAAA,OACK;AACP,SAAS,0BAA0B;AAE5B,SAAS,iBAAiB;AAC/B,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,mBAAmB;AAIvB,YAAU,MAAM;AACd,UAAM,WAAW,YAAY,MAAM;AACjC,WAAK,QAAQ;AAAA,IACf,GAAG,GAAK;AACR,WAAO,MAAM,cAAc,QAAQ;AAAA,EACrC,GAAG,CAAC,OAAO,CAAC;AAEZ,QAAM,WAAW;AAAA,IACf,CAAC,WAAmB;AAClB,UAAI,OAAO,WAAW,SAAS,GAAG;AAChC,cAAM,KAAK,OAAO,MAAM,UAAU,MAAM;AACxC,cAAM,OAAO,QAAQ,KAAK,CAAC,WAAW,OAAO,OAAO,EAAE,KAAK;AAC3D,0BAAkB,IAAI;AACtB;AAAA,MACF;AACA,cAAQ,QAAQ;AAAA,QACd,KAAK;AACH,4BAAkB,IAAI;AACtB;AAAA,QACF,KAAK;AACH,eAAK,QAAQ;AACb;AAAA,MACJ;AAAA,IACF;AAAA,IACA,CAAC,SAAS,SAAS,iBAAiB;AAAA,EACtC;AAEA,QAAM,WAA+B;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,WAAW,aAAa,CAAC;AAAA,IACpC,kBAAkB,WAAW,WAAW;AAAA,IACxC;AAAA,IACA;AAAA,EACF;AAEA,SACE,oBAAC,kBACC,8BAAC,yBAAsB,UAAoB,UAAoB,GACjE;AAEJ;","names":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type Violations = string[];
|
|
2
|
+
export declare function validateMarket(market: unknown, path?: string): Violations;
|
|
3
|
+
export declare function validateMarketsResponse(value: unknown): Violations;
|
|
4
|
+
export declare function validateMarketResponse(value: unknown): Violations;
|
|
5
|
+
export declare function validateOrderbookResponse(value: unknown): Violations;
|
|
6
|
+
export declare function validateStatusResponse(value: unknown): Violations;
|
|
7
|
+
export declare function validatePositionsResponse(value: unknown): Violations;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/__fixtures__/contract.ts"],"names":[],"mappings":"AAuBA,KAAK,UAAU,GAAG,MAAM,EAAE,CAAC;AA8C3B,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,SAAW,GAAG,UAAU,CAwD3E;AAoBD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAalE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CASjE;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAuCpE;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAiCjE;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAqDpE"}
|