@medialane/ui 0.255.0 → 0.257.0

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.
@@ -76,12 +76,12 @@ const KINDS = {
76
76
  pop: { namePrefix: "POP", accents: import_asset_accents.ASSET_ACCENTS.standard, market: false, remix: false }
77
77
  };
78
78
  const PUBLICATION_TYPES = /* @__PURE__ */ new Set(["publications", "posts"]);
79
+ function traitText(attributes, trait) {
80
+ const value = attributes.find((a) => a.trait_type === trait)?.value;
81
+ return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
82
+ }
79
83
  function publicationAuthor(attributes, metadataAuthor) {
80
- const text = (trait) => {
81
- const value = attributes.find((a) => a.trait_type === trait)?.value;
82
- return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
83
- };
84
- return text("Author") ?? metadataAuthor ?? text("Creator");
84
+ return traitText(attributes, "Author") ?? metadataAuthor ?? traitText(attributes, "Creator");
85
85
  }
86
86
  const VARIANT_KINDS = { edition: "edition", ticket: "ticket", club: "membership", pop: "pop" };
87
87
  function detectAssetKind(service, standard) {
@@ -170,12 +170,13 @@ function AssetPageView({
170
170
  const ownerAddress = !market.isERC1155 ? holders[0]?.owner ?? token.owner ?? null : null;
171
171
  const marketCount = market.activeListings.length + market.activeBids.length;
172
172
  const { Panel } = config;
173
- const articleText = token.metadata?.description?.trim() || null;
173
+ const postContent = traitText(attributes, "Content");
174
+ const articleText = postContent ?? (token.metadata?.description?.trim() || null);
174
175
  const video = (token.metadata?.ipType ?? "").toLowerCase() === "video" ? (0, import_asset_video.videoEmbed)(attributes) : null;
175
176
  const audio = (token.metadata?.ipType ?? "").toLowerCase() === "audio" ? (0, import_asset_audio.audioEmbed)(attributes) : null;
176
177
  const isPublication = !!articleText && PUBLICATION_TYPES.has((token.metadata?.ipType ?? "").toLowerCase());
177
178
  const publisherName = collection?.name ?? contract.slice(0, 8) + "\u2026";
178
- const overview = isPublication ? { attributes, hasTemplateData, isDisplayAttr } : video || audio ? (0, import_asset_attributes.assetAttributes)(attributes.filter((a) => !import_asset_video.VIDEO_EMBED_TRAITS.has(a.trait_type ?? "") && !import_asset_audio.AUDIO_EMBED_TRAITS.has(a.trait_type ?? ""))) : { attributes, hasTemplateData, isDisplayAttr };
179
+ const overview = isPublication ? { attributes, hasTemplateData, isDisplayAttr: (a) => isDisplayAttr(a) && !(postContent && a.trait_type === "Content") } : video || audio ? (0, import_asset_attributes.assetAttributes)(attributes.filter((a) => !import_asset_video.VIDEO_EMBED_TRAITS.has(a.trait_type ?? "") && !import_asset_audio.AUDIO_EMBED_TRAITS.has(a.trait_type ?? ""))) : { attributes, hasTemplateData, isDisplayAttr };
179
180
  const marketBlock = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
180
181
  Panel ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Panel, { contract, tokenId, quantityOwned: market.quantityOwned }) : null,
181
182
  config.market ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type ComponentType, type ReactNode } from \"react\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { Award } from \"lucide-react\";\nimport { assetHref, collectionHref, getDerivativesTerm, getService, resolveRemixPolicy, type ApiActivity, type ApiCollection, type ApiOrder, type ApiToken, type Chain } from \"@medialane/sdk\";\nimport { useRouter } from \"./router.js\";\nimport { PageContainer } from \"./page-container.js\";\nimport { PageBackdrop } from \"./media-header.js\";\nimport { AssetHeaderBlock, AssetMediaColumn, AssetOwnerRow } from \"./asset-top-sections.js\";\nimport { AssetPublication } from \"./asset-publication.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AssetRelatedList, AssetVideo, VIDEO_EMBED_TRAITS, videoEmbed } from \"./asset-video.js\";\nimport { AssetAudio, AUDIO_EMBED_TRAITS, audioEmbed } from \"./asset-audio.js\";\nimport { AssetUtilityIcons } from \"./asset-utility-icons.js\";\nimport { AssetMarketplacePanel } from \"./asset-marketplace-panel.js\";\nimport { AssetOwnersPanel } from \"./asset-owners-panel.js\";\nimport { AssetCollectionBar } from \"./asset-collection-bar.js\";\nimport { AssetOverviewContent } from \"./asset-overview-content.js\";\nimport { AssetMarketsTab } from \"./asset-markets-tab.js\";\nimport { AssetProvenanceTab } from \"./asset-provenance-tab.js\";\nimport { AssetLightbox } from \"./asset-lightbox.js\";\nimport { AssetUnavailable } from \"./asset-unavailable.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { DropTokenLink } from \"./drop/drop-token-link.js\";\nimport { FloatingCommentsButton } from \"./floating-comments-button.js\";\nimport { AssetCommentsDialog } from \"./asset-comments-dialog.js\";\nimport { PopBurnButton } from \"./pop-burn-button.js\";\nimport { MembershipPanel, TicketPanel, type AssetTypePanelProps } from \"./asset-type-panels.js\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"./tabs.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useToken, useTokenBalance, useTokenHistory } from \"../utils/use-tokens.js\";\nimport { useCollection, useNearbyCollectionTokens } from \"../utils/use-collections.js\";\nimport { useTokenListings } from \"../utils/use-orders.js\";\nimport { useTokenRemixes } from \"../utils/use-remix-offers.js\";\nimport { useComments } from \"../utils/use-comments.js\";\nimport { useFullTokenData } from \"../utils/use-full-token-data.js\";\nimport { useAssetMarketState } from \"../utils/asset-market-state.js\";\nimport { assetAttributes } from \"../utils/asset-attributes.js\";\nimport { ASSET_ACCENTS } from \"../utils/asset-accents.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { profileHref } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type AssetKind = \"standard\" | \"edition\" | \"ticket\" | \"membership\" | \"pop\";\n\nexport interface AssetMarketContext {\n contract: string;\n tokenId: string;\n tokenName: string;\n tokenImage: string | null;\n tokenStandard: \"ERC721\" | \"ERC1155\" | \"UNKNOWN\";\n activeListings: ApiOrder[];\n quantityOwned?: string;\n mutateListings: () => void;\n}\n\nexport interface AssetMarketActions {\n isProcessing: boolean;\n buy: (order: ApiOrder) => void;\n list: () => void;\n offer: () => void;\n transfer: () => void;\n cancel: (order: ApiOrder) => void;\n acceptBid: (order: ApiOrder) => void;\n dialogs: ReactNode;\n}\n\ninterface KindConfig {\n namePrefix: string;\n accents: (typeof ASSET_ACCENTS)[keyof typeof ASSET_ACCENTS];\n market: boolean;\n remix: boolean;\n Panel?: ComponentType<AssetTypePanelProps>;\n}\n\nconst KINDS: Record<AssetKind, KindConfig> = {\n standard: { namePrefix: \"Token\", accents: ASSET_ACCENTS.standard, market: true, remix: true },\n edition: { namePrefix: \"Edition\", accents: ASSET_ACCENTS.edition, market: true, remix: false },\n ticket: { namePrefix: \"Ticket\", accents: ASSET_ACCENTS.ticket, market: true, remix: false, Panel: TicketPanel },\n membership: { namePrefix: \"Membership\", accents: ASSET_ACCENTS.membership, market: true, remix: false, Panel: MembershipPanel },\n pop: { namePrefix: \"POP\", accents: ASSET_ACCENTS.standard, market: false, remix: false },\n};\n\nconst PUBLICATION_TYPES = new Set([\"publications\", \"posts\"]);\n\nfunction publicationAuthor(attributes: { trait_type?: string | null; value?: string | number | boolean | null }[], metadataAuthor?: string | null): string | null {\n const text = (trait: string) => {\n const value = attributes.find((a) => a.trait_type === trait)?.value;\n return typeof value === \"string\" && value.trim() !== \"\" ? value.trim() : null;\n };\n return text(\"Author\") ?? metadataAuthor ?? text(\"Creator\");\n}\n\nconst VARIANT_KINDS: Partial<Record<string, AssetKind>> = { edition: \"edition\", ticket: \"ticket\", club: \"membership\", pop: \"pop\" };\n\nexport function detectAssetKind(service: string | null | undefined, standard: string | null | undefined): AssetKind {\n const variant = getService(service)?.uiVariant;\n if (variant) return VARIANT_KINDS[variant] ?? \"standard\";\n return standard === \"ERC1155\" ? \"edition\" : \"standard\";\n}\n\nexport function AssetPageSkeleton() {\n return (\n <PageContainer className=\"pt-20 pb-8\">\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-6 items-start\">\n <Skeleton className=\"aspect-square w-full rounded-3xl\" />\n <div className=\"space-y-6\">\n <div className=\"space-y-3\">\n <Skeleton className=\"h-5 w-24 rounded-full\" />\n <Skeleton className=\"h-9 w-3/4\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-2/3\" />\n </div>\n <Skeleton className=\"h-[54px] w-full rounded-2xl\" />\n <div className=\"flex gap-2\">\n {Array.from({ length: 3 }).map((_, i) => <Skeleton key={i} className=\"h-[46px] flex-1 rounded-[13px]\" />)}\n </div>\n <Skeleton className=\"h-16 w-full rounded-2xl\" />\n </div>\n </div>\n </PageContainer>\n );\n}\n\nexport interface AssetPageProps {\n contract: string;\n tokenId: string;\n useMarketActions: (context: AssetMarketContext) => AssetMarketActions;\n}\n\nexport function AssetPage({ contract, tokenId, useMarketActions }: AssetPageProps) {\n const { token, isLoading, isIndexing } = useToken(contract, tokenId);\n const { collection, isLoading: collectionLoading } = useCollection(contract);\n if (isLoading || collectionLoading) return <AssetPageSkeleton />;\n if (!token) return <AssetUnavailable isIndexing={isIndexing} />;\n const kind = detectAssetKind(collection?.service, collection?.standard ?? token.standard);\n return <AssetPageView contract={contract} tokenId={tokenId} token={token} collection={collection ?? null} kind={kind} useMarketActions={useMarketActions} />;\n}\n\nfunction AssetPageView({\n contract,\n tokenId,\n token,\n collection,\n kind,\n useMarketActions,\n}: {\n contract: string;\n tokenId: string;\n token: ApiToken & { isHidden?: boolean };\n collection: ApiCollection | null;\n kind: AssetKind;\n useMarketActions: AssetPageProps[\"useMarketActions\"];\n}) {\n const resolveImage = useImageUrl();\n const config = KINDS[kind];\n const router = useRouter();\n const shouldReduce = useReducedMotion();\n const { walletAddress, ReportDialog } = useMedialaneApp();\n\n const { listings, mutate: mutateListings, isLoading: listingsLoading } = useTokenListings(contract, tokenId);\n const { history } = useTokenHistory(contract, tokenId);\n const { tokens: collectionTokens } = useNearbyCollectionTokens(contract, tokenId);\n const { total: commentTotal } = useComments(contract, tokenId);\n const { total: remixCount } = useTokenRemixes(contract, tokenId);\n const { data: fullTokenData } = useFullTokenData(contract, tokenId);\n const { amount: walletBalance } = useTokenBalance(contract, tokenId, walletAddress);\n const market = useAssetMarketState({ token, collection, listings, history: history as ApiActivity[], walletAddress, walletBalance });\n\n const [reportOpen, setReportOpen] = useState(false);\n const [commentOpen, setCommentOpen] = useState(false);\n const [lightboxOpen, setLightboxOpen] = useState(false);\n const [imgError, setImgError] = useState(false);\n\n const name = token.metadata?.name || `${config.namePrefix} #${token.tokenId}`;\n const image = resolveImage(token.metadata?.image);\n const tokenStandard = kind === \"standard\" || kind === \"pop\"\n ? ((token.standard ?? collection?.standard ?? \"UNKNOWN\") as AssetMarketContext[\"tokenStandard\"])\n : \"ERC1155\";\n\n const actions = useMarketActions({\n contract,\n tokenId,\n tokenName: name,\n tokenImage: image,\n tokenStandard,\n activeListings: market.activeListings,\n quantityOwned: market.quantityOwned,\n mutateListings,\n });\n\n const autoActionRef = useRef(false);\n useEffect(() => {\n if (autoActionRef.current || !config.market || !market.isOwner) return;\n const action = new URLSearchParams(window.location.search).get(\"action\");\n if (action === \"list\") actions.list();\n else if (action === \"transfer\") actions.transfer();\n else return;\n autoActionRef.current = true;\n }, [config.market, market.isOwner, actions]);\n\n const { attributes, hasTemplateData, isDisplayAttr, parentContract, parentTokenId } = assetAttributes(token.metadata?.attributes);\n const remixPolicy = resolveRemixPolicy({\n parentNoDerivatives: getDerivativesTerm(token.metadata?.attributes) === \"Not Allowed\",\n viewerIsParentOwner: market.isOwner,\n dealAvailable: !!getService(collection?.service),\n });\n const holders = token.balances ?? [];\n const ownerAddress = !market.isERC1155 ? (holders[0]?.owner ?? token.owner ?? null) : null;\n const marketCount = market.activeListings.length + market.activeBids.length;\n const { Panel } = config;\n\n const articleText = token.metadata?.description?.trim() || null;\n const video = (token.metadata?.ipType ?? \"\").toLowerCase() === \"video\" ? videoEmbed(attributes) : null;\n const audio = (token.metadata?.ipType ?? \"\").toLowerCase() === \"audio\" ? audioEmbed(attributes) : null;\n const isPublication = !!articleText && PUBLICATION_TYPES.has((token.metadata?.ipType ?? \"\").toLowerCase());\n const publisherName = collection?.name ?? contract.slice(0, 8) + \"…\";\n const overview = isPublication\n ? { attributes, hasTemplateData, isDisplayAttr }\n : video || audio\n ? assetAttributes(attributes.filter((a) => !VIDEO_EMBED_TRAITS.has(a.trait_type ?? \"\") && !AUDIO_EMBED_TRAITS.has(a.trait_type ?? \"\")))\n : { attributes, hasTemplateData, isDisplayAttr };\n\n const marketBlock = (\n <>\n {Panel ? <Panel contract={contract} tokenId={tokenId} quantityOwned={market.quantityOwned} /> : null}\n\n {config.market ? (\n <AssetMarketplacePanel\n asset={token}\n compact={isPublication || !!video || !!audio}\n cheapest={market.cheapest}\n usdValue={market.cheapestUsd}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n isERC1155={market.isERC1155}\n canListMoreEditions={market.canListMoreEditions}\n isMarketLoading={listingsLoading}\n myListing={market.myListing}\n activeBids={market.activeBids}\n remixEnabled={config.remix && remixPolicy.canRemixDirect}\n showDealOption={config.remix && remixPolicy.showDealOption}\n onCancelClick={actions.cancel}\n onAcceptBid={actions.acceptBid}\n onOpenListing={actions.list}\n onOpenTransfer={actions.transfer}\n onOpenPurchase={actions.buy}\n onOpenOffer={actions.offer}\n onOpenRemix={() => router.push(`/create/remix/${contract}/${tokenId}`)}\n />\n ) : null}\n\n {kind === \"pop\" && market.isOwner ? <PopBurnButton collectionAddress={contract} tokenId={tokenId} /> : null}\n\n {market.isERC1155 && holders.length > 0 ? (\n <AssetOwnersPanel balances={holders} total={token.holderCount} editions={Number(token.supply ?? 0)} />\n ) : null}\n </>\n );\n\n const detailsBlock = (\n <div className=\"pt-5 space-y-5\">\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n {collection?.service === \"drop-collection\" ? <DropTokenLink contract={contract} name={collection.name ?? null} /> : null}\n <AssetCollectionBar\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n currentTokenId={tokenId}\n siblingTokens={collectionTokens.map((t) => ({\n tokenId: t.tokenId,\n image: resolveImage(t.metadata?.image),\n }))}\n onNavigate={(id) => router.push(assetHref(\"STARKNET\", contract, id))}\n floorPriceRaw={collection?.floorPrice}\n />\n <div className=\"-ml-3\">\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n </div>\n </div>\n );\n\n return (\n <div className=\"relative z-0 min-h-screen\">\n {token.isHidden ? <HiddenContentBanner /> : null}\n <PageBackdrop image={image} />\n\n <PageContainer className={isPublication ? \"pt-20 space-y-8 pb-8 lg:px-16 xl:px-24\" : \"pt-20 space-y-8 pb-8\"}>\n {video ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetVideo\n name={name}\n embedSrc={video.src}\n embedLabel={video.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Video\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : audio ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetAudio\n name={name}\n image={image}\n embedSrc={audio.src}\n embedLabel={audio.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Audio\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n shape=\"square\"\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : isPublication ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-20 gap-8 items-start\">\n <AssetPublication\n name={name}\n text={articleText!}\n image={image}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n author={publicationAuthor(attributes, token.metadata?.author)}\n externalUrl={token.metadata?.externalUrl}\n />\n <aside className=\"space-y-6 min-w-0 lg:sticky lg:top-16\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Publications\"} size=\"md\" showLabel />\n {marketBlock}\n {detailsBlock}\n </aside>\n </div>\n ) : (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-8 items-start\">\n <AssetMediaColumn\n shouldReduce={Boolean(shouldReduce)}\n image={image}\n imageAlt={name}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n animationUrl={token.metadata?.animationUrl}\n live={isLivingRenderCollection(token.chain as Chain, token.contractAddress)}\n fallback={<div className=\"aspect-square bg-muted\" />}\n />\n\n <motion.div\n initial={shouldReduce ? false : { opacity: 0, y: 16 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, delay: 0.2 }}\n className=\"space-y-6\"\n >\n <AssetHeaderBlock\n name={name}\n description={token.metadata?.description}\n externalUrl={token.metadata?.externalUrl}\n ipType={token.metadata?.ipType}\n parentContract={parentContract}\n parentTokenId={parentTokenId}\n badges={kind === \"pop\" ? (\n <span className=\"inline-flex items-center gap-1 text-2xs font-semibold px-2.5 py-1 rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-500\">\n <Award className=\"h-3 w-3\" />\n POP\n </span>\n ) : null}\n />\n\n {marketBlock}\n\n {detailsBlock}\n </motion.div>\n </div>\n )}\n\n <Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n {config.market ? <TabsTrigger value=\"markets\">Markets {marketCount > 0 && `(${marketCount})`}</TabsTrigger> : null}\n <TabsTrigger value=\"provenance\">Provenance {history.length > 0 && `(${history.length})`}</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\">\n <AssetOverviewContent attributes={overview.attributes} hasTemplateData={overview.hasTemplateData} isDisplayAttr={overview.isDisplayAttr} />\n </TabsContent>\n\n {config.market ? (\n <TabsContent value=\"markets\">\n <AssetMarketsTab\n activeListings={market.activeListings}\n activeBids={market.activeBids}\n walletAddress={walletAddress ?? undefined}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n onBuyClick={actions.buy}\n onCancelClick={actions.cancel}\n onAcceptClick={actions.acceptBid}\n />\n </TabsContent>\n ) : null}\n\n <TabsContent value=\"provenance\">\n <AssetProvenanceTab\n history={history as ApiActivity[]}\n contract={contract}\n tokenId={tokenId}\n remixCount={remixCount}\n originalCreator={fullTokenData?.originalCreator}\n registeredAt={fullTokenData?.registeredAt}\n />\n </TabsContent>\n </Tabs>\n </PageContainer>\n\n <AssetLightbox open={lightboxOpen} onOpenChange={setLightboxOpen} image={image} alt={name} />\n <FloatingCommentsButton onClick={() => setCommentOpen(true)} commentTotal={commentTotal} />\n <AssetCommentsDialog\n open={commentOpen}\n onOpenChange={setCommentOpen}\n contract={contract}\n tokenId={tokenId}\n name={name}\n imageUrl={image}\n commentTotal={commentTotal}\n {...config.accents}\n />\n {ReportDialog ? <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"TOKEN\", contract: token.contractAddress, tokenId: token.tokenId, name }} /> : null}\n {actions.dialogs}\n </div>\n );\n}\n"],"mappings":"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","names":["import_sdk"]}
1
+ {"version":3,"sources":["../../src/components/asset-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type ComponentType, type ReactNode } from \"react\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { Award } from \"lucide-react\";\nimport { assetHref, collectionHref, getDerivativesTerm, getService, resolveRemixPolicy, type ApiActivity, type ApiCollection, type ApiOrder, type ApiToken, type Chain } from \"@medialane/sdk\";\nimport { useRouter } from \"./router.js\";\nimport { PageContainer } from \"./page-container.js\";\nimport { PageBackdrop } from \"./media-header.js\";\nimport { AssetHeaderBlock, AssetMediaColumn, AssetOwnerRow } from \"./asset-top-sections.js\";\nimport { AssetPublication } from \"./asset-publication.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AssetRelatedList, AssetVideo, VIDEO_EMBED_TRAITS, videoEmbed } from \"./asset-video.js\";\nimport { AssetAudio, AUDIO_EMBED_TRAITS, audioEmbed } from \"./asset-audio.js\";\nimport { AssetUtilityIcons } from \"./asset-utility-icons.js\";\nimport { AssetMarketplacePanel } from \"./asset-marketplace-panel.js\";\nimport { AssetOwnersPanel } from \"./asset-owners-panel.js\";\nimport { AssetCollectionBar } from \"./asset-collection-bar.js\";\nimport { AssetOverviewContent } from \"./asset-overview-content.js\";\nimport { AssetMarketsTab } from \"./asset-markets-tab.js\";\nimport { AssetProvenanceTab } from \"./asset-provenance-tab.js\";\nimport { AssetLightbox } from \"./asset-lightbox.js\";\nimport { AssetUnavailable } from \"./asset-unavailable.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { DropTokenLink } from \"./drop/drop-token-link.js\";\nimport { FloatingCommentsButton } from \"./floating-comments-button.js\";\nimport { AssetCommentsDialog } from \"./asset-comments-dialog.js\";\nimport { PopBurnButton } from \"./pop-burn-button.js\";\nimport { MembershipPanel, TicketPanel, type AssetTypePanelProps } from \"./asset-type-panels.js\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"./tabs.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useToken, useTokenBalance, useTokenHistory } from \"../utils/use-tokens.js\";\nimport { useCollection, useNearbyCollectionTokens } from \"../utils/use-collections.js\";\nimport { useTokenListings } from \"../utils/use-orders.js\";\nimport { useTokenRemixes } from \"../utils/use-remix-offers.js\";\nimport { useComments } from \"../utils/use-comments.js\";\nimport { useFullTokenData } from \"../utils/use-full-token-data.js\";\nimport { useAssetMarketState } from \"../utils/asset-market-state.js\";\nimport { assetAttributes } from \"../utils/asset-attributes.js\";\nimport { ASSET_ACCENTS } from \"../utils/asset-accents.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { profileHref } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type AssetKind = \"standard\" | \"edition\" | \"ticket\" | \"membership\" | \"pop\";\n\nexport interface AssetMarketContext {\n contract: string;\n tokenId: string;\n tokenName: string;\n tokenImage: string | null;\n tokenStandard: \"ERC721\" | \"ERC1155\" | \"UNKNOWN\";\n activeListings: ApiOrder[];\n quantityOwned?: string;\n mutateListings: () => void;\n}\n\nexport interface AssetMarketActions {\n isProcessing: boolean;\n buy: (order: ApiOrder) => void;\n list: () => void;\n offer: () => void;\n transfer: () => void;\n cancel: (order: ApiOrder) => void;\n acceptBid: (order: ApiOrder) => void;\n dialogs: ReactNode;\n}\n\ninterface KindConfig {\n namePrefix: string;\n accents: (typeof ASSET_ACCENTS)[keyof typeof ASSET_ACCENTS];\n market: boolean;\n remix: boolean;\n Panel?: ComponentType<AssetTypePanelProps>;\n}\n\nconst KINDS: Record<AssetKind, KindConfig> = {\n standard: { namePrefix: \"Token\", accents: ASSET_ACCENTS.standard, market: true, remix: true },\n edition: { namePrefix: \"Edition\", accents: ASSET_ACCENTS.edition, market: true, remix: false },\n ticket: { namePrefix: \"Ticket\", accents: ASSET_ACCENTS.ticket, market: true, remix: false, Panel: TicketPanel },\n membership: { namePrefix: \"Membership\", accents: ASSET_ACCENTS.membership, market: true, remix: false, Panel: MembershipPanel },\n pop: { namePrefix: \"POP\", accents: ASSET_ACCENTS.standard, market: false, remix: false },\n};\n\nconst PUBLICATION_TYPES = new Set([\"publications\", \"posts\"]);\n\ntype TraitList = { trait_type?: string | null; value?: string | number | boolean | null }[];\n\nfunction traitText(attributes: TraitList, trait: string): string | null {\n const value = attributes.find((a) => a.trait_type === trait)?.value;\n return typeof value === \"string\" && value.trim() !== \"\" ? value.trim() : null;\n}\n\nfunction publicationAuthor(attributes: TraitList, metadataAuthor?: string | null): string | null {\n return traitText(attributes, \"Author\") ?? metadataAuthor ?? traitText(attributes, \"Creator\");\n}\n\nconst VARIANT_KINDS: Partial<Record<string, AssetKind>> = { edition: \"edition\", ticket: \"ticket\", club: \"membership\", pop: \"pop\" };\n\nexport function detectAssetKind(service: string | null | undefined, standard: string | null | undefined): AssetKind {\n const variant = getService(service)?.uiVariant;\n if (variant) return VARIANT_KINDS[variant] ?? \"standard\";\n return standard === \"ERC1155\" ? \"edition\" : \"standard\";\n}\n\nexport function AssetPageSkeleton() {\n return (\n <PageContainer className=\"pt-20 pb-8\">\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-6 items-start\">\n <Skeleton className=\"aspect-square w-full rounded-3xl\" />\n <div className=\"space-y-6\">\n <div className=\"space-y-3\">\n <Skeleton className=\"h-5 w-24 rounded-full\" />\n <Skeleton className=\"h-9 w-3/4\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-2/3\" />\n </div>\n <Skeleton className=\"h-[54px] w-full rounded-2xl\" />\n <div className=\"flex gap-2\">\n {Array.from({ length: 3 }).map((_, i) => <Skeleton key={i} className=\"h-[46px] flex-1 rounded-[13px]\" />)}\n </div>\n <Skeleton className=\"h-16 w-full rounded-2xl\" />\n </div>\n </div>\n </PageContainer>\n );\n}\n\nexport interface AssetPageProps {\n contract: string;\n tokenId: string;\n useMarketActions: (context: AssetMarketContext) => AssetMarketActions;\n}\n\nexport function AssetPage({ contract, tokenId, useMarketActions }: AssetPageProps) {\n const { token, isLoading, isIndexing } = useToken(contract, tokenId);\n const { collection, isLoading: collectionLoading } = useCollection(contract);\n if (isLoading || collectionLoading) return <AssetPageSkeleton />;\n if (!token) return <AssetUnavailable isIndexing={isIndexing} />;\n const kind = detectAssetKind(collection?.service, collection?.standard ?? token.standard);\n return <AssetPageView contract={contract} tokenId={tokenId} token={token} collection={collection ?? null} kind={kind} useMarketActions={useMarketActions} />;\n}\n\nfunction AssetPageView({\n contract,\n tokenId,\n token,\n collection,\n kind,\n useMarketActions,\n}: {\n contract: string;\n tokenId: string;\n token: ApiToken & { isHidden?: boolean };\n collection: ApiCollection | null;\n kind: AssetKind;\n useMarketActions: AssetPageProps[\"useMarketActions\"];\n}) {\n const resolveImage = useImageUrl();\n const config = KINDS[kind];\n const router = useRouter();\n const shouldReduce = useReducedMotion();\n const { walletAddress, ReportDialog } = useMedialaneApp();\n\n const { listings, mutate: mutateListings, isLoading: listingsLoading } = useTokenListings(contract, tokenId);\n const { history } = useTokenHistory(contract, tokenId);\n const { tokens: collectionTokens } = useNearbyCollectionTokens(contract, tokenId);\n const { total: commentTotal } = useComments(contract, tokenId);\n const { total: remixCount } = useTokenRemixes(contract, tokenId);\n const { data: fullTokenData } = useFullTokenData(contract, tokenId);\n const { amount: walletBalance } = useTokenBalance(contract, tokenId, walletAddress);\n const market = useAssetMarketState({ token, collection, listings, history: history as ApiActivity[], walletAddress, walletBalance });\n\n const [reportOpen, setReportOpen] = useState(false);\n const [commentOpen, setCommentOpen] = useState(false);\n const [lightboxOpen, setLightboxOpen] = useState(false);\n const [imgError, setImgError] = useState(false);\n\n const name = token.metadata?.name || `${config.namePrefix} #${token.tokenId}`;\n const image = resolveImage(token.metadata?.image);\n const tokenStandard = kind === \"standard\" || kind === \"pop\"\n ? ((token.standard ?? collection?.standard ?? \"UNKNOWN\") as AssetMarketContext[\"tokenStandard\"])\n : \"ERC1155\";\n\n const actions = useMarketActions({\n contract,\n tokenId,\n tokenName: name,\n tokenImage: image,\n tokenStandard,\n activeListings: market.activeListings,\n quantityOwned: market.quantityOwned,\n mutateListings,\n });\n\n const autoActionRef = useRef(false);\n useEffect(() => {\n if (autoActionRef.current || !config.market || !market.isOwner) return;\n const action = new URLSearchParams(window.location.search).get(\"action\");\n if (action === \"list\") actions.list();\n else if (action === \"transfer\") actions.transfer();\n else return;\n autoActionRef.current = true;\n }, [config.market, market.isOwner, actions]);\n\n const { attributes, hasTemplateData, isDisplayAttr, parentContract, parentTokenId } = assetAttributes(token.metadata?.attributes);\n const remixPolicy = resolveRemixPolicy({\n parentNoDerivatives: getDerivativesTerm(token.metadata?.attributes) === \"Not Allowed\",\n viewerIsParentOwner: market.isOwner,\n dealAvailable: !!getService(collection?.service),\n });\n const holders = token.balances ?? [];\n const ownerAddress = !market.isERC1155 ? (holders[0]?.owner ?? token.owner ?? null) : null;\n const marketCount = market.activeListings.length + market.activeBids.length;\n const { Panel } = config;\n\n const postContent = traitText(attributes, \"Content\");\n const articleText = postContent ?? (token.metadata?.description?.trim() || null);\n const video = (token.metadata?.ipType ?? \"\").toLowerCase() === \"video\" ? videoEmbed(attributes) : null;\n const audio = (token.metadata?.ipType ?? \"\").toLowerCase() === \"audio\" ? audioEmbed(attributes) : null;\n const isPublication = !!articleText && PUBLICATION_TYPES.has((token.metadata?.ipType ?? \"\").toLowerCase());\n const publisherName = collection?.name ?? contract.slice(0, 8) + \"…\";\n const overview = isPublication\n ? { attributes, hasTemplateData, isDisplayAttr: (a: Parameters<typeof isDisplayAttr>[0]) => isDisplayAttr(a) && !(postContent && a.trait_type === \"Content\") }\n : video || audio\n ? assetAttributes(attributes.filter((a) => !VIDEO_EMBED_TRAITS.has(a.trait_type ?? \"\") && !AUDIO_EMBED_TRAITS.has(a.trait_type ?? \"\")))\n : { attributes, hasTemplateData, isDisplayAttr };\n\n const marketBlock = (\n <>\n {Panel ? <Panel contract={contract} tokenId={tokenId} quantityOwned={market.quantityOwned} /> : null}\n\n {config.market ? (\n <AssetMarketplacePanel\n asset={token}\n compact={isPublication || !!video || !!audio}\n cheapest={market.cheapest}\n usdValue={market.cheapestUsd}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n isERC1155={market.isERC1155}\n canListMoreEditions={market.canListMoreEditions}\n isMarketLoading={listingsLoading}\n myListing={market.myListing}\n activeBids={market.activeBids}\n remixEnabled={config.remix && remixPolicy.canRemixDirect}\n showDealOption={config.remix && remixPolicy.showDealOption}\n onCancelClick={actions.cancel}\n onAcceptBid={actions.acceptBid}\n onOpenListing={actions.list}\n onOpenTransfer={actions.transfer}\n onOpenPurchase={actions.buy}\n onOpenOffer={actions.offer}\n onOpenRemix={() => router.push(`/create/remix/${contract}/${tokenId}`)}\n />\n ) : null}\n\n {kind === \"pop\" && market.isOwner ? <PopBurnButton collectionAddress={contract} tokenId={tokenId} /> : null}\n\n {market.isERC1155 && holders.length > 0 ? (\n <AssetOwnersPanel balances={holders} total={token.holderCount} editions={Number(token.supply ?? 0)} />\n ) : null}\n </>\n );\n\n const detailsBlock = (\n <div className=\"pt-5 space-y-5\">\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n {collection?.service === \"drop-collection\" ? <DropTokenLink contract={contract} name={collection.name ?? null} /> : null}\n <AssetCollectionBar\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n currentTokenId={tokenId}\n siblingTokens={collectionTokens.map((t) => ({\n tokenId: t.tokenId,\n image: resolveImage(t.metadata?.image),\n }))}\n onNavigate={(id) => router.push(assetHref(\"STARKNET\", contract, id))}\n floorPriceRaw={collection?.floorPrice}\n />\n <div className=\"-ml-3\">\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n </div>\n </div>\n );\n\n return (\n <div className=\"relative z-0 min-h-screen\">\n {token.isHidden ? <HiddenContentBanner /> : null}\n <PageBackdrop image={image} />\n\n <PageContainer className={isPublication ? \"pt-20 space-y-8 pb-8 lg:px-16 xl:px-24\" : \"pt-20 space-y-8 pb-8\"}>\n {video ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetVideo\n name={name}\n embedSrc={video.src}\n embedLabel={video.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Video\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : audio ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetAudio\n name={name}\n image={image}\n embedSrc={audio.src}\n embedLabel={audio.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Audio\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n shape=\"square\"\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : isPublication ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-20 gap-8 items-start\">\n <AssetPublication\n name={name}\n text={articleText!}\n image={image}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n author={publicationAuthor(attributes, token.metadata?.author)}\n externalUrl={token.metadata?.externalUrl}\n />\n <aside className=\"space-y-6 min-w-0 lg:sticky lg:top-16\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Publications\"} size=\"md\" showLabel />\n {marketBlock}\n {detailsBlock}\n </aside>\n </div>\n ) : (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-8 items-start\">\n <AssetMediaColumn\n shouldReduce={Boolean(shouldReduce)}\n image={image}\n imageAlt={name}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n animationUrl={token.metadata?.animationUrl}\n live={isLivingRenderCollection(token.chain as Chain, token.contractAddress)}\n fallback={<div className=\"aspect-square bg-muted\" />}\n />\n\n <motion.div\n initial={shouldReduce ? false : { opacity: 0, y: 16 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, delay: 0.2 }}\n className=\"space-y-6\"\n >\n <AssetHeaderBlock\n name={name}\n description={token.metadata?.description}\n externalUrl={token.metadata?.externalUrl}\n ipType={token.metadata?.ipType}\n parentContract={parentContract}\n parentTokenId={parentTokenId}\n badges={kind === \"pop\" ? (\n <span className=\"inline-flex items-center gap-1 text-2xs font-semibold px-2.5 py-1 rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-500\">\n <Award className=\"h-3 w-3\" />\n POP\n </span>\n ) : null}\n />\n\n {marketBlock}\n\n {detailsBlock}\n </motion.div>\n </div>\n )}\n\n <Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n {config.market ? <TabsTrigger value=\"markets\">Markets {marketCount > 0 && `(${marketCount})`}</TabsTrigger> : null}\n <TabsTrigger value=\"provenance\">Provenance {history.length > 0 && `(${history.length})`}</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\">\n <AssetOverviewContent attributes={overview.attributes} hasTemplateData={overview.hasTemplateData} isDisplayAttr={overview.isDisplayAttr} />\n </TabsContent>\n\n {config.market ? (\n <TabsContent value=\"markets\">\n <AssetMarketsTab\n activeListings={market.activeListings}\n activeBids={market.activeBids}\n walletAddress={walletAddress ?? undefined}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n onBuyClick={actions.buy}\n onCancelClick={actions.cancel}\n onAcceptClick={actions.acceptBid}\n />\n </TabsContent>\n ) : null}\n\n <TabsContent value=\"provenance\">\n <AssetProvenanceTab\n history={history as ApiActivity[]}\n contract={contract}\n tokenId={tokenId}\n remixCount={remixCount}\n originalCreator={fullTokenData?.originalCreator}\n registeredAt={fullTokenData?.registeredAt}\n />\n </TabsContent>\n </Tabs>\n </PageContainer>\n\n <AssetLightbox open={lightboxOpen} onOpenChange={setLightboxOpen} image={image} alt={name} />\n <FloatingCommentsButton onClick={() => setCommentOpen(true)} commentTotal={commentTotal} />\n <AssetCommentsDialog\n open={commentOpen}\n onOpenChange={setCommentOpen}\n contract={contract}\n tokenId={tokenId}\n name={name}\n imageUrl={image}\n commentTotal={commentTotal}\n {...config.accents}\n />\n {ReportDialog ? <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"TOKEN\", contract: token.contractAddress, tokenId: token.tokenId, name }} /> : null}\n {actions.dialogs}\n </div>\n );\n}\n"],"mappings":"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","names":["import_sdk"]}
@@ -51,12 +51,12 @@ const KINDS = {
51
51
  pop: { namePrefix: "POP", accents: ASSET_ACCENTS.standard, market: false, remix: false }
52
52
  };
53
53
  const PUBLICATION_TYPES = /* @__PURE__ */ new Set(["publications", "posts"]);
54
+ function traitText(attributes, trait) {
55
+ const value = attributes.find((a) => a.trait_type === trait)?.value;
56
+ return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
57
+ }
54
58
  function publicationAuthor(attributes, metadataAuthor) {
55
- const text = (trait) => {
56
- const value = attributes.find((a) => a.trait_type === trait)?.value;
57
- return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
58
- };
59
- return text("Author") ?? metadataAuthor ?? text("Creator");
59
+ return traitText(attributes, "Author") ?? metadataAuthor ?? traitText(attributes, "Creator");
60
60
  }
61
61
  const VARIANT_KINDS = { edition: "edition", ticket: "ticket", club: "membership", pop: "pop" };
62
62
  function detectAssetKind(service, standard) {
@@ -145,12 +145,13 @@ function AssetPageView({
145
145
  const ownerAddress = !market.isERC1155 ? holders[0]?.owner ?? token.owner ?? null : null;
146
146
  const marketCount = market.activeListings.length + market.activeBids.length;
147
147
  const { Panel } = config;
148
- const articleText = token.metadata?.description?.trim() || null;
148
+ const postContent = traitText(attributes, "Content");
149
+ const articleText = postContent ?? (token.metadata?.description?.trim() || null);
149
150
  const video = (token.metadata?.ipType ?? "").toLowerCase() === "video" ? videoEmbed(attributes) : null;
150
151
  const audio = (token.metadata?.ipType ?? "").toLowerCase() === "audio" ? audioEmbed(attributes) : null;
151
152
  const isPublication = !!articleText && PUBLICATION_TYPES.has((token.metadata?.ipType ?? "").toLowerCase());
152
153
  const publisherName = collection?.name ?? contract.slice(0, 8) + "\u2026";
153
- const overview = isPublication ? { attributes, hasTemplateData, isDisplayAttr } : video || audio ? assetAttributes(attributes.filter((a) => !VIDEO_EMBED_TRAITS.has(a.trait_type ?? "") && !AUDIO_EMBED_TRAITS.has(a.trait_type ?? ""))) : { attributes, hasTemplateData, isDisplayAttr };
154
+ const overview = isPublication ? { attributes, hasTemplateData, isDisplayAttr: (a) => isDisplayAttr(a) && !(postContent && a.trait_type === "Content") } : video || audio ? assetAttributes(attributes.filter((a) => !VIDEO_EMBED_TRAITS.has(a.trait_type ?? "") && !AUDIO_EMBED_TRAITS.has(a.trait_type ?? ""))) : { attributes, hasTemplateData, isDisplayAttr };
154
155
  const marketBlock = /* @__PURE__ */ jsxs(Fragment, { children: [
155
156
  Panel ? /* @__PURE__ */ jsx(Panel, { contract, tokenId, quantityOwned: market.quantityOwned }) : null,
156
157
  config.market ? /* @__PURE__ */ jsx(
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type ComponentType, type ReactNode } from \"react\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { Award } from \"lucide-react\";\nimport { assetHref, collectionHref, getDerivativesTerm, getService, resolveRemixPolicy, type ApiActivity, type ApiCollection, type ApiOrder, type ApiToken, type Chain } from \"@medialane/sdk\";\nimport { useRouter } from \"./router.js\";\nimport { PageContainer } from \"./page-container.js\";\nimport { PageBackdrop } from \"./media-header.js\";\nimport { AssetHeaderBlock, AssetMediaColumn, AssetOwnerRow } from \"./asset-top-sections.js\";\nimport { AssetPublication } from \"./asset-publication.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AssetRelatedList, AssetVideo, VIDEO_EMBED_TRAITS, videoEmbed } from \"./asset-video.js\";\nimport { AssetAudio, AUDIO_EMBED_TRAITS, audioEmbed } from \"./asset-audio.js\";\nimport { AssetUtilityIcons } from \"./asset-utility-icons.js\";\nimport { AssetMarketplacePanel } from \"./asset-marketplace-panel.js\";\nimport { AssetOwnersPanel } from \"./asset-owners-panel.js\";\nimport { AssetCollectionBar } from \"./asset-collection-bar.js\";\nimport { AssetOverviewContent } from \"./asset-overview-content.js\";\nimport { AssetMarketsTab } from \"./asset-markets-tab.js\";\nimport { AssetProvenanceTab } from \"./asset-provenance-tab.js\";\nimport { AssetLightbox } from \"./asset-lightbox.js\";\nimport { AssetUnavailable } from \"./asset-unavailable.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { DropTokenLink } from \"./drop/drop-token-link.js\";\nimport { FloatingCommentsButton } from \"./floating-comments-button.js\";\nimport { AssetCommentsDialog } from \"./asset-comments-dialog.js\";\nimport { PopBurnButton } from \"./pop-burn-button.js\";\nimport { MembershipPanel, TicketPanel, type AssetTypePanelProps } from \"./asset-type-panels.js\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"./tabs.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useToken, useTokenBalance, useTokenHistory } from \"../utils/use-tokens.js\";\nimport { useCollection, useNearbyCollectionTokens } from \"../utils/use-collections.js\";\nimport { useTokenListings } from \"../utils/use-orders.js\";\nimport { useTokenRemixes } from \"../utils/use-remix-offers.js\";\nimport { useComments } from \"../utils/use-comments.js\";\nimport { useFullTokenData } from \"../utils/use-full-token-data.js\";\nimport { useAssetMarketState } from \"../utils/asset-market-state.js\";\nimport { assetAttributes } from \"../utils/asset-attributes.js\";\nimport { ASSET_ACCENTS } from \"../utils/asset-accents.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { profileHref } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type AssetKind = \"standard\" | \"edition\" | \"ticket\" | \"membership\" | \"pop\";\n\nexport interface AssetMarketContext {\n contract: string;\n tokenId: string;\n tokenName: string;\n tokenImage: string | null;\n tokenStandard: \"ERC721\" | \"ERC1155\" | \"UNKNOWN\";\n activeListings: ApiOrder[];\n quantityOwned?: string;\n mutateListings: () => void;\n}\n\nexport interface AssetMarketActions {\n isProcessing: boolean;\n buy: (order: ApiOrder) => void;\n list: () => void;\n offer: () => void;\n transfer: () => void;\n cancel: (order: ApiOrder) => void;\n acceptBid: (order: ApiOrder) => void;\n dialogs: ReactNode;\n}\n\ninterface KindConfig {\n namePrefix: string;\n accents: (typeof ASSET_ACCENTS)[keyof typeof ASSET_ACCENTS];\n market: boolean;\n remix: boolean;\n Panel?: ComponentType<AssetTypePanelProps>;\n}\n\nconst KINDS: Record<AssetKind, KindConfig> = {\n standard: { namePrefix: \"Token\", accents: ASSET_ACCENTS.standard, market: true, remix: true },\n edition: { namePrefix: \"Edition\", accents: ASSET_ACCENTS.edition, market: true, remix: false },\n ticket: { namePrefix: \"Ticket\", accents: ASSET_ACCENTS.ticket, market: true, remix: false, Panel: TicketPanel },\n membership: { namePrefix: \"Membership\", accents: ASSET_ACCENTS.membership, market: true, remix: false, Panel: MembershipPanel },\n pop: { namePrefix: \"POP\", accents: ASSET_ACCENTS.standard, market: false, remix: false },\n};\n\nconst PUBLICATION_TYPES = new Set([\"publications\", \"posts\"]);\n\nfunction publicationAuthor(attributes: { trait_type?: string | null; value?: string | number | boolean | null }[], metadataAuthor?: string | null): string | null {\n const text = (trait: string) => {\n const value = attributes.find((a) => a.trait_type === trait)?.value;\n return typeof value === \"string\" && value.trim() !== \"\" ? value.trim() : null;\n };\n return text(\"Author\") ?? metadataAuthor ?? text(\"Creator\");\n}\n\nconst VARIANT_KINDS: Partial<Record<string, AssetKind>> = { edition: \"edition\", ticket: \"ticket\", club: \"membership\", pop: \"pop\" };\n\nexport function detectAssetKind(service: string | null | undefined, standard: string | null | undefined): AssetKind {\n const variant = getService(service)?.uiVariant;\n if (variant) return VARIANT_KINDS[variant] ?? \"standard\";\n return standard === \"ERC1155\" ? \"edition\" : \"standard\";\n}\n\nexport function AssetPageSkeleton() {\n return (\n <PageContainer className=\"pt-20 pb-8\">\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-6 items-start\">\n <Skeleton className=\"aspect-square w-full rounded-3xl\" />\n <div className=\"space-y-6\">\n <div className=\"space-y-3\">\n <Skeleton className=\"h-5 w-24 rounded-full\" />\n <Skeleton className=\"h-9 w-3/4\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-2/3\" />\n </div>\n <Skeleton className=\"h-[54px] w-full rounded-2xl\" />\n <div className=\"flex gap-2\">\n {Array.from({ length: 3 }).map((_, i) => <Skeleton key={i} className=\"h-[46px] flex-1 rounded-[13px]\" />)}\n </div>\n <Skeleton className=\"h-16 w-full rounded-2xl\" />\n </div>\n </div>\n </PageContainer>\n );\n}\n\nexport interface AssetPageProps {\n contract: string;\n tokenId: string;\n useMarketActions: (context: AssetMarketContext) => AssetMarketActions;\n}\n\nexport function AssetPage({ contract, tokenId, useMarketActions }: AssetPageProps) {\n const { token, isLoading, isIndexing } = useToken(contract, tokenId);\n const { collection, isLoading: collectionLoading } = useCollection(contract);\n if (isLoading || collectionLoading) return <AssetPageSkeleton />;\n if (!token) return <AssetUnavailable isIndexing={isIndexing} />;\n const kind = detectAssetKind(collection?.service, collection?.standard ?? token.standard);\n return <AssetPageView contract={contract} tokenId={tokenId} token={token} collection={collection ?? null} kind={kind} useMarketActions={useMarketActions} />;\n}\n\nfunction AssetPageView({\n contract,\n tokenId,\n token,\n collection,\n kind,\n useMarketActions,\n}: {\n contract: string;\n tokenId: string;\n token: ApiToken & { isHidden?: boolean };\n collection: ApiCollection | null;\n kind: AssetKind;\n useMarketActions: AssetPageProps[\"useMarketActions\"];\n}) {\n const resolveImage = useImageUrl();\n const config = KINDS[kind];\n const router = useRouter();\n const shouldReduce = useReducedMotion();\n const { walletAddress, ReportDialog } = useMedialaneApp();\n\n const { listings, mutate: mutateListings, isLoading: listingsLoading } = useTokenListings(contract, tokenId);\n const { history } = useTokenHistory(contract, tokenId);\n const { tokens: collectionTokens } = useNearbyCollectionTokens(contract, tokenId);\n const { total: commentTotal } = useComments(contract, tokenId);\n const { total: remixCount } = useTokenRemixes(contract, tokenId);\n const { data: fullTokenData } = useFullTokenData(contract, tokenId);\n const { amount: walletBalance } = useTokenBalance(contract, tokenId, walletAddress);\n const market = useAssetMarketState({ token, collection, listings, history: history as ApiActivity[], walletAddress, walletBalance });\n\n const [reportOpen, setReportOpen] = useState(false);\n const [commentOpen, setCommentOpen] = useState(false);\n const [lightboxOpen, setLightboxOpen] = useState(false);\n const [imgError, setImgError] = useState(false);\n\n const name = token.metadata?.name || `${config.namePrefix} #${token.tokenId}`;\n const image = resolveImage(token.metadata?.image);\n const tokenStandard = kind === \"standard\" || kind === \"pop\"\n ? ((token.standard ?? collection?.standard ?? \"UNKNOWN\") as AssetMarketContext[\"tokenStandard\"])\n : \"ERC1155\";\n\n const actions = useMarketActions({\n contract,\n tokenId,\n tokenName: name,\n tokenImage: image,\n tokenStandard,\n activeListings: market.activeListings,\n quantityOwned: market.quantityOwned,\n mutateListings,\n });\n\n const autoActionRef = useRef(false);\n useEffect(() => {\n if (autoActionRef.current || !config.market || !market.isOwner) return;\n const action = new URLSearchParams(window.location.search).get(\"action\");\n if (action === \"list\") actions.list();\n else if (action === \"transfer\") actions.transfer();\n else return;\n autoActionRef.current = true;\n }, [config.market, market.isOwner, actions]);\n\n const { attributes, hasTemplateData, isDisplayAttr, parentContract, parentTokenId } = assetAttributes(token.metadata?.attributes);\n const remixPolicy = resolveRemixPolicy({\n parentNoDerivatives: getDerivativesTerm(token.metadata?.attributes) === \"Not Allowed\",\n viewerIsParentOwner: market.isOwner,\n dealAvailable: !!getService(collection?.service),\n });\n const holders = token.balances ?? [];\n const ownerAddress = !market.isERC1155 ? (holders[0]?.owner ?? token.owner ?? null) : null;\n const marketCount = market.activeListings.length + market.activeBids.length;\n const { Panel } = config;\n\n const articleText = token.metadata?.description?.trim() || null;\n const video = (token.metadata?.ipType ?? \"\").toLowerCase() === \"video\" ? videoEmbed(attributes) : null;\n const audio = (token.metadata?.ipType ?? \"\").toLowerCase() === \"audio\" ? audioEmbed(attributes) : null;\n const isPublication = !!articleText && PUBLICATION_TYPES.has((token.metadata?.ipType ?? \"\").toLowerCase());\n const publisherName = collection?.name ?? contract.slice(0, 8) + \"…\";\n const overview = isPublication\n ? { attributes, hasTemplateData, isDisplayAttr }\n : video || audio\n ? assetAttributes(attributes.filter((a) => !VIDEO_EMBED_TRAITS.has(a.trait_type ?? \"\") && !AUDIO_EMBED_TRAITS.has(a.trait_type ?? \"\")))\n : { attributes, hasTemplateData, isDisplayAttr };\n\n const marketBlock = (\n <>\n {Panel ? <Panel contract={contract} tokenId={tokenId} quantityOwned={market.quantityOwned} /> : null}\n\n {config.market ? (\n <AssetMarketplacePanel\n asset={token}\n compact={isPublication || !!video || !!audio}\n cheapest={market.cheapest}\n usdValue={market.cheapestUsd}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n isERC1155={market.isERC1155}\n canListMoreEditions={market.canListMoreEditions}\n isMarketLoading={listingsLoading}\n myListing={market.myListing}\n activeBids={market.activeBids}\n remixEnabled={config.remix && remixPolicy.canRemixDirect}\n showDealOption={config.remix && remixPolicy.showDealOption}\n onCancelClick={actions.cancel}\n onAcceptBid={actions.acceptBid}\n onOpenListing={actions.list}\n onOpenTransfer={actions.transfer}\n onOpenPurchase={actions.buy}\n onOpenOffer={actions.offer}\n onOpenRemix={() => router.push(`/create/remix/${contract}/${tokenId}`)}\n />\n ) : null}\n\n {kind === \"pop\" && market.isOwner ? <PopBurnButton collectionAddress={contract} tokenId={tokenId} /> : null}\n\n {market.isERC1155 && holders.length > 0 ? (\n <AssetOwnersPanel balances={holders} total={token.holderCount} editions={Number(token.supply ?? 0)} />\n ) : null}\n </>\n );\n\n const detailsBlock = (\n <div className=\"pt-5 space-y-5\">\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n {collection?.service === \"drop-collection\" ? <DropTokenLink contract={contract} name={collection.name ?? null} /> : null}\n <AssetCollectionBar\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n currentTokenId={tokenId}\n siblingTokens={collectionTokens.map((t) => ({\n tokenId: t.tokenId,\n image: resolveImage(t.metadata?.image),\n }))}\n onNavigate={(id) => router.push(assetHref(\"STARKNET\", contract, id))}\n floorPriceRaw={collection?.floorPrice}\n />\n <div className=\"-ml-3\">\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n </div>\n </div>\n );\n\n return (\n <div className=\"relative z-0 min-h-screen\">\n {token.isHidden ? <HiddenContentBanner /> : null}\n <PageBackdrop image={image} />\n\n <PageContainer className={isPublication ? \"pt-20 space-y-8 pb-8 lg:px-16 xl:px-24\" : \"pt-20 space-y-8 pb-8\"}>\n {video ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetVideo\n name={name}\n embedSrc={video.src}\n embedLabel={video.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Video\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : audio ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetAudio\n name={name}\n image={image}\n embedSrc={audio.src}\n embedLabel={audio.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Audio\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n shape=\"square\"\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : isPublication ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-20 gap-8 items-start\">\n <AssetPublication\n name={name}\n text={articleText!}\n image={image}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n author={publicationAuthor(attributes, token.metadata?.author)}\n externalUrl={token.metadata?.externalUrl}\n />\n <aside className=\"space-y-6 min-w-0 lg:sticky lg:top-16\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Publications\"} size=\"md\" showLabel />\n {marketBlock}\n {detailsBlock}\n </aside>\n </div>\n ) : (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-8 items-start\">\n <AssetMediaColumn\n shouldReduce={Boolean(shouldReduce)}\n image={image}\n imageAlt={name}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n animationUrl={token.metadata?.animationUrl}\n live={isLivingRenderCollection(token.chain as Chain, token.contractAddress)}\n fallback={<div className=\"aspect-square bg-muted\" />}\n />\n\n <motion.div\n initial={shouldReduce ? false : { opacity: 0, y: 16 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, delay: 0.2 }}\n className=\"space-y-6\"\n >\n <AssetHeaderBlock\n name={name}\n description={token.metadata?.description}\n externalUrl={token.metadata?.externalUrl}\n ipType={token.metadata?.ipType}\n parentContract={parentContract}\n parentTokenId={parentTokenId}\n badges={kind === \"pop\" ? (\n <span className=\"inline-flex items-center gap-1 text-2xs font-semibold px-2.5 py-1 rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-500\">\n <Award className=\"h-3 w-3\" />\n POP\n </span>\n ) : null}\n />\n\n {marketBlock}\n\n {detailsBlock}\n </motion.div>\n </div>\n )}\n\n <Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n {config.market ? <TabsTrigger value=\"markets\">Markets {marketCount > 0 && `(${marketCount})`}</TabsTrigger> : null}\n <TabsTrigger value=\"provenance\">Provenance {history.length > 0 && `(${history.length})`}</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\">\n <AssetOverviewContent attributes={overview.attributes} hasTemplateData={overview.hasTemplateData} isDisplayAttr={overview.isDisplayAttr} />\n </TabsContent>\n\n {config.market ? (\n <TabsContent value=\"markets\">\n <AssetMarketsTab\n activeListings={market.activeListings}\n activeBids={market.activeBids}\n walletAddress={walletAddress ?? undefined}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n onBuyClick={actions.buy}\n onCancelClick={actions.cancel}\n onAcceptClick={actions.acceptBid}\n />\n </TabsContent>\n ) : null}\n\n <TabsContent value=\"provenance\">\n <AssetProvenanceTab\n history={history as ApiActivity[]}\n contract={contract}\n tokenId={tokenId}\n remixCount={remixCount}\n originalCreator={fullTokenData?.originalCreator}\n registeredAt={fullTokenData?.registeredAt}\n />\n </TabsContent>\n </Tabs>\n </PageContainer>\n\n <AssetLightbox open={lightboxOpen} onOpenChange={setLightboxOpen} image={image} alt={name} />\n <FloatingCommentsButton onClick={() => setCommentOpen(true)} commentTotal={commentTotal} />\n <AssetCommentsDialog\n open={commentOpen}\n onOpenChange={setCommentOpen}\n contract={contract}\n tokenId={tokenId}\n name={name}\n imageUrl={image}\n commentTotal={commentTotal}\n {...config.accents}\n />\n {ReportDialog ? <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"TOKEN\", contract: token.contractAddress, tokenId: token.tokenId, name }} /> : null}\n {actions.dialogs}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/asset-page.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type ComponentType, type ReactNode } from \"react\";\nimport { motion, useReducedMotion } from \"framer-motion\";\nimport { Award } from \"lucide-react\";\nimport { assetHref, collectionHref, getDerivativesTerm, getService, resolveRemixPolicy, type ApiActivity, type ApiCollection, type ApiOrder, type ApiToken, type Chain } from \"@medialane/sdk\";\nimport { useRouter } from \"./router.js\";\nimport { PageContainer } from \"./page-container.js\";\nimport { PageBackdrop } from \"./media-header.js\";\nimport { AssetHeaderBlock, AssetMediaColumn, AssetOwnerRow } from \"./asset-top-sections.js\";\nimport { AssetPublication } from \"./asset-publication.js\";\nimport { IpTypeBadge } from \"./ip-type-badge.js\";\nimport { AssetRelatedList, AssetVideo, VIDEO_EMBED_TRAITS, videoEmbed } from \"./asset-video.js\";\nimport { AssetAudio, AUDIO_EMBED_TRAITS, audioEmbed } from \"./asset-audio.js\";\nimport { AssetUtilityIcons } from \"./asset-utility-icons.js\";\nimport { AssetMarketplacePanel } from \"./asset-marketplace-panel.js\";\nimport { AssetOwnersPanel } from \"./asset-owners-panel.js\";\nimport { AssetCollectionBar } from \"./asset-collection-bar.js\";\nimport { AssetOverviewContent } from \"./asset-overview-content.js\";\nimport { AssetMarketsTab } from \"./asset-markets-tab.js\";\nimport { AssetProvenanceTab } from \"./asset-provenance-tab.js\";\nimport { AssetLightbox } from \"./asset-lightbox.js\";\nimport { AssetUnavailable } from \"./asset-unavailable.js\";\nimport { HiddenContentBanner } from \"./hidden-content-banner.js\";\nimport { DropTokenLink } from \"./drop/drop-token-link.js\";\nimport { FloatingCommentsButton } from \"./floating-comments-button.js\";\nimport { AssetCommentsDialog } from \"./asset-comments-dialog.js\";\nimport { PopBurnButton } from \"./pop-burn-button.js\";\nimport { MembershipPanel, TicketPanel, type AssetTypePanelProps } from \"./asset-type-panels.js\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"./tabs.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { useMedialaneApp } from \"./medialane-app.js\";\nimport { useToken, useTokenBalance, useTokenHistory } from \"../utils/use-tokens.js\";\nimport { useCollection, useNearbyCollectionTokens } from \"../utils/use-collections.js\";\nimport { useTokenListings } from \"../utils/use-orders.js\";\nimport { useTokenRemixes } from \"../utils/use-remix-offers.js\";\nimport { useComments } from \"../utils/use-comments.js\";\nimport { useFullTokenData } from \"../utils/use-full-token-data.js\";\nimport { useAssetMarketState } from \"../utils/asset-market-state.js\";\nimport { assetAttributes } from \"../utils/asset-attributes.js\";\nimport { ASSET_ACCENTS } from \"../utils/asset-accents.js\";\nimport { isLivingRenderCollection } from \"../data/living-render-collections.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { profileHref } from \"@medialane/sdk\";\nimport { useImageUrl } from \"../utils/use-image-url.js\";\n\nexport type AssetKind = \"standard\" | \"edition\" | \"ticket\" | \"membership\" | \"pop\";\n\nexport interface AssetMarketContext {\n contract: string;\n tokenId: string;\n tokenName: string;\n tokenImage: string | null;\n tokenStandard: \"ERC721\" | \"ERC1155\" | \"UNKNOWN\";\n activeListings: ApiOrder[];\n quantityOwned?: string;\n mutateListings: () => void;\n}\n\nexport interface AssetMarketActions {\n isProcessing: boolean;\n buy: (order: ApiOrder) => void;\n list: () => void;\n offer: () => void;\n transfer: () => void;\n cancel: (order: ApiOrder) => void;\n acceptBid: (order: ApiOrder) => void;\n dialogs: ReactNode;\n}\n\ninterface KindConfig {\n namePrefix: string;\n accents: (typeof ASSET_ACCENTS)[keyof typeof ASSET_ACCENTS];\n market: boolean;\n remix: boolean;\n Panel?: ComponentType<AssetTypePanelProps>;\n}\n\nconst KINDS: Record<AssetKind, KindConfig> = {\n standard: { namePrefix: \"Token\", accents: ASSET_ACCENTS.standard, market: true, remix: true },\n edition: { namePrefix: \"Edition\", accents: ASSET_ACCENTS.edition, market: true, remix: false },\n ticket: { namePrefix: \"Ticket\", accents: ASSET_ACCENTS.ticket, market: true, remix: false, Panel: TicketPanel },\n membership: { namePrefix: \"Membership\", accents: ASSET_ACCENTS.membership, market: true, remix: false, Panel: MembershipPanel },\n pop: { namePrefix: \"POP\", accents: ASSET_ACCENTS.standard, market: false, remix: false },\n};\n\nconst PUBLICATION_TYPES = new Set([\"publications\", \"posts\"]);\n\ntype TraitList = { trait_type?: string | null; value?: string | number | boolean | null }[];\n\nfunction traitText(attributes: TraitList, trait: string): string | null {\n const value = attributes.find((a) => a.trait_type === trait)?.value;\n return typeof value === \"string\" && value.trim() !== \"\" ? value.trim() : null;\n}\n\nfunction publicationAuthor(attributes: TraitList, metadataAuthor?: string | null): string | null {\n return traitText(attributes, \"Author\") ?? metadataAuthor ?? traitText(attributes, \"Creator\");\n}\n\nconst VARIANT_KINDS: Partial<Record<string, AssetKind>> = { edition: \"edition\", ticket: \"ticket\", club: \"membership\", pop: \"pop\" };\n\nexport function detectAssetKind(service: string | null | undefined, standard: string | null | undefined): AssetKind {\n const variant = getService(service)?.uiVariant;\n if (variant) return VARIANT_KINDS[variant] ?? \"standard\";\n return standard === \"ERC1155\" ? \"edition\" : \"standard\";\n}\n\nexport function AssetPageSkeleton() {\n return (\n <PageContainer className=\"pt-20 pb-8\">\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-6 items-start\">\n <Skeleton className=\"aspect-square w-full rounded-3xl\" />\n <div className=\"space-y-6\">\n <div className=\"space-y-3\">\n <Skeleton className=\"h-5 w-24 rounded-full\" />\n <Skeleton className=\"h-9 w-3/4\" />\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-2/3\" />\n </div>\n <Skeleton className=\"h-[54px] w-full rounded-2xl\" />\n <div className=\"flex gap-2\">\n {Array.from({ length: 3 }).map((_, i) => <Skeleton key={i} className=\"h-[46px] flex-1 rounded-[13px]\" />)}\n </div>\n <Skeleton className=\"h-16 w-full rounded-2xl\" />\n </div>\n </div>\n </PageContainer>\n );\n}\n\nexport interface AssetPageProps {\n contract: string;\n tokenId: string;\n useMarketActions: (context: AssetMarketContext) => AssetMarketActions;\n}\n\nexport function AssetPage({ contract, tokenId, useMarketActions }: AssetPageProps) {\n const { token, isLoading, isIndexing } = useToken(contract, tokenId);\n const { collection, isLoading: collectionLoading } = useCollection(contract);\n if (isLoading || collectionLoading) return <AssetPageSkeleton />;\n if (!token) return <AssetUnavailable isIndexing={isIndexing} />;\n const kind = detectAssetKind(collection?.service, collection?.standard ?? token.standard);\n return <AssetPageView contract={contract} tokenId={tokenId} token={token} collection={collection ?? null} kind={kind} useMarketActions={useMarketActions} />;\n}\n\nfunction AssetPageView({\n contract,\n tokenId,\n token,\n collection,\n kind,\n useMarketActions,\n}: {\n contract: string;\n tokenId: string;\n token: ApiToken & { isHidden?: boolean };\n collection: ApiCollection | null;\n kind: AssetKind;\n useMarketActions: AssetPageProps[\"useMarketActions\"];\n}) {\n const resolveImage = useImageUrl();\n const config = KINDS[kind];\n const router = useRouter();\n const shouldReduce = useReducedMotion();\n const { walletAddress, ReportDialog } = useMedialaneApp();\n\n const { listings, mutate: mutateListings, isLoading: listingsLoading } = useTokenListings(contract, tokenId);\n const { history } = useTokenHistory(contract, tokenId);\n const { tokens: collectionTokens } = useNearbyCollectionTokens(contract, tokenId);\n const { total: commentTotal } = useComments(contract, tokenId);\n const { total: remixCount } = useTokenRemixes(contract, tokenId);\n const { data: fullTokenData } = useFullTokenData(contract, tokenId);\n const { amount: walletBalance } = useTokenBalance(contract, tokenId, walletAddress);\n const market = useAssetMarketState({ token, collection, listings, history: history as ApiActivity[], walletAddress, walletBalance });\n\n const [reportOpen, setReportOpen] = useState(false);\n const [commentOpen, setCommentOpen] = useState(false);\n const [lightboxOpen, setLightboxOpen] = useState(false);\n const [imgError, setImgError] = useState(false);\n\n const name = token.metadata?.name || `${config.namePrefix} #${token.tokenId}`;\n const image = resolveImage(token.metadata?.image);\n const tokenStandard = kind === \"standard\" || kind === \"pop\"\n ? ((token.standard ?? collection?.standard ?? \"UNKNOWN\") as AssetMarketContext[\"tokenStandard\"])\n : \"ERC1155\";\n\n const actions = useMarketActions({\n contract,\n tokenId,\n tokenName: name,\n tokenImage: image,\n tokenStandard,\n activeListings: market.activeListings,\n quantityOwned: market.quantityOwned,\n mutateListings,\n });\n\n const autoActionRef = useRef(false);\n useEffect(() => {\n if (autoActionRef.current || !config.market || !market.isOwner) return;\n const action = new URLSearchParams(window.location.search).get(\"action\");\n if (action === \"list\") actions.list();\n else if (action === \"transfer\") actions.transfer();\n else return;\n autoActionRef.current = true;\n }, [config.market, market.isOwner, actions]);\n\n const { attributes, hasTemplateData, isDisplayAttr, parentContract, parentTokenId } = assetAttributes(token.metadata?.attributes);\n const remixPolicy = resolveRemixPolicy({\n parentNoDerivatives: getDerivativesTerm(token.metadata?.attributes) === \"Not Allowed\",\n viewerIsParentOwner: market.isOwner,\n dealAvailable: !!getService(collection?.service),\n });\n const holders = token.balances ?? [];\n const ownerAddress = !market.isERC1155 ? (holders[0]?.owner ?? token.owner ?? null) : null;\n const marketCount = market.activeListings.length + market.activeBids.length;\n const { Panel } = config;\n\n const postContent = traitText(attributes, \"Content\");\n const articleText = postContent ?? (token.metadata?.description?.trim() || null);\n const video = (token.metadata?.ipType ?? \"\").toLowerCase() === \"video\" ? videoEmbed(attributes) : null;\n const audio = (token.metadata?.ipType ?? \"\").toLowerCase() === \"audio\" ? audioEmbed(attributes) : null;\n const isPublication = !!articleText && PUBLICATION_TYPES.has((token.metadata?.ipType ?? \"\").toLowerCase());\n const publisherName = collection?.name ?? contract.slice(0, 8) + \"…\";\n const overview = isPublication\n ? { attributes, hasTemplateData, isDisplayAttr: (a: Parameters<typeof isDisplayAttr>[0]) => isDisplayAttr(a) && !(postContent && a.trait_type === \"Content\") }\n : video || audio\n ? assetAttributes(attributes.filter((a) => !VIDEO_EMBED_TRAITS.has(a.trait_type ?? \"\") && !AUDIO_EMBED_TRAITS.has(a.trait_type ?? \"\")))\n : { attributes, hasTemplateData, isDisplayAttr };\n\n const marketBlock = (\n <>\n {Panel ? <Panel contract={contract} tokenId={tokenId} quantityOwned={market.quantityOwned} /> : null}\n\n {config.market ? (\n <AssetMarketplacePanel\n asset={token}\n compact={isPublication || !!video || !!audio}\n cheapest={market.cheapest}\n usdValue={market.cheapestUsd}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n isERC1155={market.isERC1155}\n canListMoreEditions={market.canListMoreEditions}\n isMarketLoading={listingsLoading}\n myListing={market.myListing}\n activeBids={market.activeBids}\n remixEnabled={config.remix && remixPolicy.canRemixDirect}\n showDealOption={config.remix && remixPolicy.showDealOption}\n onCancelClick={actions.cancel}\n onAcceptBid={actions.acceptBid}\n onOpenListing={actions.list}\n onOpenTransfer={actions.transfer}\n onOpenPurchase={actions.buy}\n onOpenOffer={actions.offer}\n onOpenRemix={() => router.push(`/create/remix/${contract}/${tokenId}`)}\n />\n ) : null}\n\n {kind === \"pop\" && market.isOwner ? <PopBurnButton collectionAddress={contract} tokenId={tokenId} /> : null}\n\n {market.isERC1155 && holders.length > 0 ? (\n <AssetOwnersPanel balances={holders} total={token.holderCount} editions={Number(token.supply ?? 0)} />\n ) : null}\n </>\n );\n\n const detailsBlock = (\n <div className=\"pt-5 space-y-5\">\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n {collection?.service === \"drop-collection\" ? <DropTokenLink contract={contract} name={collection.name ?? null} /> : null}\n <AssetCollectionBar\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n currentTokenId={tokenId}\n siblingTokens={collectionTokens.map((t) => ({\n tokenId: t.tokenId,\n image: resolveImage(t.metadata?.image),\n }))}\n onNavigate={(id) => router.push(assetHref(\"STARKNET\", contract, id))}\n floorPriceRaw={collection?.floorPrice}\n />\n <div className=\"-ml-3\">\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n </div>\n </div>\n );\n\n return (\n <div className=\"relative z-0 min-h-screen\">\n {token.isHidden ? <HiddenContentBanner /> : null}\n <PageBackdrop image={image} />\n\n <PageContainer className={isPublication ? \"pt-20 space-y-8 pb-8 lg:px-16 xl:px-24\" : \"pt-20 space-y-8 pb-8\"}>\n {video ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetVideo\n name={name}\n embedSrc={video.src}\n embedLabel={video.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Video\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : audio ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-12 gap-8 items-start\">\n <AssetAudio\n name={name}\n image={image}\n embedSrc={audio.src}\n embedLabel={audio.label}\n description={token.metadata?.description}\n collectionName={publisherName}\n collectionImage={resolveImage(collection?.image)}\n collectionHref={collectionHref(\"STARKNET\", contract)}\n utilities={\n <AssetUtilityIcons\n contractExplorerHref={`${EXPLORER_URL}/contract/${token.contractAddress}`}\n shareTitle={name}\n onReportClick={() => setReportOpen(true)}\n />\n }\n />\n <aside className=\"space-y-6 min-w-0\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Audio\"} size=\"md\" showLabel />\n {marketBlock}\n {ownerAddress ? <AssetOwnerRow ownerAddress={ownerAddress} ownerHref={profileHref({ address: ownerAddress })} /> : null}\n <AssetRelatedList\n title={publisherName}\n titleHref={collectionHref(\"STARKNET\", contract)}\n shape=\"square\"\n items={collectionTokens\n .filter((t) => String(t.tokenId) !== String(tokenId))\n .map((t) => ({\n tokenId: t.tokenId,\n name: t.metadata?.name || `${config.namePrefix} #${t.tokenId}`,\n image: resolveImage(t.metadata?.image),\n href: assetHref(\"STARKNET\", contract, t.tokenId),\n }))}\n />\n </aside>\n </div>\n ) : isPublication ? (\n <div className=\"grid grid-cols-1 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)] lg:gap-20 gap-8 items-start\">\n <AssetPublication\n name={name}\n text={articleText!}\n image={image}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n author={publicationAuthor(attributes, token.metadata?.author)}\n externalUrl={token.metadata?.externalUrl}\n />\n <aside className=\"space-y-6 min-w-0 lg:sticky lg:top-16\">\n <IpTypeBadge ipType={token.metadata?.ipType ?? \"Publications\"} size=\"md\" showLabel />\n {marketBlock}\n {detailsBlock}\n </aside>\n </div>\n ) : (\n <div className=\"grid grid-cols-1 lg:grid-cols-2 lg:gap-10 gap-8 items-start\">\n <AssetMediaColumn\n shouldReduce={Boolean(shouldReduce)}\n image={image}\n imageAlt={name}\n imgError={imgError}\n onImageError={() => setImgError(true)}\n onZoom={() => setLightboxOpen(true)}\n animationUrl={token.metadata?.animationUrl}\n live={isLivingRenderCollection(token.chain as Chain, token.contractAddress)}\n fallback={<div className=\"aspect-square bg-muted\" />}\n />\n\n <motion.div\n initial={shouldReduce ? false : { opacity: 0, y: 16 }}\n animate={{ opacity: 1, y: 0 }}\n transition={{ duration: 0.5, delay: 0.2 }}\n className=\"space-y-6\"\n >\n <AssetHeaderBlock\n name={name}\n description={token.metadata?.description}\n externalUrl={token.metadata?.externalUrl}\n ipType={token.metadata?.ipType}\n parentContract={parentContract}\n parentTokenId={parentTokenId}\n badges={kind === \"pop\" ? (\n <span className=\"inline-flex items-center gap-1 text-2xs font-semibold px-2.5 py-1 rounded-full border border-emerald-500/30 bg-emerald-500/10 text-emerald-500\">\n <Award className=\"h-3 w-3\" />\n POP\n </span>\n ) : null}\n />\n\n {marketBlock}\n\n {detailsBlock}\n </motion.div>\n </div>\n )}\n\n <Tabs defaultValue=\"overview\">\n <TabsList>\n <TabsTrigger value=\"overview\">Overview</TabsTrigger>\n {config.market ? <TabsTrigger value=\"markets\">Markets {marketCount > 0 && `(${marketCount})`}</TabsTrigger> : null}\n <TabsTrigger value=\"provenance\">Provenance {history.length > 0 && `(${history.length})`}</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\">\n <AssetOverviewContent attributes={overview.attributes} hasTemplateData={overview.hasTemplateData} isDisplayAttr={overview.isDisplayAttr} />\n </TabsContent>\n\n {config.market ? (\n <TabsContent value=\"markets\">\n <AssetMarketsTab\n activeListings={market.activeListings}\n activeBids={market.activeBids}\n walletAddress={walletAddress ?? undefined}\n isOwner={market.isOwner}\n isProcessing={actions.isProcessing}\n onBuyClick={actions.buy}\n onCancelClick={actions.cancel}\n onAcceptClick={actions.acceptBid}\n />\n </TabsContent>\n ) : null}\n\n <TabsContent value=\"provenance\">\n <AssetProvenanceTab\n history={history as ApiActivity[]}\n contract={contract}\n tokenId={tokenId}\n remixCount={remixCount}\n originalCreator={fullTokenData?.originalCreator}\n registeredAt={fullTokenData?.registeredAt}\n />\n </TabsContent>\n </Tabs>\n </PageContainer>\n\n <AssetLightbox open={lightboxOpen} onOpenChange={setLightboxOpen} image={image} alt={name} />\n <FloatingCommentsButton onClick={() => setCommentOpen(true)} commentTotal={commentTotal} />\n <AssetCommentsDialog\n open={commentOpen}\n onOpenChange={setCommentOpen}\n contract={contract}\n tokenId={tokenId}\n name={name}\n imageUrl={image}\n commentTotal={commentTotal}\n {...config.accents}\n />\n {ReportDialog ? <ReportDialog open={reportOpen} onOpenChange={setReportOpen} target={{ type: \"TOKEN\", contract: token.contractAddress, tokenId: token.tokenId, name }} /> : null}\n {actions.dialogs}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -29,12 +29,10 @@ var import_external_link = require("../utils/external-link.js");
29
29
  function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }) {
30
30
  const link = (0, import_external_link.externalLink)(externalUrl);
31
31
  const paragraphs = text.split(/\n{2,}/).map((p) => p.trim()).filter(Boolean);
32
- const [lead, ...body] = paragraphs.length > 1 ? paragraphs : [null, ...paragraphs];
33
32
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "min-w-0 space-y-6", children: [
34
33
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("header", { className: "space-y-3", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { className: "text-2xl lg:text-4xl font-bold leading-tight break-words", children: name }) }),
35
- lead ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "max-w-3xl text-base leading-relaxed text-foreground whitespace-pre-line", children: lead }) : null,
36
34
  image && !imgError ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", onClick: onZoom, "aria-label": "View full image", className: "block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("img", { src: image, alt: name, onError: onImageError, className: "w-full h-auto max-h-[80vh] object-contain" }) }) : null,
37
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "max-w-3xl space-y-4 text-sm leading-relaxed text-foreground/85 break-words", children: body.map((paragraph, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "whitespace-pre-line", children: paragraph }, i)) }),
35
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "max-w-3xl space-y-4 text-base leading-relaxed text-foreground break-words", children: paragraphs.map((paragraph, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "whitespace-pre-line", children: paragraph }, i)) }),
38
36
  author || link ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-wrap items-center gap-4", children: [
39
37
  author ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "min-w-0 break-words text-sm text-muted-foreground", children: author }) : null,
40
38
  link ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_button.Button, { asChild: true, variant: "outline", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("a", { href: link, target: "_blank", rel: "noopener noreferrer", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-publication.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"./button.js\";\nimport { externalLink } from \"../utils/external-link.js\";\n\nexport interface AssetPublicationProps {\n name: string;\n text: string;\n image: string | null;\n imgError: boolean;\n onImageError: () => void;\n onZoom: () => void;\n author?: string | null;\n externalUrl?: string | null;\n}\n\nexport function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }: AssetPublicationProps) {\n const link = externalLink(externalUrl);\n const paragraphs = text.split(/\\n{2,}/).map((p) => p.trim()).filter(Boolean);\n const [lead, ...body] = paragraphs.length > 1 ? paragraphs : [null, ...paragraphs];\n\n return (\n <article className=\"min-w-0 space-y-6\">\n <header className=\"space-y-3\">\n <h1 className=\"text-2xl lg:text-4xl font-bold leading-tight break-words\">{name}</h1>\n </header>\n\n {lead ? <p className=\"max-w-3xl text-base leading-relaxed text-foreground whitespace-pre-line\">{lead}</p> : null}\n\n {image && !imgError ? (\n <button type=\"button\" onClick={onZoom} aria-label=\"View full image\" className=\"block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\">\n <img src={image} alt={name} onError={onImageError} className=\"w-full h-auto max-h-[80vh] object-contain\" />\n </button>\n ) : null}\n\n <div className=\"max-w-3xl space-y-4 text-sm leading-relaxed text-foreground/85 break-words\">\n {body.map((paragraph, i) => (\n <p key={i} className=\"whitespace-pre-line\">{paragraph}</p>\n ))}\n </div>\n\n {author || link ? (\n <div className=\"flex flex-wrap items-center gap-4\">\n {author ? <p className=\"min-w-0 break-words text-sm text-muted-foreground\">{author}</p> : null}\n {link ? (\n <Button asChild variant=\"outline\">\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\">\n Read more\n <ExternalLink />\n </a>\n </Button>\n ) : null}\n </div>\n ) : null}\n </article>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAyBQ;AAvBR,0BAA6B;AAC7B,oBAAuB;AACvB,2BAA6B;AAatB,SAAS,iBAAiB,EAAE,MAAM,MAAM,OAAO,UAAU,cAAc,QAAQ,QAAQ,YAAY,GAA0B;AAClI,QAAM,WAAO,mCAAa,WAAW;AACrC,QAAM,aAAa,KAAK,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAC3E,QAAM,CAAC,MAAM,GAAG,IAAI,IAAI,WAAW,SAAS,IAAI,aAAa,CAAC,MAAM,GAAG,UAAU;AAEjF,SACE,6CAAC,aAAQ,WAAU,qBACjB;AAAA,gDAAC,YAAO,WAAU,aAChB,sDAAC,QAAG,WAAU,4DAA4D,gBAAK,GACjF;AAAA,IAEC,OAAO,4CAAC,OAAE,WAAU,2EAA2E,gBAAK,IAAO;AAAA,IAE3G,SAAS,CAAC,WACT,4CAAC,YAAO,MAAK,UAAS,SAAS,QAAQ,cAAW,mBAAkB,WAAU,8EAC5E,sDAAC,SAAI,KAAK,OAAO,KAAK,MAAM,SAAS,cAAc,WAAU,6CAA4C,GAC3G,IACE;AAAA,IAEJ,4CAAC,SAAI,WAAU,8EACZ,eAAK,IAAI,CAAC,WAAW,MACpB,4CAAC,OAAU,WAAU,uBAAuB,uBAApC,CAA8C,CACvD,GACH;AAAA,IAEC,UAAU,OACT,6CAAC,SAAI,WAAU,qCACZ;AAAA,eAAS,4CAAC,OAAE,WAAU,qDAAqD,kBAAO,IAAO;AAAA,MACzF,OACC,4CAAC,wBAAO,SAAO,MAAC,SAAQ,WACtB,uDAAC,OAAE,MAAM,MAAM,QAAO,UAAS,KAAI,uBAAsB;AAAA;AAAA,QAEvD,4CAAC,oCAAa;AAAA,SAChB,GACF,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/asset-publication.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"./button.js\";\nimport { externalLink } from \"../utils/external-link.js\";\n\nexport interface AssetPublicationProps {\n name: string;\n text: string;\n image: string | null;\n imgError: boolean;\n onImageError: () => void;\n onZoom: () => void;\n author?: string | null;\n externalUrl?: string | null;\n}\n\nexport function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }: AssetPublicationProps) {\n const link = externalLink(externalUrl);\n const paragraphs = text.split(/\\n{2,}/).map((p) => p.trim()).filter(Boolean);\n\n return (\n <article className=\"min-w-0 space-y-6\">\n <header className=\"space-y-3\">\n <h1 className=\"text-2xl lg:text-4xl font-bold leading-tight break-words\">{name}</h1>\n </header>\n\n {image && !imgError ? (\n <button type=\"button\" onClick={onZoom} aria-label=\"View full image\" className=\"block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\">\n <img src={image} alt={name} onError={onImageError} className=\"w-full h-auto max-h-[80vh] object-contain\" />\n </button>\n ) : null}\n\n <div className=\"max-w-3xl space-y-4 text-base leading-relaxed text-foreground break-words\">\n {paragraphs.map((paragraph, i) => (\n <p key={i} className=\"whitespace-pre-line\">{paragraph}</p>\n ))}\n </div>\n\n {author || link ? (\n <div className=\"flex flex-wrap items-center gap-4\">\n {author ? <p className=\"min-w-0 break-words text-sm text-muted-foreground\">{author}</p> : null}\n {link ? (\n <Button asChild variant=\"outline\">\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\">\n Read more\n <ExternalLink />\n </a>\n </Button>\n ) : null}\n </div>\n ) : null}\n </article>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBQ;AAtBR,0BAA6B;AAC7B,oBAAuB;AACvB,2BAA6B;AAatB,SAAS,iBAAiB,EAAE,MAAM,MAAM,OAAO,UAAU,cAAc,QAAQ,QAAQ,YAAY,GAA0B;AAClI,QAAM,WAAO,mCAAa,WAAW;AACrC,QAAM,aAAa,KAAK,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAE3E,SACE,6CAAC,aAAQ,WAAU,qBACjB;AAAA,gDAAC,YAAO,WAAU,aAChB,sDAAC,QAAG,WAAU,4DAA4D,gBAAK,GACjF;AAAA,IAEC,SAAS,CAAC,WACT,4CAAC,YAAO,MAAK,UAAS,SAAS,QAAQ,cAAW,mBAAkB,WAAU,8EAC5E,sDAAC,SAAI,KAAK,OAAO,KAAK,MAAM,SAAS,cAAc,WAAU,6CAA4C,GAC3G,IACE;AAAA,IAEJ,4CAAC,SAAI,WAAU,6EACZ,qBAAW,IAAI,CAAC,WAAW,MAC1B,4CAAC,OAAU,WAAU,uBAAuB,uBAApC,CAA8C,CACvD,GACH;AAAA,IAEC,UAAU,OACT,6CAAC,SAAI,WAAU,qCACZ;AAAA,eAAS,4CAAC,OAAE,WAAU,qDAAqD,kBAAO,IAAO;AAAA,MACzF,OACC,4CAAC,wBAAO,SAAO,MAAC,SAAQ,WACtB,uDAAC,OAAE,MAAM,MAAM,QAAO,UAAS,KAAI,uBAAsB;AAAA;AAAA,QAEvD,4CAAC,oCAAa;AAAA,SAChB,GACF,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;","names":[]}
@@ -6,12 +6,10 @@ import { externalLink } from "../utils/external-link.js";
6
6
  function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }) {
7
7
  const link = externalLink(externalUrl);
8
8
  const paragraphs = text.split(/\n{2,}/).map((p) => p.trim()).filter(Boolean);
9
- const [lead, ...body] = paragraphs.length > 1 ? paragraphs : [null, ...paragraphs];
10
9
  return /* @__PURE__ */ jsxs("article", { className: "min-w-0 space-y-6", children: [
11
10
  /* @__PURE__ */ jsx("header", { className: "space-y-3", children: /* @__PURE__ */ jsx("h1", { className: "text-2xl lg:text-4xl font-bold leading-tight break-words", children: name }) }),
12
- lead ? /* @__PURE__ */ jsx("p", { className: "max-w-3xl text-base leading-relaxed text-foreground whitespace-pre-line", children: lead }) : null,
13
11
  image && !imgError ? /* @__PURE__ */ jsx("button", { type: "button", onClick: onZoom, "aria-label": "View full image", className: "block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none", children: /* @__PURE__ */ jsx("img", { src: image, alt: name, onError: onImageError, className: "w-full h-auto max-h-[80vh] object-contain" }) }) : null,
14
- /* @__PURE__ */ jsx("div", { className: "max-w-3xl space-y-4 text-sm leading-relaxed text-foreground/85 break-words", children: body.map((paragraph, i) => /* @__PURE__ */ jsx("p", { className: "whitespace-pre-line", children: paragraph }, i)) }),
12
+ /* @__PURE__ */ jsx("div", { className: "max-w-3xl space-y-4 text-base leading-relaxed text-foreground break-words", children: paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx("p", { className: "whitespace-pre-line", children: paragraph }, i)) }),
15
13
  author || link ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-4", children: [
16
14
  author ? /* @__PURE__ */ jsx("p", { className: "min-w-0 break-words text-sm text-muted-foreground", children: author }) : null,
17
15
  link ? /* @__PURE__ */ jsx(Button, { asChild: true, variant: "outline", children: /* @__PURE__ */ jsxs("a", { href: link, target: "_blank", rel: "noopener noreferrer", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/asset-publication.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"./button.js\";\nimport { externalLink } from \"../utils/external-link.js\";\n\nexport interface AssetPublicationProps {\n name: string;\n text: string;\n image: string | null;\n imgError: boolean;\n onImageError: () => void;\n onZoom: () => void;\n author?: string | null;\n externalUrl?: string | null;\n}\n\nexport function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }: AssetPublicationProps) {\n const link = externalLink(externalUrl);\n const paragraphs = text.split(/\\n{2,}/).map((p) => p.trim()).filter(Boolean);\n const [lead, ...body] = paragraphs.length > 1 ? paragraphs : [null, ...paragraphs];\n\n return (\n <article className=\"min-w-0 space-y-6\">\n <header className=\"space-y-3\">\n <h1 className=\"text-2xl lg:text-4xl font-bold leading-tight break-words\">{name}</h1>\n </header>\n\n {lead ? <p className=\"max-w-3xl text-base leading-relaxed text-foreground whitespace-pre-line\">{lead}</p> : null}\n\n {image && !imgError ? (\n <button type=\"button\" onClick={onZoom} aria-label=\"View full image\" className=\"block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\">\n <img src={image} alt={name} onError={onImageError} className=\"w-full h-auto max-h-[80vh] object-contain\" />\n </button>\n ) : null}\n\n <div className=\"max-w-3xl space-y-4 text-sm leading-relaxed text-foreground/85 break-words\">\n {body.map((paragraph, i) => (\n <p key={i} className=\"whitespace-pre-line\">{paragraph}</p>\n ))}\n </div>\n\n {author || link ? (\n <div className=\"flex flex-wrap items-center gap-4\">\n {author ? <p className=\"min-w-0 break-words text-sm text-muted-foreground\">{author}</p> : null}\n {link ? (\n <Button asChild variant=\"outline\">\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\">\n Read more\n <ExternalLink />\n </a>\n </Button>\n ) : null}\n </div>\n ) : null}\n </article>\n );\n}\n"],"mappings":";AAyBQ,cAsBM,YAtBN;AAvBR,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAatB,SAAS,iBAAiB,EAAE,MAAM,MAAM,OAAO,UAAU,cAAc,QAAQ,QAAQ,YAAY,GAA0B;AAClI,QAAM,OAAO,aAAa,WAAW;AACrC,QAAM,aAAa,KAAK,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAC3E,QAAM,CAAC,MAAM,GAAG,IAAI,IAAI,WAAW,SAAS,IAAI,aAAa,CAAC,MAAM,GAAG,UAAU;AAEjF,SACE,qBAAC,aAAQ,WAAU,qBACjB;AAAA,wBAAC,YAAO,WAAU,aAChB,8BAAC,QAAG,WAAU,4DAA4D,gBAAK,GACjF;AAAA,IAEC,OAAO,oBAAC,OAAE,WAAU,2EAA2E,gBAAK,IAAO;AAAA,IAE3G,SAAS,CAAC,WACT,oBAAC,YAAO,MAAK,UAAS,SAAS,QAAQ,cAAW,mBAAkB,WAAU,8EAC5E,8BAAC,SAAI,KAAK,OAAO,KAAK,MAAM,SAAS,cAAc,WAAU,6CAA4C,GAC3G,IACE;AAAA,IAEJ,oBAAC,SAAI,WAAU,8EACZ,eAAK,IAAI,CAAC,WAAW,MACpB,oBAAC,OAAU,WAAU,uBAAuB,uBAApC,CAA8C,CACvD,GACH;AAAA,IAEC,UAAU,OACT,qBAAC,SAAI,WAAU,qCACZ;AAAA,eAAS,oBAAC,OAAE,WAAU,qDAAqD,kBAAO,IAAO;AAAA,MACzF,OACC,oBAAC,UAAO,SAAO,MAAC,SAAQ,WACtB,+BAAC,OAAE,MAAM,MAAM,QAAO,UAAS,KAAI,uBAAsB;AAAA;AAAA,QAEvD,oBAAC,gBAAa;AAAA,SAChB,GACF,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/components/asset-publication.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { Button } from \"./button.js\";\nimport { externalLink } from \"../utils/external-link.js\";\n\nexport interface AssetPublicationProps {\n name: string;\n text: string;\n image: string | null;\n imgError: boolean;\n onImageError: () => void;\n onZoom: () => void;\n author?: string | null;\n externalUrl?: string | null;\n}\n\nexport function AssetPublication({ name, text, image, imgError, onImageError, onZoom, author, externalUrl }: AssetPublicationProps) {\n const link = externalLink(externalUrl);\n const paragraphs = text.split(/\\n{2,}/).map((p) => p.trim()).filter(Boolean);\n\n return (\n <article className=\"min-w-0 space-y-6\">\n <header className=\"space-y-3\">\n <h1 className=\"text-2xl lg:text-4xl font-bold leading-tight break-words\">{name}</h1>\n </header>\n\n {image && !imgError ? (\n <button type=\"button\" onClick={onZoom} aria-label=\"View full image\" className=\"block w-full overflow-hidden rounded-3xl cursor-zoom-in focus:outline-none\">\n <img src={image} alt={name} onError={onImageError} className=\"w-full h-auto max-h-[80vh] object-contain\" />\n </button>\n ) : null}\n\n <div className=\"max-w-3xl space-y-4 text-base leading-relaxed text-foreground break-words\">\n {paragraphs.map((paragraph, i) => (\n <p key={i} className=\"whitespace-pre-line\">{paragraph}</p>\n ))}\n </div>\n\n {author || link ? (\n <div className=\"flex flex-wrap items-center gap-4\">\n {author ? <p className=\"min-w-0 break-words text-sm text-muted-foreground\">{author}</p> : null}\n {link ? (\n <Button asChild variant=\"outline\">\n <a href={link} target=\"_blank\" rel=\"noopener noreferrer\">\n Read more\n <ExternalLink />\n </a>\n </Button>\n ) : null}\n </div>\n ) : null}\n </article>\n );\n}\n"],"mappings":";AAwBQ,cAoBM,YApBN;AAtBR,SAAS,oBAAoB;AAC7B,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAatB,SAAS,iBAAiB,EAAE,MAAM,MAAM,OAAO,UAAU,cAAc,QAAQ,QAAQ,YAAY,GAA0B;AAClI,QAAM,OAAO,aAAa,WAAW;AACrC,QAAM,aAAa,KAAK,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO;AAE3E,SACE,qBAAC,aAAQ,WAAU,qBACjB;AAAA,wBAAC,YAAO,WAAU,aAChB,8BAAC,QAAG,WAAU,4DAA4D,gBAAK,GACjF;AAAA,IAEC,SAAS,CAAC,WACT,oBAAC,YAAO,MAAK,UAAS,SAAS,QAAQ,cAAW,mBAAkB,WAAU,8EAC5E,8BAAC,SAAI,KAAK,OAAO,KAAK,MAAM,SAAS,cAAc,WAAU,6CAA4C,GAC3G,IACE;AAAA,IAEJ,oBAAC,SAAI,WAAU,6EACZ,qBAAW,IAAI,CAAC,WAAW,MAC1B,oBAAC,OAAU,WAAU,uBAAuB,uBAApC,CAA8C,CACvD,GACH;AAAA,IAEC,UAAU,OACT,qBAAC,SAAI,WAAU,qCACZ;AAAA,eAAS,oBAAC,OAAE,WAAU,qDAAqD,kBAAO,IAAO;AAAA,MACzF,OACC,oBAAC,UAAO,SAAO,MAAC,SAAQ,WACtB,+BAAC,OAAE,MAAM,MAAM,QAAO,UAAS,KAAI,uBAAsB;AAAA;AAAA,QAEvD,oBAAC,gBAAa;AAAA,SAChB,GACF,IACE;AAAA,OACN,IACE;AAAA,KACN;AAEJ;","names":[]}
@@ -63,7 +63,7 @@ function ExportKeySection({ loadSealed, unlock, describeError }) {
63
63
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-3", children: [
64
64
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
65
65
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "text-sm font-semibold", children: "Recovery key" }),
66
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-1 text-xs text-muted-foreground leading-relaxed", children: "Save this somewhere private, such as a password manager. It restores your account if you lose access to every device you use. To start using a new phone or browser, approve it from a device you already have." })
66
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mt-1 text-xs text-muted-foreground leading-relaxed", children: "Save this somewhere private, such as a password manager. Paste it when you sign in on a new phone or browser, or if you lose access to every device you use." })
67
67
  ] }),
68
68
  recoveryKey ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
69
69
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_alert.Alert, { variant: "destructive", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/wallet/export-key-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { KeyRound, Copy, Check, EyeOff, Loader2, ShieldAlert } from \"lucide-react\";\nimport { encodeRecoveryKey, type SealedOwner } from \"@medialane/sdk/starknet\";\nimport { Button } from \"../button.js\";\nimport { Alert, AlertDescription } from \"../alert.js\";\n\nexport interface ExportKeySectionProps {\n loadSealed: () => SealedOwner | null;\n unlock: (sealed: SealedOwner) => Promise<string>;\n describeError?: (err: unknown, fallback: string) => string;\n}\n\nexport function ExportKeySection({ loadSealed, unlock, describeError }: ExportKeySectionProps) {\n const [recoveryKey, setRecoveryKey] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [copied, setCopied] = useState(false);\n\n const reveal = async () => {\n setBusy(true);\n setError(null);\n try {\n const sealed = loadSealed();\n if (!sealed) {\n setError(\"This browser has no wallet key stored.\");\n return;\n }\n setRecoveryKey(encodeRecoveryKey({ walletAddress: sealed.address, privateKey: await unlock(sealed) }));\n } catch (err) {\n const fallback = \"Could not unlock your key. Please try again.\";\n setError(describeError ? describeError(err, fallback) : fallback);\n } finally {\n setBusy(false);\n }\n };\n\n const copy = async () => {\n if (!recoveryKey) return;\n await navigator.clipboard.writeText(recoveryKey);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n const hide = () => {\n setRecoveryKey(null);\n setCopied(false);\n };\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div>\n <p className=\"text-sm font-semibold\">Recovery key</p>\n <p className=\"mt-1 text-xs text-muted-foreground leading-relaxed\">\n Save this somewhere private, such as a password manager. It restores your account if you\n lose access to every device you use. To start using a new phone or browser, approve it\n from a device you already have.\n </p>\n </div>\n\n {recoveryKey ? (\n <>\n <Alert variant=\"destructive\">\n <ShieldAlert className=\"h-4 w-4\" />\n <AlertDescription className=\"text-xs leading-relaxed\">\n <span className=\"font-semibold\">Anyone with this key controls your wallet.</span>{\" \"}\n Medialane will never ask you for it. Treat any message requesting it as an attempt to\n take your assets.\n </AlertDescription>\n </Alert>\n <code className=\"block break-all rounded-xl bg-muted px-3 py-2.5 font-mono text-xs select-all\">\n {recoveryKey}\n </code>\n <div className=\"flex items-center gap-2\">\n <Button onClick={copy} variant=\"outline\" size=\"sm\">\n {copied ? <Check className=\"mr-1.5 h-3.5 w-3.5\" /> : <Copy className=\"mr-1.5 h-3.5 w-3.5\" />}\n {copied ? \"Copied\" : \"Copy key\"}\n </Button>\n <Button onClick={hide} variant=\"ghost\" size=\"sm\">\n <EyeOff className=\"mr-1.5 h-3.5 w-3.5\" />\n Hide\n </Button>\n </div>\n </>\n ) : (\n <>\n {error && <p className=\"text-sm text-destructive\">{error}</p>}\n <Button onClick={reveal} disabled={busy} variant=\"outline\" size=\"sm\" className=\"self-start\">\n {busy ? <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" /> : <KeyRound className=\"mr-1.5 h-3.5 w-3.5\" />}\n Show recovery key\n </Button>\n </>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoDM;AAlDN,mBAAyB;AACzB,0BAAoE;AACpE,sBAAoD;AACpD,oBAAuB;AACvB,mBAAwC;AAQjC,SAAS,iBAAiB,EAAE,YAAY,QAAQ,cAAc,GAA0B;AAC7F,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAwB,IAAI;AAClE,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAS,KAAK;AACtC,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAwB,IAAI;AACtD,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAE1C,QAAM,SAAS,YAAY;AACzB,YAAQ,IAAI;AACZ,aAAS,IAAI;AACb,QAAI;AACF,YAAM,SAAS,WAAW;AAC1B,UAAI,CAAC,QAAQ;AACX,iBAAS,wCAAwC;AACjD;AAAA,MACF;AACA,yBAAe,mCAAkB,EAAE,eAAe,OAAO,SAAS,YAAY,MAAM,OAAO,MAAM,EAAE,CAAC,CAAC;AAAA,IACvG,SAAS,KAAK;AACZ,YAAM,WAAW;AACjB,eAAS,gBAAgB,cAAc,KAAK,QAAQ,IAAI,QAAQ;AAAA,IAClE,UAAE;AACA,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,QAAM,OAAO,YAAY;AACvB,QAAI,CAAC,YAAa;AAClB,UAAM,UAAU,UAAU,UAAU,WAAW;AAC/C,cAAU,IAAI;AACd,eAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,EACzC;AAEA,QAAM,OAAO,MAAM;AACjB,mBAAe,IAAI;AACnB,cAAU,KAAK;AAAA,EACjB;AAEA,SACE,6CAAC,SAAI,WAAU,uBACb;AAAA,iDAAC,SACC;AAAA,kDAAC,OAAE,WAAU,yBAAwB,0BAAY;AAAA,MACjD,4CAAC,OAAE,WAAU,sDAAqD,6NAIlE;AAAA,OACF;AAAA,IAEC,cACC,4EACE;AAAA,mDAAC,sBAAM,SAAQ,eACb;AAAA,oDAAC,mCAAY,WAAU,WAAU;AAAA,QACjC,6CAAC,iCAAiB,WAAU,2BAC1B;AAAA,sDAAC,UAAK,WAAU,iBAAgB,wDAA0C;AAAA,UAAQ;AAAA,UAAI;AAAA,WAGxF;AAAA,SACF;AAAA,MACA,4CAAC,UAAK,WAAU,gFACb,uBACH;AAAA,MACA,6CAAC,SAAI,WAAU,2BACb;AAAA,qDAAC,wBAAO,SAAS,MAAM,SAAQ,WAAU,MAAK,MAC3C;AAAA,mBAAS,4CAAC,6BAAM,WAAU,sBAAqB,IAAK,4CAAC,4BAAK,WAAU,sBAAqB;AAAA,UACzF,SAAS,WAAW;AAAA,WACvB;AAAA,QACA,6CAAC,wBAAO,SAAS,MAAM,SAAQ,SAAQ,MAAK,MAC1C;AAAA,sDAAC,8BAAO,WAAU,sBAAqB;AAAA,UAAE;AAAA,WAE3C;AAAA,SACF;AAAA,OACF,IAEA,4EACG;AAAA,eAAS,4CAAC,OAAE,WAAU,4BAA4B,iBAAM;AAAA,MACzD,6CAAC,wBAAO,SAAS,QAAQ,UAAU,MAAM,SAAQ,WAAU,MAAK,MAAK,WAAU,cAC5E;AAAA,eAAO,4CAAC,+BAAQ,WAAU,mCAAkC,IAAK,4CAAC,gCAAS,WAAU,sBAAqB;AAAA,QAAG;AAAA,SAEhH;AAAA,OACF;AAAA,KAEJ;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/wallet/export-key-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { KeyRound, Copy, Check, EyeOff, Loader2, ShieldAlert } from \"lucide-react\";\nimport { encodeRecoveryKey, type SealedOwner } from \"@medialane/sdk/starknet\";\nimport { Button } from \"../button.js\";\nimport { Alert, AlertDescription } from \"../alert.js\";\n\nexport interface ExportKeySectionProps {\n loadSealed: () => SealedOwner | null;\n unlock: (sealed: SealedOwner) => Promise<string>;\n describeError?: (err: unknown, fallback: string) => string;\n}\n\nexport function ExportKeySection({ loadSealed, unlock, describeError }: ExportKeySectionProps) {\n const [recoveryKey, setRecoveryKey] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [copied, setCopied] = useState(false);\n\n const reveal = async () => {\n setBusy(true);\n setError(null);\n try {\n const sealed = loadSealed();\n if (!sealed) {\n setError(\"This browser has no wallet key stored.\");\n return;\n }\n setRecoveryKey(encodeRecoveryKey({ walletAddress: sealed.address, privateKey: await unlock(sealed) }));\n } catch (err) {\n const fallback = \"Could not unlock your key. Please try again.\";\n setError(describeError ? describeError(err, fallback) : fallback);\n } finally {\n setBusy(false);\n }\n };\n\n const copy = async () => {\n if (!recoveryKey) return;\n await navigator.clipboard.writeText(recoveryKey);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n const hide = () => {\n setRecoveryKey(null);\n setCopied(false);\n };\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div>\n <p className=\"text-sm font-semibold\">Recovery key</p>\n <p className=\"mt-1 text-xs text-muted-foreground leading-relaxed\">\n Save this somewhere private, such as a password manager. Paste it when you sign in on a\n new phone or browser, or if you lose access to every device you use.\n </p>\n </div>\n\n {recoveryKey ? (\n <>\n <Alert variant=\"destructive\">\n <ShieldAlert className=\"h-4 w-4\" />\n <AlertDescription className=\"text-xs leading-relaxed\">\n <span className=\"font-semibold\">Anyone with this key controls your wallet.</span>{\" \"}\n Medialane will never ask you for it. Treat any message requesting it as an attempt to\n take your assets.\n </AlertDescription>\n </Alert>\n <code className=\"block break-all rounded-xl bg-muted px-3 py-2.5 font-mono text-xs select-all\">\n {recoveryKey}\n </code>\n <div className=\"flex items-center gap-2\">\n <Button onClick={copy} variant=\"outline\" size=\"sm\">\n {copied ? <Check className=\"mr-1.5 h-3.5 w-3.5\" /> : <Copy className=\"mr-1.5 h-3.5 w-3.5\" />}\n {copied ? \"Copied\" : \"Copy key\"}\n </Button>\n <Button onClick={hide} variant=\"ghost\" size=\"sm\">\n <EyeOff className=\"mr-1.5 h-3.5 w-3.5\" />\n Hide\n </Button>\n </div>\n </>\n ) : (\n <>\n {error && <p className=\"text-sm text-destructive\">{error}</p>}\n <Button onClick={reveal} disabled={busy} variant=\"outline\" size=\"sm\" className=\"self-start\">\n {busy ? <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" /> : <KeyRound className=\"mr-1.5 h-3.5 w-3.5\" />}\n Show recovery key\n </Button>\n </>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoDM;AAlDN,mBAAyB;AACzB,0BAAoE;AACpE,sBAAoD;AACpD,oBAAuB;AACvB,mBAAwC;AAQjC,SAAS,iBAAiB,EAAE,YAAY,QAAQ,cAAc,GAA0B;AAC7F,QAAM,CAAC,aAAa,cAAc,QAAI,uBAAwB,IAAI;AAClE,QAAM,CAAC,MAAM,OAAO,QAAI,uBAAS,KAAK;AACtC,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAAwB,IAAI;AACtD,QAAM,CAAC,QAAQ,SAAS,QAAI,uBAAS,KAAK;AAE1C,QAAM,SAAS,YAAY;AACzB,YAAQ,IAAI;AACZ,aAAS,IAAI;AACb,QAAI;AACF,YAAM,SAAS,WAAW;AAC1B,UAAI,CAAC,QAAQ;AACX,iBAAS,wCAAwC;AACjD;AAAA,MACF;AACA,yBAAe,mCAAkB,EAAE,eAAe,OAAO,SAAS,YAAY,MAAM,OAAO,MAAM,EAAE,CAAC,CAAC;AAAA,IACvG,SAAS,KAAK;AACZ,YAAM,WAAW;AACjB,eAAS,gBAAgB,cAAc,KAAK,QAAQ,IAAI,QAAQ;AAAA,IAClE,UAAE;AACA,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,QAAM,OAAO,YAAY;AACvB,QAAI,CAAC,YAAa;AAClB,UAAM,UAAU,UAAU,UAAU,WAAW;AAC/C,cAAU,IAAI;AACd,eAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,EACzC;AAEA,QAAM,OAAO,MAAM;AACjB,mBAAe,IAAI;AACnB,cAAU,KAAK;AAAA,EACjB;AAEA,SACE,6CAAC,SAAI,WAAU,uBACb;AAAA,iDAAC,SACC;AAAA,kDAAC,OAAE,WAAU,yBAAwB,0BAAY;AAAA,MACjD,4CAAC,OAAE,WAAU,sDAAqD,0KAGlE;AAAA,OACF;AAAA,IAEC,cACC,4EACE;AAAA,mDAAC,sBAAM,SAAQ,eACb;AAAA,oDAAC,mCAAY,WAAU,WAAU;AAAA,QACjC,6CAAC,iCAAiB,WAAU,2BAC1B;AAAA,sDAAC,UAAK,WAAU,iBAAgB,wDAA0C;AAAA,UAAQ;AAAA,UAAI;AAAA,WAGxF;AAAA,SACF;AAAA,MACA,4CAAC,UAAK,WAAU,gFACb,uBACH;AAAA,MACA,6CAAC,SAAI,WAAU,2BACb;AAAA,qDAAC,wBAAO,SAAS,MAAM,SAAQ,WAAU,MAAK,MAC3C;AAAA,mBAAS,4CAAC,6BAAM,WAAU,sBAAqB,IAAK,4CAAC,4BAAK,WAAU,sBAAqB;AAAA,UACzF,SAAS,WAAW;AAAA,WACvB;AAAA,QACA,6CAAC,wBAAO,SAAS,MAAM,SAAQ,SAAQ,MAAK,MAC1C;AAAA,sDAAC,8BAAO,WAAU,sBAAqB;AAAA,UAAE;AAAA,WAE3C;AAAA,SACF;AAAA,OACF,IAEA,4EACG;AAAA,eAAS,4CAAC,OAAE,WAAU,4BAA4B,iBAAM;AAAA,MACzD,6CAAC,wBAAO,SAAS,QAAQ,UAAU,MAAM,SAAQ,WAAU,MAAK,MAAK,WAAU,cAC5E;AAAA,eAAO,4CAAC,+BAAQ,WAAU,mCAAkC,IAAK,4CAAC,gCAAS,WAAU,sBAAqB;AAAA,QAAG;AAAA,SAEhH;AAAA,OACF;AAAA,KAEJ;AAEJ;","names":[]}
@@ -40,7 +40,7 @@ function ExportKeySection({ loadSealed, unlock, describeError }) {
40
40
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
41
41
  /* @__PURE__ */ jsxs("div", { children: [
42
42
  /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Recovery key" }),
43
- /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-muted-foreground leading-relaxed", children: "Save this somewhere private, such as a password manager. It restores your account if you lose access to every device you use. To start using a new phone or browser, approve it from a device you already have." })
43
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs text-muted-foreground leading-relaxed", children: "Save this somewhere private, such as a password manager. Paste it when you sign in on a new phone or browser, or if you lose access to every device you use." })
44
44
  ] }),
45
45
  recoveryKey ? /* @__PURE__ */ jsxs(Fragment, { children: [
46
46
  /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/wallet/export-key-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { KeyRound, Copy, Check, EyeOff, Loader2, ShieldAlert } from \"lucide-react\";\nimport { encodeRecoveryKey, type SealedOwner } from \"@medialane/sdk/starknet\";\nimport { Button } from \"../button.js\";\nimport { Alert, AlertDescription } from \"../alert.js\";\n\nexport interface ExportKeySectionProps {\n loadSealed: () => SealedOwner | null;\n unlock: (sealed: SealedOwner) => Promise<string>;\n describeError?: (err: unknown, fallback: string) => string;\n}\n\nexport function ExportKeySection({ loadSealed, unlock, describeError }: ExportKeySectionProps) {\n const [recoveryKey, setRecoveryKey] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [copied, setCopied] = useState(false);\n\n const reveal = async () => {\n setBusy(true);\n setError(null);\n try {\n const sealed = loadSealed();\n if (!sealed) {\n setError(\"This browser has no wallet key stored.\");\n return;\n }\n setRecoveryKey(encodeRecoveryKey({ walletAddress: sealed.address, privateKey: await unlock(sealed) }));\n } catch (err) {\n const fallback = \"Could not unlock your key. Please try again.\";\n setError(describeError ? describeError(err, fallback) : fallback);\n } finally {\n setBusy(false);\n }\n };\n\n const copy = async () => {\n if (!recoveryKey) return;\n await navigator.clipboard.writeText(recoveryKey);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n const hide = () => {\n setRecoveryKey(null);\n setCopied(false);\n };\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div>\n <p className=\"text-sm font-semibold\">Recovery key</p>\n <p className=\"mt-1 text-xs text-muted-foreground leading-relaxed\">\n Save this somewhere private, such as a password manager. It restores your account if you\n lose access to every device you use. To start using a new phone or browser, approve it\n from a device you already have.\n </p>\n </div>\n\n {recoveryKey ? (\n <>\n <Alert variant=\"destructive\">\n <ShieldAlert className=\"h-4 w-4\" />\n <AlertDescription className=\"text-xs leading-relaxed\">\n <span className=\"font-semibold\">Anyone with this key controls your wallet.</span>{\" \"}\n Medialane will never ask you for it. Treat any message requesting it as an attempt to\n take your assets.\n </AlertDescription>\n </Alert>\n <code className=\"block break-all rounded-xl bg-muted px-3 py-2.5 font-mono text-xs select-all\">\n {recoveryKey}\n </code>\n <div className=\"flex items-center gap-2\">\n <Button onClick={copy} variant=\"outline\" size=\"sm\">\n {copied ? <Check className=\"mr-1.5 h-3.5 w-3.5\" /> : <Copy className=\"mr-1.5 h-3.5 w-3.5\" />}\n {copied ? \"Copied\" : \"Copy key\"}\n </Button>\n <Button onClick={hide} variant=\"ghost\" size=\"sm\">\n <EyeOff className=\"mr-1.5 h-3.5 w-3.5\" />\n Hide\n </Button>\n </div>\n </>\n ) : (\n <>\n {error && <p className=\"text-sm text-destructive\">{error}</p>}\n <Button onClick={reveal} disabled={busy} variant=\"outline\" size=\"sm\" className=\"self-start\">\n {busy ? <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" /> : <KeyRound className=\"mr-1.5 h-3.5 w-3.5\" />}\n Show recovery key\n </Button>\n </>\n )}\n </div>\n );\n}\n"],"mappings":";AAoDM,SAUE,UATA,KADF;AAlDN,SAAS,gBAAgB;AACzB,SAAS,UAAU,MAAM,OAAO,QAAQ,SAAS,mBAAmB;AACpE,SAAS,yBAA2C;AACpD,SAAS,cAAc;AACvB,SAAS,OAAO,wBAAwB;AAQjC,SAAS,iBAAiB,EAAE,YAAY,QAAQ,cAAc,GAA0B;AAC7F,QAAM,CAAC,aAAa,cAAc,IAAI,SAAwB,IAAI;AAClE,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,SAAS,YAAY;AACzB,YAAQ,IAAI;AACZ,aAAS,IAAI;AACb,QAAI;AACF,YAAM,SAAS,WAAW;AAC1B,UAAI,CAAC,QAAQ;AACX,iBAAS,wCAAwC;AACjD;AAAA,MACF;AACA,qBAAe,kBAAkB,EAAE,eAAe,OAAO,SAAS,YAAY,MAAM,OAAO,MAAM,EAAE,CAAC,CAAC;AAAA,IACvG,SAAS,KAAK;AACZ,YAAM,WAAW;AACjB,eAAS,gBAAgB,cAAc,KAAK,QAAQ,IAAI,QAAQ;AAAA,IAClE,UAAE;AACA,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,QAAM,OAAO,YAAY;AACvB,QAAI,CAAC,YAAa;AAClB,UAAM,UAAU,UAAU,UAAU,WAAW;AAC/C,cAAU,IAAI;AACd,eAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,EACzC;AAEA,QAAM,OAAO,MAAM;AACjB,mBAAe,IAAI;AACnB,cAAU,KAAK;AAAA,EACjB;AAEA,SACE,qBAAC,SAAI,WAAU,uBACb;AAAA,yBAAC,SACC;AAAA,0BAAC,OAAE,WAAU,yBAAwB,0BAAY;AAAA,MACjD,oBAAC,OAAE,WAAU,sDAAqD,6NAIlE;AAAA,OACF;AAAA,IAEC,cACC,iCACE;AAAA,2BAAC,SAAM,SAAQ,eACb;AAAA,4BAAC,eAAY,WAAU,WAAU;AAAA,QACjC,qBAAC,oBAAiB,WAAU,2BAC1B;AAAA,8BAAC,UAAK,WAAU,iBAAgB,wDAA0C;AAAA,UAAQ;AAAA,UAAI;AAAA,WAGxF;AAAA,SACF;AAAA,MACA,oBAAC,UAAK,WAAU,gFACb,uBACH;AAAA,MACA,qBAAC,SAAI,WAAU,2BACb;AAAA,6BAAC,UAAO,SAAS,MAAM,SAAQ,WAAU,MAAK,MAC3C;AAAA,mBAAS,oBAAC,SAAM,WAAU,sBAAqB,IAAK,oBAAC,QAAK,WAAU,sBAAqB;AAAA,UACzF,SAAS,WAAW;AAAA,WACvB;AAAA,QACA,qBAAC,UAAO,SAAS,MAAM,SAAQ,SAAQ,MAAK,MAC1C;AAAA,8BAAC,UAAO,WAAU,sBAAqB;AAAA,UAAE;AAAA,WAE3C;AAAA,SACF;AAAA,OACF,IAEA,iCACG;AAAA,eAAS,oBAAC,OAAE,WAAU,4BAA4B,iBAAM;AAAA,MACzD,qBAAC,UAAO,SAAS,QAAQ,UAAU,MAAM,SAAQ,WAAU,MAAK,MAAK,WAAU,cAC5E;AAAA,eAAO,oBAAC,WAAQ,WAAU,mCAAkC,IAAK,oBAAC,YAAS,WAAU,sBAAqB;AAAA,QAAG;AAAA,SAEhH;AAAA,OACF;AAAA,KAEJ;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/components/wallet/export-key-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport { KeyRound, Copy, Check, EyeOff, Loader2, ShieldAlert } from \"lucide-react\";\nimport { encodeRecoveryKey, type SealedOwner } from \"@medialane/sdk/starknet\";\nimport { Button } from \"../button.js\";\nimport { Alert, AlertDescription } from \"../alert.js\";\n\nexport interface ExportKeySectionProps {\n loadSealed: () => SealedOwner | null;\n unlock: (sealed: SealedOwner) => Promise<string>;\n describeError?: (err: unknown, fallback: string) => string;\n}\n\nexport function ExportKeySection({ loadSealed, unlock, describeError }: ExportKeySectionProps) {\n const [recoveryKey, setRecoveryKey] = useState<string | null>(null);\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [copied, setCopied] = useState(false);\n\n const reveal = async () => {\n setBusy(true);\n setError(null);\n try {\n const sealed = loadSealed();\n if (!sealed) {\n setError(\"This browser has no wallet key stored.\");\n return;\n }\n setRecoveryKey(encodeRecoveryKey({ walletAddress: sealed.address, privateKey: await unlock(sealed) }));\n } catch (err) {\n const fallback = \"Could not unlock your key. Please try again.\";\n setError(describeError ? describeError(err, fallback) : fallback);\n } finally {\n setBusy(false);\n }\n };\n\n const copy = async () => {\n if (!recoveryKey) return;\n await navigator.clipboard.writeText(recoveryKey);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n };\n\n const hide = () => {\n setRecoveryKey(null);\n setCopied(false);\n };\n\n return (\n <div className=\"flex flex-col gap-3\">\n <div>\n <p className=\"text-sm font-semibold\">Recovery key</p>\n <p className=\"mt-1 text-xs text-muted-foreground leading-relaxed\">\n Save this somewhere private, such as a password manager. Paste it when you sign in on a\n new phone or browser, or if you lose access to every device you use.\n </p>\n </div>\n\n {recoveryKey ? (\n <>\n <Alert variant=\"destructive\">\n <ShieldAlert className=\"h-4 w-4\" />\n <AlertDescription className=\"text-xs leading-relaxed\">\n <span className=\"font-semibold\">Anyone with this key controls your wallet.</span>{\" \"}\n Medialane will never ask you for it. Treat any message requesting it as an attempt to\n take your assets.\n </AlertDescription>\n </Alert>\n <code className=\"block break-all rounded-xl bg-muted px-3 py-2.5 font-mono text-xs select-all\">\n {recoveryKey}\n </code>\n <div className=\"flex items-center gap-2\">\n <Button onClick={copy} variant=\"outline\" size=\"sm\">\n {copied ? <Check className=\"mr-1.5 h-3.5 w-3.5\" /> : <Copy className=\"mr-1.5 h-3.5 w-3.5\" />}\n {copied ? \"Copied\" : \"Copy key\"}\n </Button>\n <Button onClick={hide} variant=\"ghost\" size=\"sm\">\n <EyeOff className=\"mr-1.5 h-3.5 w-3.5\" />\n Hide\n </Button>\n </div>\n </>\n ) : (\n <>\n {error && <p className=\"text-sm text-destructive\">{error}</p>}\n <Button onClick={reveal} disabled={busy} variant=\"outline\" size=\"sm\" className=\"self-start\">\n {busy ? <Loader2 className=\"mr-1.5 h-3.5 w-3.5 animate-spin\" /> : <KeyRound className=\"mr-1.5 h-3.5 w-3.5\" />}\n Show recovery key\n </Button>\n </>\n )}\n </div>\n );\n}\n"],"mappings":";AAoDM,SASE,UARA,KADF;AAlDN,SAAS,gBAAgB;AACzB,SAAS,UAAU,MAAM,OAAO,QAAQ,SAAS,mBAAmB;AACpE,SAAS,yBAA2C;AACpD,SAAS,cAAc;AACvB,SAAS,OAAO,wBAAwB;AAQjC,SAAS,iBAAiB,EAAE,YAAY,QAAQ,cAAc,GAA0B;AAC7F,QAAM,CAAC,aAAa,cAAc,IAAI,SAAwB,IAAI;AAClE,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAwB,IAAI;AACtD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,SAAS,YAAY;AACzB,YAAQ,IAAI;AACZ,aAAS,IAAI;AACb,QAAI;AACF,YAAM,SAAS,WAAW;AAC1B,UAAI,CAAC,QAAQ;AACX,iBAAS,wCAAwC;AACjD;AAAA,MACF;AACA,qBAAe,kBAAkB,EAAE,eAAe,OAAO,SAAS,YAAY,MAAM,OAAO,MAAM,EAAE,CAAC,CAAC;AAAA,IACvG,SAAS,KAAK;AACZ,YAAM,WAAW;AACjB,eAAS,gBAAgB,cAAc,KAAK,QAAQ,IAAI,QAAQ;AAAA,IAClE,UAAE;AACA,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,QAAM,OAAO,YAAY;AACvB,QAAI,CAAC,YAAa;AAClB,UAAM,UAAU,UAAU,UAAU,WAAW;AAC/C,cAAU,IAAI;AACd,eAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,EACzC;AAEA,QAAM,OAAO,MAAM;AACjB,mBAAe,IAAI;AACnB,cAAU,KAAK;AAAA,EACjB;AAEA,SACE,qBAAC,SAAI,WAAU,uBACb;AAAA,yBAAC,SACC;AAAA,0BAAC,OAAE,WAAU,yBAAwB,0BAAY;AAAA,MACjD,oBAAC,OAAE,WAAU,sDAAqD,0KAGlE;AAAA,OACF;AAAA,IAEC,cACC,iCACE;AAAA,2BAAC,SAAM,SAAQ,eACb;AAAA,4BAAC,eAAY,WAAU,WAAU;AAAA,QACjC,qBAAC,oBAAiB,WAAU,2BAC1B;AAAA,8BAAC,UAAK,WAAU,iBAAgB,wDAA0C;AAAA,UAAQ;AAAA,UAAI;AAAA,WAGxF;AAAA,SACF;AAAA,MACA,oBAAC,UAAK,WAAU,gFACb,uBACH;AAAA,MACA,qBAAC,SAAI,WAAU,2BACb;AAAA,6BAAC,UAAO,SAAS,MAAM,SAAQ,WAAU,MAAK,MAC3C;AAAA,mBAAS,oBAAC,SAAM,WAAU,sBAAqB,IAAK,oBAAC,QAAK,WAAU,sBAAqB;AAAA,UACzF,SAAS,WAAW;AAAA,WACvB;AAAA,QACA,qBAAC,UAAO,SAAS,MAAM,SAAQ,SAAQ,MAAK,MAC1C;AAAA,8BAAC,UAAO,WAAU,sBAAqB;AAAA,UAAE;AAAA,WAE3C;AAAA,SACF;AAAA,OACF,IAEA,iCACG;AAAA,eAAS,oBAAC,OAAE,WAAU,4BAA4B,iBAAM;AAAA,MACzD,qBAAC,UAAO,SAAS,QAAQ,UAAU,MAAM,SAAQ,WAAU,MAAK,MAAK,WAAU,cAC5E;AAAA,eAAO,oBAAC,WAAQ,WAAU,mCAAkC,IAAK,oBAAC,YAAS,WAAU,sBAAqB;AAAA,QAAG;AAAA,SAEhH;AAAA,OACF;AAAA,KAEJ;AAEJ;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medialane/ui",
3
- "version": "0.255.0",
3
+ "version": "0.257.0",
4
4
  "description": "Shared UI components for Medialane apps",
5
5
  "type": "module",
6
6
  "sideEffects": false,