@medialane/ui 0.258.0 → 0.259.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.
Files changed (103) hide show
  1. package/dist/components/comments-section.cjs +5 -4
  2. package/dist/components/comments-section.cjs.map +1 -1
  3. package/dist/components/comments-section.js +5 -4
  4. package/dist/components/comments-section.js.map +1 -1
  5. package/dist/components/launchpad/coin-create.cjs +9 -7
  6. package/dist/components/launchpad/coin-create.cjs.map +1 -1
  7. package/dist/components/launchpad/coin-create.js +9 -7
  8. package/dist/components/launchpad/coin-create.js.map +1 -1
  9. package/dist/components/launchpad/collection-create-form.cjs +11 -14
  10. package/dist/components/launchpad/collection-create-form.cjs.map +1 -1
  11. package/dist/components/launchpad/collection-create-form.js +12 -15
  12. package/dist/components/launchpad/collection-create-form.js.map +1 -1
  13. package/dist/components/launchpad/collection-create-presets.cjs +8 -8
  14. package/dist/components/launchpad/collection-create-presets.cjs.map +1 -1
  15. package/dist/components/launchpad/collection-create-presets.d.cts +2 -1
  16. package/dist/components/launchpad/collection-create-presets.d.ts +2 -1
  17. package/dist/components/launchpad/collection-create-presets.js +8 -8
  18. package/dist/components/launchpad/collection-create-presets.js.map +1 -1
  19. package/dist/components/launchpad/edition-mint.cjs +9 -7
  20. package/dist/components/launchpad/edition-mint.cjs.map +1 -1
  21. package/dist/components/launchpad/edition-mint.js +9 -7
  22. package/dist/components/launchpad/edition-mint.js.map +1 -1
  23. package/dist/components/launchpad/pop-create.cjs +5 -6
  24. package/dist/components/launchpad/pop-create.cjs.map +1 -1
  25. package/dist/components/launchpad/pop-create.js +5 -6
  26. package/dist/components/launchpad/pop-create.js.map +1 -1
  27. package/dist/components/launchpad/remix-mint.cjs +9 -7
  28. package/dist/components/launchpad/remix-mint.cjs.map +1 -1
  29. package/dist/components/launchpad/remix-mint.js +9 -7
  30. package/dist/components/launchpad/remix-mint.js.map +1 -1
  31. package/dist/components/launchpad/single-edition-mint.cjs +9 -7
  32. package/dist/components/launchpad/single-edition-mint.cjs.map +1 -1
  33. package/dist/components/launchpad/single-edition-mint.js +9 -7
  34. package/dist/components/launchpad/single-edition-mint.js.map +1 -1
  35. package/dist/components/launchpad/sponsorship-create.cjs +5 -6
  36. package/dist/components/launchpad/sponsorship-create.cjs.map +1 -1
  37. package/dist/components/launchpad/sponsorship-create.js +5 -6
  38. package/dist/components/launchpad/sponsorship-create.js.map +1 -1
  39. package/dist/components/launchpad/tier-mint-form.cjs +5 -6
  40. package/dist/components/launchpad/tier-mint-form.cjs.map +1 -1
  41. package/dist/components/launchpad/tier-mint-form.js +5 -6
  42. package/dist/components/launchpad/tier-mint-form.js.map +1 -1
  43. package/dist/components/launchpad/tier-mint-presets.cjs +2 -2
  44. package/dist/components/launchpad/tier-mint-presets.cjs.map +1 -1
  45. package/dist/components/launchpad/tier-mint-presets.d.cts +2 -1
  46. package/dist/components/launchpad/tier-mint-presets.d.ts +2 -1
  47. package/dist/components/launchpad/tier-mint-presets.js +2 -2
  48. package/dist/components/launchpad/tier-mint-presets.js.map +1 -1
  49. package/dist/components/marketplace-dialog-primitives.cjs +0 -30
  50. package/dist/components/marketplace-dialog-primitives.cjs.map +1 -1
  51. package/dist/components/marketplace-dialog-primitives.d.cts +1 -12
  52. package/dist/components/marketplace-dialog-primitives.d.ts +1 -12
  53. package/dist/components/marketplace-dialog-primitives.js +1 -30
  54. package/dist/components/marketplace-dialog-primitives.js.map +1 -1
  55. package/dist/components/pop-claim-button.cjs +5 -4
  56. package/dist/components/pop-claim-button.cjs.map +1 -1
  57. package/dist/components/pop-claim-button.js +5 -4
  58. package/dist/components/pop-claim-button.js.map +1 -1
  59. package/dist/components/pop-manage-page.cjs +2 -2
  60. package/dist/components/pop-manage-page.cjs.map +1 -1
  61. package/dist/components/pop-manage-page.js +2 -2
  62. package/dist/components/pop-manage-page.js.map +1 -1
  63. package/dist/components/portfolio-sponsorships.cjs +2 -2
  64. package/dist/components/portfolio-sponsorships.cjs.map +1 -1
  65. package/dist/components/portfolio-sponsorships.js +2 -2
  66. package/dist/components/portfolio-sponsorships.js.map +1 -1
  67. package/dist/components/sponsorship-offer-page.cjs +5 -4
  68. package/dist/components/sponsorship-offer-page.cjs.map +1 -1
  69. package/dist/components/sponsorship-offer-page.js +5 -4
  70. package/dist/components/sponsorship-offer-page.js.map +1 -1
  71. package/dist/components/{creation-success.cjs → transaction-success.cjs} +14 -15
  72. package/dist/components/transaction-success.cjs.map +1 -0
  73. package/dist/components/transaction-success.d.cts +20 -0
  74. package/dist/components/transaction-success.d.ts +20 -0
  75. package/dist/components/{creation-success.js → transaction-success.js} +10 -11
  76. package/dist/components/transaction-success.js.map +1 -0
  77. package/dist/components/transfer-collection-ownership.cjs +5 -4
  78. package/dist/components/transfer-collection-ownership.cjs.map +1 -1
  79. package/dist/components/transfer-collection-ownership.js +5 -4
  80. package/dist/components/transfer-collection-ownership.js.map +1 -1
  81. package/dist/index.cjs +6 -8
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.d.cts +3 -3
  84. package/dist/index.d.ts +3 -3
  85. package/dist/index.js +4 -6
  86. package/dist/index.js.map +1 -1
  87. package/dist/utils/success-messages.cjs +54 -0
  88. package/dist/utils/success-messages.cjs.map +1 -0
  89. package/dist/utils/success-messages.d.cts +31 -0
  90. package/dist/utils/success-messages.d.ts +31 -0
  91. package/dist/utils/success-messages.js +30 -0
  92. package/dist/utils/success-messages.js.map +1 -0
  93. package/package.json +3 -3
  94. package/dist/components/creation-success.cjs.map +0 -1
  95. package/dist/components/creation-success.d.cts +0 -20
  96. package/dist/components/creation-success.d.ts +0 -20
  97. package/dist/components/creation-success.js.map +0 -1
  98. package/dist/components/transaction-done.cjs +0 -46
  99. package/dist/components/transaction-done.cjs.map +0 -1
  100. package/dist/components/transaction-done.d.cts +0 -18
  101. package/dist/components/transaction-done.d.ts +0 -18
  102. package/dist/components/transaction-done.js +0 -22
  103. package/dist/components/transaction-done.js.map +0 -1
@@ -44,7 +44,7 @@ var import_reward_earned = require("./rewards/reward-earned.js");
44
44
  var import_skeleton = require("./skeleton.js");
45
45
  var import_textarea = require("./textarea.js");
46
46
  var import_transaction_dialog = require("./transaction-dialog.js");
47
- var import_transaction_done = require("./transaction-done.js");
47
+ var import_transaction_success = require("./transaction-success.js");
48
48
  var import_cn = require("../utils/cn.js");
49
49
  var import_explorer_url = require("../utils/explorer-url.js");
50
50
  var import_run_intent_calls = require("../utils/run-intent-calls.js");
@@ -286,13 +286,14 @@ function CommentsSection({ contract, tokenId, className }) {
286
286
  }
287
287
  ),
288
288
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_transaction_dialog.TransactionDialog, { tx, title: "Comment", workingLabel: "Posting your comment\u2026", firstStepLabel: "Prepare comment", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
289
- import_transaction_done.TransactionDone,
289
+ import_transaction_success.TransactionSuccess,
290
290
  {
291
- tx,
292
291
  name: "Comment",
293
292
  title: "Comment posted!",
294
293
  description: "Your comment is onchain and will appear here once indexed (~30s).",
295
- footer: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_reward_earned.RewardEarned, { actionType: "comment" })
294
+ txHash: tx.txHash,
295
+ actions: [{ label: "Done", onClick: tx.reset }],
296
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_reward_earned.RewardEarned, { actionType: "comment" })
296
297
  }
297
298
  ) })
298
299
  ] });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/comments-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { ExternalLink, Flag, Loader2, MessageCircle, Send, Zap } from \"lucide-react\";\nimport { normalizeAddress, profileHref, STARKNET_NFTCOMMENTS_CONTRACT } from \"@medialane/sdk\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp, type ReportTarget } from \"./medialane-app.js\";\nimport { RewardEarned } from \"./rewards/reward-earned.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { Textarea } from \"./textarea.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionDone } from \"./transaction-done.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { useComments } from \"../utils/use-comments.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\nconst MAX_LEN = 1000;\n\nexport interface CommentsSectionProps {\n contract: string;\n tokenId: string;\n className?: string;\n}\n\nexport function CommentsSection({ contract, tokenId, className }: CommentsSectionProps) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const hasWallet = !!walletAddress;\n const { ReportDialog } = app;\n const { comments, isLoading, mutate } = useComments(contract, tokenId);\n const tx = useTransaction();\n\n const [text, setText] = useState(\"\");\n const [reportTarget, setReportTarget] = useState<ReportTarget | null>(null);\n\n const messagesRef = useRef<HTMLDivElement>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const composeRef = useRef<HTMLTextAreaElement>(null);\n\n const byteLen = new TextEncoder().encode(text).length;\n const canSubmit = text.trim().length > 0 && byteLen <= MAX_LEN && !!STARKNET_NFTCOMMENTS_CONTRACT;\n const isProcessing = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const isOwn = (author: string) =>\n !!walletAddress && normalizeAddress(\"STARKNET\", author) === normalizeAddress(\"STARKNET\", walletAddress);\n\n const isNearBottom = () => {\n const el = messagesRef.current;\n if (!el) return true;\n return el.scrollHeight - el.scrollTop - el.clientHeight < 100;\n };\n\n useEffect(() => {\n if (isNearBottom()) {\n bottomRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }\n\n }, [comments.length]);\n\n const handleTextInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setText(e.target.value);\n e.target.style.height = \"auto\";\n e.target.style.height = Math.min(e.target.scrollHeight, 96) + \"px\";\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey && canSubmit && !isProcessing) {\n e.preventDefault();\n post();\n }\n };\n\n const post = () => {\n const body = text.trim();\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () =>\n app.getClient().api.intents.create(\"comment\", { author: signer.address, nftContract: contract, tokenId, text: body }),\n );\n })\n .then((ok) => {\n if (!ok) return;\n setText(\"\");\n if (composeRef.current) composeRef.current.style.height = \"auto\";\n void mutate();\n });\n };\n\n const handleStartConversation = () => {\n if (hasWallet) composeRef.current?.focus();\n };\n\n return (\n <div className={cn(\"flex flex-col h-[480px] overflow-hidden\", className)}>\n\n <div ref={messagesRef} className=\"flex-1 overflow-y-auto px-4 py-4\">\n {isLoading ? (\n <div className=\"space-y-4\">\n {([\n { own: false, w: \"w-40\" },\n { own: true, w: \"w-56\" },\n { own: false, w: \"w-48\" },\n { own: true, w: \"w-32\" },\n ] as const).map((item, i) => (\n <div key={i} className={`flex ${item.own ? \"justify-end\" : \"justify-start\"} gap-2`}>\n {!item.own && <Skeleton className=\"h-8 w-8 rounded-full shrink-0\" />}\n <Skeleton\n className={`h-10 ${item.w} rounded-2xl ${item.own ? \"rounded-tr-sm\" : \"rounded-tl-sm\"}`}\n />\n </div>\n ))}\n </div>\n ) : comments.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center h-full gap-4 text-center px-4\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full\" style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue) / 0.15), hsl(var(--brand-purple) / 0.15))\" }}>\n <MessageCircle className=\"h-7 w-7\" style={{ color: \"hsl(var(--brand-blue))\" }} />\n </div>\n <div>\n <p className=\"text-sm font-semibold\">Nothing here yet</p>\n <p className=\"text-xs text-muted-foreground mt-1 leading-relaxed max-w-[220px]\">\n Your comment will be minted onchain — attached to this NFT forever.\n </p>\n </div>\n <Button\n size=\"sm\"\n onClick={handleStartConversation}\n className=\"rounded-full text-white px-5\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n Write the first comment\n </Button>\n </div>\n ) : (\n <div className=\"space-y-5\">\n {comments.map((comment) => {\n const own = isOwn(comment.author);\n const avatarSeed = parseInt(comment.author.slice(2, 8), 16) % 360;\n const avatarBg = own\n ? \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\"\n : `linear-gradient(135deg, hsl(${avatarSeed}, 65%, 45%), hsl(${(avatarSeed + 60) % 360}, 65%, 55%))`;\n\n return (\n <div\n key={comment.id}\n className={`group flex gap-2.5 ${own ? \"flex-row-reverse\" : \"flex-row\"}`}\n >\n\n <Link href={profileHref({ address: comment.author })} className=\"shrink-0 mt-0.5\">\n <div\n className=\"h-9 w-9 rounded-full flex items-center justify-center text-2xs font-bold text-white select-none ring-2 ring-background hover:ring-primary/40 transition-all\"\n style={{ background: avatarBg }}\n >\n {comment.author.slice(2, 5).toUpperCase()}\n </div>\n </Link>\n\n <div className={`flex flex-col max-w-[75%] gap-1 ${own ? \"items-end\" : \"items-start\"}`}>\n\n <div className={`flex items-center gap-2 px-1 ${own ? \"flex-row-reverse\" : \"flex-row\"}`}>\n <Link\n href={profileHref({ address: comment.author })}\n className=\"text-xs font-semibold text-foreground hover:underline underline-offset-2\"\n >\n {own ? \"You\" : <AddressDisplay address={comment.author} chars={5} showCopy={false} />}\n </Link>\n <span className=\"text-2xs text-muted-foreground\" title={comment.postedAt}>\n {timeAgo(comment.postedAt)}\n </span>\n </div>\n\n <div className=\"relative\">\n {own ? (\n <div\n className=\"px-3.5 py-2.5 text-sm leading-relaxed break-words rounded-2xl rounded-tr-sm text-white\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n {comment.content}\n </div>\n ) : (\n <div className=\"px-3.5 py-2.5 text-sm leading-relaxed break-words bg-muted rounded-2xl rounded-tl-sm border border-border/50\">\n {comment.content}\n </div>\n )}\n {!own && hasWallet && (\n <button\n className=\"absolute -top-1 -right-5 opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground/40 hover:text-destructive/70\"\n title=\"Report comment\"\n aria-label=\"Report comment\"\n onClick={() => setReportTarget({ type: \"COMMENT\", commentId: comment.id })}\n >\n <Flag className=\"h-3 w-3\" />\n </button>\n )}\n </div>\n\n {comment.txHash && (\n <a\n href={`${EXPLORER_URL}/tx/${comment.txHash}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1 px-1 text-2xs font-medium transition-colors\"\n style={{ color: \"hsl(var(--brand-blue) / 0.55)\" }}\n onMouseEnter={(e) => (e.currentTarget.style.color = \"hsl(var(--brand-blue))\")}\n onMouseLeave={(e) => (e.currentTarget.style.color = \"hsl(var(--brand-blue) / 0.55)\")}\n >\n <span>⛓</span>\n <span>onchain proof</span>\n <ExternalLink className=\"h-2.5 w-2.5\" />\n </a>\n )}\n </div>\n </div>\n );\n })}\n <div ref={bottomRef} />\n </div>\n )}\n </div>\n\n <div className=\"border-t border-border/60 shrink-0\">\n {!hasWallet ? (\n <div className=\"flex items-center justify-center px-4 h-16\">\n <button type=\"button\" onClick={app.onRequireWallet} className=\"text-sm text-primary hover:underline\">\n {app.connectLabel ?? \"Connect\"} to comment\n </button>\n </div>\n ) : (\n <div className=\"px-3 pt-2 pb-3 space-y-2\">\n\n <div className=\"flex items-center gap-1.5\">\n <Zap className=\"h-3 w-3\" style={{ color: \"hsl(var(--brand-blue))\" }} />\n <span className=\"text-2xs font-semibold\" style={{ color: \"hsl(var(--brand-blue))\" }}>\n Mint your message onchain\n </span>\n </div>\n\n <div\n className=\"rounded-xl border bg-background/60 transition-all focus-within:ring-2\"\n style={{\n borderColor: \"hsl(var(--border))\",\n }}\n onFocusCapture={(e) => {\n (e.currentTarget as HTMLDivElement).style.borderColor = \"hsl(var(--brand-blue) / 0.6)\";\n (e.currentTarget as HTMLDivElement).style.boxShadow = \"0 0 0 3px hsl(var(--brand-blue) / 0.12)\";\n }}\n onBlurCapture={(e) => {\n (e.currentTarget as HTMLDivElement).style.borderColor = \"hsl(var(--border))\";\n (e.currentTarget as HTMLDivElement).style.boxShadow = \"\";\n }}\n >\n <Textarea\n ref={composeRef}\n placeholder=\"Say something onchain… it's permanent.\"\n value={text}\n onChange={handleTextInput}\n onKeyDown={handleKeyDown}\n rows={2}\n className=\"resize-none min-h-[52px] max-h-[120px] w-full border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 px-3 pt-2.5 pb-1 text-sm rounded-xl\"\n disabled={isProcessing}\n />\n <div className=\"flex items-center justify-between px-3 pb-2.5\">\n <span className=\"text-2xs text-muted-foreground/40 flex items-center gap-1\">\n Enter ↵ to post\n </span>\n <div className=\"flex items-center gap-2\">\n {byteLen > 800 && (\n <span className={`text-2xs ${byteLen > MAX_LEN ? \"text-destructive\" : \"text-muted-foreground\"}`}>\n {byteLen}/{MAX_LEN}\n </span>\n )}\n <button\n onClick={post}\n disabled={!canSubmit || isProcessing}\n className=\"flex items-center gap-1.5 h-7 px-3 text-xs font-semibold rounded-full text-white transition-all hover:opacity-90 active:scale-95 disabled:opacity-40 disabled:cursor-not-allowed\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n {isProcessing ? <Loader2 className=\"h-3 w-3 animate-spin\" /> : <Send className=\"h-3 w-3\" />}\n Post onchain\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n\n {reportTarget && ReportDialog && (\n <ReportDialog\n target={reportTarget}\n open={!!reportTarget}\n onOpenChange={(open) => { if (!open) setReportTarget(null); }}\n />\n )}\n\n <TransactionDialog tx={tx} title=\"Comment\" workingLabel=\"Posting your comment…\" firstStepLabel=\"Prepare comment\">\n <TransactionDone\n tx={tx}\n name=\"Comment\"\n title=\"Comment posted!\"\n description=\"Your comment is onchain and will appear here once indexed (~30s).\"\n footer={<RewardEarned actionType=\"comment\" />}\n />\n </TransactionDialog>\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
1
+ {"version":3,"sources":["../../src/components/comments-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { ExternalLink, Flag, Loader2, MessageCircle, Send, Zap } from \"lucide-react\";\nimport { normalizeAddress, profileHref, STARKNET_NFTCOMMENTS_CONTRACT } from \"@medialane/sdk\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp, type ReportTarget } from \"./medialane-app.js\";\nimport { RewardEarned } from \"./rewards/reward-earned.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { Textarea } from \"./textarea.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionSuccess } from \"./transaction-success.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { useComments } from \"../utils/use-comments.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\nconst MAX_LEN = 1000;\n\nexport interface CommentsSectionProps {\n contract: string;\n tokenId: string;\n className?: string;\n}\n\nexport function CommentsSection({ contract, tokenId, className }: CommentsSectionProps) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const hasWallet = !!walletAddress;\n const { ReportDialog } = app;\n const { comments, isLoading, mutate } = useComments(contract, tokenId);\n const tx = useTransaction();\n\n const [text, setText] = useState(\"\");\n const [reportTarget, setReportTarget] = useState<ReportTarget | null>(null);\n\n const messagesRef = useRef<HTMLDivElement>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const composeRef = useRef<HTMLTextAreaElement>(null);\n\n const byteLen = new TextEncoder().encode(text).length;\n const canSubmit = text.trim().length > 0 && byteLen <= MAX_LEN && !!STARKNET_NFTCOMMENTS_CONTRACT;\n const isProcessing = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const isOwn = (author: string) =>\n !!walletAddress && normalizeAddress(\"STARKNET\", author) === normalizeAddress(\"STARKNET\", walletAddress);\n\n const isNearBottom = () => {\n const el = messagesRef.current;\n if (!el) return true;\n return el.scrollHeight - el.scrollTop - el.clientHeight < 100;\n };\n\n useEffect(() => {\n if (isNearBottom()) {\n bottomRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }\n\n }, [comments.length]);\n\n const handleTextInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setText(e.target.value);\n e.target.style.height = \"auto\";\n e.target.style.height = Math.min(e.target.scrollHeight, 96) + \"px\";\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey && canSubmit && !isProcessing) {\n e.preventDefault();\n post();\n }\n };\n\n const post = () => {\n const body = text.trim();\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () =>\n app.getClient().api.intents.create(\"comment\", { author: signer.address, nftContract: contract, tokenId, text: body }),\n );\n })\n .then((ok) => {\n if (!ok) return;\n setText(\"\");\n if (composeRef.current) composeRef.current.style.height = \"auto\";\n void mutate();\n });\n };\n\n const handleStartConversation = () => {\n if (hasWallet) composeRef.current?.focus();\n };\n\n return (\n <div className={cn(\"flex flex-col h-[480px] overflow-hidden\", className)}>\n\n <div ref={messagesRef} className=\"flex-1 overflow-y-auto px-4 py-4\">\n {isLoading ? (\n <div className=\"space-y-4\">\n {([\n { own: false, w: \"w-40\" },\n { own: true, w: \"w-56\" },\n { own: false, w: \"w-48\" },\n { own: true, w: \"w-32\" },\n ] as const).map((item, i) => (\n <div key={i} className={`flex ${item.own ? \"justify-end\" : \"justify-start\"} gap-2`}>\n {!item.own && <Skeleton className=\"h-8 w-8 rounded-full shrink-0\" />}\n <Skeleton\n className={`h-10 ${item.w} rounded-2xl ${item.own ? \"rounded-tr-sm\" : \"rounded-tl-sm\"}`}\n />\n </div>\n ))}\n </div>\n ) : comments.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center h-full gap-4 text-center px-4\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full\" style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue) / 0.15), hsl(var(--brand-purple) / 0.15))\" }}>\n <MessageCircle className=\"h-7 w-7\" style={{ color: \"hsl(var(--brand-blue))\" }} />\n </div>\n <div>\n <p className=\"text-sm font-semibold\">Nothing here yet</p>\n <p className=\"text-xs text-muted-foreground mt-1 leading-relaxed max-w-[220px]\">\n Your comment will be minted onchain — attached to this NFT forever.\n </p>\n </div>\n <Button\n size=\"sm\"\n onClick={handleStartConversation}\n className=\"rounded-full text-white px-5\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n Write the first comment\n </Button>\n </div>\n ) : (\n <div className=\"space-y-5\">\n {comments.map((comment) => {\n const own = isOwn(comment.author);\n const avatarSeed = parseInt(comment.author.slice(2, 8), 16) % 360;\n const avatarBg = own\n ? \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\"\n : `linear-gradient(135deg, hsl(${avatarSeed}, 65%, 45%), hsl(${(avatarSeed + 60) % 360}, 65%, 55%))`;\n\n return (\n <div\n key={comment.id}\n className={`group flex gap-2.5 ${own ? \"flex-row-reverse\" : \"flex-row\"}`}\n >\n\n <Link href={profileHref({ address: comment.author })} className=\"shrink-0 mt-0.5\">\n <div\n className=\"h-9 w-9 rounded-full flex items-center justify-center text-2xs font-bold text-white select-none ring-2 ring-background hover:ring-primary/40 transition-all\"\n style={{ background: avatarBg }}\n >\n {comment.author.slice(2, 5).toUpperCase()}\n </div>\n </Link>\n\n <div className={`flex flex-col max-w-[75%] gap-1 ${own ? \"items-end\" : \"items-start\"}`}>\n\n <div className={`flex items-center gap-2 px-1 ${own ? \"flex-row-reverse\" : \"flex-row\"}`}>\n <Link\n href={profileHref({ address: comment.author })}\n className=\"text-xs font-semibold text-foreground hover:underline underline-offset-2\"\n >\n {own ? \"You\" : <AddressDisplay address={comment.author} chars={5} showCopy={false} />}\n </Link>\n <span className=\"text-2xs text-muted-foreground\" title={comment.postedAt}>\n {timeAgo(comment.postedAt)}\n </span>\n </div>\n\n <div className=\"relative\">\n {own ? (\n <div\n className=\"px-3.5 py-2.5 text-sm leading-relaxed break-words rounded-2xl rounded-tr-sm text-white\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n {comment.content}\n </div>\n ) : (\n <div className=\"px-3.5 py-2.5 text-sm leading-relaxed break-words bg-muted rounded-2xl rounded-tl-sm border border-border/50\">\n {comment.content}\n </div>\n )}\n {!own && hasWallet && (\n <button\n className=\"absolute -top-1 -right-5 opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground/40 hover:text-destructive/70\"\n title=\"Report comment\"\n aria-label=\"Report comment\"\n onClick={() => setReportTarget({ type: \"COMMENT\", commentId: comment.id })}\n >\n <Flag className=\"h-3 w-3\" />\n </button>\n )}\n </div>\n\n {comment.txHash && (\n <a\n href={`${EXPLORER_URL}/tx/${comment.txHash}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1 px-1 text-2xs font-medium transition-colors\"\n style={{ color: \"hsl(var(--brand-blue) / 0.55)\" }}\n onMouseEnter={(e) => (e.currentTarget.style.color = \"hsl(var(--brand-blue))\")}\n onMouseLeave={(e) => (e.currentTarget.style.color = \"hsl(var(--brand-blue) / 0.55)\")}\n >\n <span>⛓</span>\n <span>onchain proof</span>\n <ExternalLink className=\"h-2.5 w-2.5\" />\n </a>\n )}\n </div>\n </div>\n );\n })}\n <div ref={bottomRef} />\n </div>\n )}\n </div>\n\n <div className=\"border-t border-border/60 shrink-0\">\n {!hasWallet ? (\n <div className=\"flex items-center justify-center px-4 h-16\">\n <button type=\"button\" onClick={app.onRequireWallet} className=\"text-sm text-primary hover:underline\">\n {app.connectLabel ?? \"Connect\"} to comment\n </button>\n </div>\n ) : (\n <div className=\"px-3 pt-2 pb-3 space-y-2\">\n\n <div className=\"flex items-center gap-1.5\">\n <Zap className=\"h-3 w-3\" style={{ color: \"hsl(var(--brand-blue))\" }} />\n <span className=\"text-2xs font-semibold\" style={{ color: \"hsl(var(--brand-blue))\" }}>\n Mint your message onchain\n </span>\n </div>\n\n <div\n className=\"rounded-xl border bg-background/60 transition-all focus-within:ring-2\"\n style={{\n borderColor: \"hsl(var(--border))\",\n }}\n onFocusCapture={(e) => {\n (e.currentTarget as HTMLDivElement).style.borderColor = \"hsl(var(--brand-blue) / 0.6)\";\n (e.currentTarget as HTMLDivElement).style.boxShadow = \"0 0 0 3px hsl(var(--brand-blue) / 0.12)\";\n }}\n onBlurCapture={(e) => {\n (e.currentTarget as HTMLDivElement).style.borderColor = \"hsl(var(--border))\";\n (e.currentTarget as HTMLDivElement).style.boxShadow = \"\";\n }}\n >\n <Textarea\n ref={composeRef}\n placeholder=\"Say something onchain… it's permanent.\"\n value={text}\n onChange={handleTextInput}\n onKeyDown={handleKeyDown}\n rows={2}\n className=\"resize-none min-h-[52px] max-h-[120px] w-full border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 px-3 pt-2.5 pb-1 text-sm rounded-xl\"\n disabled={isProcessing}\n />\n <div className=\"flex items-center justify-between px-3 pb-2.5\">\n <span className=\"text-2xs text-muted-foreground/40 flex items-center gap-1\">\n Enter ↵ to post\n </span>\n <div className=\"flex items-center gap-2\">\n {byteLen > 800 && (\n <span className={`text-2xs ${byteLen > MAX_LEN ? \"text-destructive\" : \"text-muted-foreground\"}`}>\n {byteLen}/{MAX_LEN}\n </span>\n )}\n <button\n onClick={post}\n disabled={!canSubmit || isProcessing}\n className=\"flex items-center gap-1.5 h-7 px-3 text-xs font-semibold rounded-full text-white transition-all hover:opacity-90 active:scale-95 disabled:opacity-40 disabled:cursor-not-allowed\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n {isProcessing ? <Loader2 className=\"h-3 w-3 animate-spin\" /> : <Send className=\"h-3 w-3\" />}\n Post onchain\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n\n {reportTarget && ReportDialog && (\n <ReportDialog\n target={reportTarget}\n open={!!reportTarget}\n onOpenChange={(open) => { if (!open) setReportTarget(null); }}\n />\n )}\n\n <TransactionDialog tx={tx} title=\"Comment\" workingLabel=\"Posting your comment…\" firstStepLabel=\"Prepare comment\">\n <TransactionSuccess\n name=\"Comment\"\n title=\"Comment posted!\"\n description=\"Your comment is onchain and will appear here once indexed (~30s).\"\n txHash={tx.txHash}\n actions={[{ label: \"Done\", onClick: tx.reset }]}\n >\n <RewardEarned actionType=\"comment\" />\n </TransactionSuccess>\n </TransactionDialog>\n </div>\n );\n}\n"],"mappings":"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","names":["Link"]}
@@ -11,7 +11,7 @@ import { RewardEarned } from "./rewards/reward-earned.js";
11
11
  import { Skeleton } from "./skeleton.js";
12
12
  import { Textarea } from "./textarea.js";
13
13
  import { TransactionDialog } from "./transaction-dialog.js";
14
- import { TransactionDone } from "./transaction-done.js";
14
+ import { TransactionSuccess } from "./transaction-success.js";
15
15
  import { cn } from "../utils/cn.js";
16
16
  import { EXPLORER_URL } from "../utils/explorer-url.js";
17
17
  import { runIntentCalls } from "../utils/run-intent-calls.js";
@@ -253,13 +253,14 @@ function CommentsSection({ contract, tokenId, className }) {
253
253
  }
254
254
  ),
255
255
  /* @__PURE__ */ jsx(TransactionDialog, { tx, title: "Comment", workingLabel: "Posting your comment\u2026", firstStepLabel: "Prepare comment", children: /* @__PURE__ */ jsx(
256
- TransactionDone,
256
+ TransactionSuccess,
257
257
  {
258
- tx,
259
258
  name: "Comment",
260
259
  title: "Comment posted!",
261
260
  description: "Your comment is onchain and will appear here once indexed (~30s).",
262
- footer: /* @__PURE__ */ jsx(RewardEarned, { actionType: "comment" })
261
+ txHash: tx.txHash,
262
+ actions: [{ label: "Done", onClick: tx.reset }],
263
+ children: /* @__PURE__ */ jsx(RewardEarned, { actionType: "comment" })
263
264
  }
264
265
  ) })
265
266
  ] });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/components/comments-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { ExternalLink, Flag, Loader2, MessageCircle, Send, Zap } from \"lucide-react\";\nimport { normalizeAddress, profileHref, STARKNET_NFTCOMMENTS_CONTRACT } from \"@medialane/sdk\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp, type ReportTarget } from \"./medialane-app.js\";\nimport { RewardEarned } from \"./rewards/reward-earned.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { Textarea } from \"./textarea.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionDone } from \"./transaction-done.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { useComments } from \"../utils/use-comments.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\nconst MAX_LEN = 1000;\n\nexport interface CommentsSectionProps {\n contract: string;\n tokenId: string;\n className?: string;\n}\n\nexport function CommentsSection({ contract, tokenId, className }: CommentsSectionProps) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const hasWallet = !!walletAddress;\n const { ReportDialog } = app;\n const { comments, isLoading, mutate } = useComments(contract, tokenId);\n const tx = useTransaction();\n\n const [text, setText] = useState(\"\");\n const [reportTarget, setReportTarget] = useState<ReportTarget | null>(null);\n\n const messagesRef = useRef<HTMLDivElement>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const composeRef = useRef<HTMLTextAreaElement>(null);\n\n const byteLen = new TextEncoder().encode(text).length;\n const canSubmit = text.trim().length > 0 && byteLen <= MAX_LEN && !!STARKNET_NFTCOMMENTS_CONTRACT;\n const isProcessing = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const isOwn = (author: string) =>\n !!walletAddress && normalizeAddress(\"STARKNET\", author) === normalizeAddress(\"STARKNET\", walletAddress);\n\n const isNearBottom = () => {\n const el = messagesRef.current;\n if (!el) return true;\n return el.scrollHeight - el.scrollTop - el.clientHeight < 100;\n };\n\n useEffect(() => {\n if (isNearBottom()) {\n bottomRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }\n\n }, [comments.length]);\n\n const handleTextInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setText(e.target.value);\n e.target.style.height = \"auto\";\n e.target.style.height = Math.min(e.target.scrollHeight, 96) + \"px\";\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey && canSubmit && !isProcessing) {\n e.preventDefault();\n post();\n }\n };\n\n const post = () => {\n const body = text.trim();\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () =>\n app.getClient().api.intents.create(\"comment\", { author: signer.address, nftContract: contract, tokenId, text: body }),\n );\n })\n .then((ok) => {\n if (!ok) return;\n setText(\"\");\n if (composeRef.current) composeRef.current.style.height = \"auto\";\n void mutate();\n });\n };\n\n const handleStartConversation = () => {\n if (hasWallet) composeRef.current?.focus();\n };\n\n return (\n <div className={cn(\"flex flex-col h-[480px] overflow-hidden\", className)}>\n\n <div ref={messagesRef} className=\"flex-1 overflow-y-auto px-4 py-4\">\n {isLoading ? (\n <div className=\"space-y-4\">\n {([\n { own: false, w: \"w-40\" },\n { own: true, w: \"w-56\" },\n { own: false, w: \"w-48\" },\n { own: true, w: \"w-32\" },\n ] as const).map((item, i) => (\n <div key={i} className={`flex ${item.own ? \"justify-end\" : \"justify-start\"} gap-2`}>\n {!item.own && <Skeleton className=\"h-8 w-8 rounded-full shrink-0\" />}\n <Skeleton\n className={`h-10 ${item.w} rounded-2xl ${item.own ? \"rounded-tr-sm\" : \"rounded-tl-sm\"}`}\n />\n </div>\n ))}\n </div>\n ) : comments.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center h-full gap-4 text-center px-4\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full\" style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue) / 0.15), hsl(var(--brand-purple) / 0.15))\" }}>\n <MessageCircle className=\"h-7 w-7\" style={{ color: \"hsl(var(--brand-blue))\" }} />\n </div>\n <div>\n <p className=\"text-sm font-semibold\">Nothing here yet</p>\n <p className=\"text-xs text-muted-foreground mt-1 leading-relaxed max-w-[220px]\">\n Your comment will be minted onchain — attached to this NFT forever.\n </p>\n </div>\n <Button\n size=\"sm\"\n onClick={handleStartConversation}\n className=\"rounded-full text-white px-5\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n Write the first comment\n </Button>\n </div>\n ) : (\n <div className=\"space-y-5\">\n {comments.map((comment) => {\n const own = isOwn(comment.author);\n const avatarSeed = parseInt(comment.author.slice(2, 8), 16) % 360;\n const avatarBg = own\n ? \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\"\n : `linear-gradient(135deg, hsl(${avatarSeed}, 65%, 45%), hsl(${(avatarSeed + 60) % 360}, 65%, 55%))`;\n\n return (\n <div\n key={comment.id}\n className={`group flex gap-2.5 ${own ? \"flex-row-reverse\" : \"flex-row\"}`}\n >\n\n <Link href={profileHref({ address: comment.author })} className=\"shrink-0 mt-0.5\">\n <div\n className=\"h-9 w-9 rounded-full flex items-center justify-center text-2xs font-bold text-white select-none ring-2 ring-background hover:ring-primary/40 transition-all\"\n style={{ background: avatarBg }}\n >\n {comment.author.slice(2, 5).toUpperCase()}\n </div>\n </Link>\n\n <div className={`flex flex-col max-w-[75%] gap-1 ${own ? \"items-end\" : \"items-start\"}`}>\n\n <div className={`flex items-center gap-2 px-1 ${own ? \"flex-row-reverse\" : \"flex-row\"}`}>\n <Link\n href={profileHref({ address: comment.author })}\n className=\"text-xs font-semibold text-foreground hover:underline underline-offset-2\"\n >\n {own ? \"You\" : <AddressDisplay address={comment.author} chars={5} showCopy={false} />}\n </Link>\n <span className=\"text-2xs text-muted-foreground\" title={comment.postedAt}>\n {timeAgo(comment.postedAt)}\n </span>\n </div>\n\n <div className=\"relative\">\n {own ? (\n <div\n className=\"px-3.5 py-2.5 text-sm leading-relaxed break-words rounded-2xl rounded-tr-sm text-white\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n {comment.content}\n </div>\n ) : (\n <div className=\"px-3.5 py-2.5 text-sm leading-relaxed break-words bg-muted rounded-2xl rounded-tl-sm border border-border/50\">\n {comment.content}\n </div>\n )}\n {!own && hasWallet && (\n <button\n className=\"absolute -top-1 -right-5 opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground/40 hover:text-destructive/70\"\n title=\"Report comment\"\n aria-label=\"Report comment\"\n onClick={() => setReportTarget({ type: \"COMMENT\", commentId: comment.id })}\n >\n <Flag className=\"h-3 w-3\" />\n </button>\n )}\n </div>\n\n {comment.txHash && (\n <a\n href={`${EXPLORER_URL}/tx/${comment.txHash}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1 px-1 text-2xs font-medium transition-colors\"\n style={{ color: \"hsl(var(--brand-blue) / 0.55)\" }}\n onMouseEnter={(e) => (e.currentTarget.style.color = \"hsl(var(--brand-blue))\")}\n onMouseLeave={(e) => (e.currentTarget.style.color = \"hsl(var(--brand-blue) / 0.55)\")}\n >\n <span>⛓</span>\n <span>onchain proof</span>\n <ExternalLink className=\"h-2.5 w-2.5\" />\n </a>\n )}\n </div>\n </div>\n );\n })}\n <div ref={bottomRef} />\n </div>\n )}\n </div>\n\n <div className=\"border-t border-border/60 shrink-0\">\n {!hasWallet ? (\n <div className=\"flex items-center justify-center px-4 h-16\">\n <button type=\"button\" onClick={app.onRequireWallet} className=\"text-sm text-primary hover:underline\">\n {app.connectLabel ?? \"Connect\"} to comment\n </button>\n </div>\n ) : (\n <div className=\"px-3 pt-2 pb-3 space-y-2\">\n\n <div className=\"flex items-center gap-1.5\">\n <Zap className=\"h-3 w-3\" style={{ color: \"hsl(var(--brand-blue))\" }} />\n <span className=\"text-2xs font-semibold\" style={{ color: \"hsl(var(--brand-blue))\" }}>\n Mint your message onchain\n </span>\n </div>\n\n <div\n className=\"rounded-xl border bg-background/60 transition-all focus-within:ring-2\"\n style={{\n borderColor: \"hsl(var(--border))\",\n }}\n onFocusCapture={(e) => {\n (e.currentTarget as HTMLDivElement).style.borderColor = \"hsl(var(--brand-blue) / 0.6)\";\n (e.currentTarget as HTMLDivElement).style.boxShadow = \"0 0 0 3px hsl(var(--brand-blue) / 0.12)\";\n }}\n onBlurCapture={(e) => {\n (e.currentTarget as HTMLDivElement).style.borderColor = \"hsl(var(--border))\";\n (e.currentTarget as HTMLDivElement).style.boxShadow = \"\";\n }}\n >\n <Textarea\n ref={composeRef}\n placeholder=\"Say something onchain… it's permanent.\"\n value={text}\n onChange={handleTextInput}\n onKeyDown={handleKeyDown}\n rows={2}\n className=\"resize-none min-h-[52px] max-h-[120px] w-full border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 px-3 pt-2.5 pb-1 text-sm rounded-xl\"\n disabled={isProcessing}\n />\n <div className=\"flex items-center justify-between px-3 pb-2.5\">\n <span className=\"text-2xs text-muted-foreground/40 flex items-center gap-1\">\n Enter ↵ to post\n </span>\n <div className=\"flex items-center gap-2\">\n {byteLen > 800 && (\n <span className={`text-2xs ${byteLen > MAX_LEN ? \"text-destructive\" : \"text-muted-foreground\"}`}>\n {byteLen}/{MAX_LEN}\n </span>\n )}\n <button\n onClick={post}\n disabled={!canSubmit || isProcessing}\n className=\"flex items-center gap-1.5 h-7 px-3 text-xs font-semibold rounded-full text-white transition-all hover:opacity-90 active:scale-95 disabled:opacity-40 disabled:cursor-not-allowed\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n {isProcessing ? <Loader2 className=\"h-3 w-3 animate-spin\" /> : <Send className=\"h-3 w-3\" />}\n Post onchain\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n\n {reportTarget && ReportDialog && (\n <ReportDialog\n target={reportTarget}\n open={!!reportTarget}\n onOpenChange={(open) => { if (!open) setReportTarget(null); }}\n />\n )}\n\n <TransactionDialog tx={tx} title=\"Comment\" workingLabel=\"Posting your comment…\" firstStepLabel=\"Prepare comment\">\n <TransactionDone\n tx={tx}\n name=\"Comment\"\n title=\"Comment posted!\"\n description=\"Your comment is onchain and will appear here once indexed (~30s).\"\n footer={<RewardEarned actionType=\"comment\" />}\n />\n </TransactionDialog>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/components/comments-section.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { ExternalLink, Flag, Loader2, MessageCircle, Send, Zap } from \"lucide-react\";\nimport { normalizeAddress, profileHref, STARKNET_NFTCOMMENTS_CONTRACT } from \"@medialane/sdk\";\nimport { AddressDisplay } from \"./address-display.js\";\nimport { Button } from \"./button.js\";\nimport Link from \"./link.js\";\nimport { useMedialaneApp, type ReportTarget } from \"./medialane-app.js\";\nimport { RewardEarned } from \"./rewards/reward-earned.js\";\nimport { Skeleton } from \"./skeleton.js\";\nimport { Textarea } from \"./textarea.js\";\nimport { TransactionDialog } from \"./transaction-dialog.js\";\nimport { TransactionSuccess } from \"./transaction-success.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { EXPLORER_URL } from \"../utils/explorer-url.js\";\nimport { runIntentCalls } from \"../utils/run-intent-calls.js\";\nimport { timeAgo } from \"../utils/time.js\";\nimport { useComments } from \"../utils/use-comments.js\";\nimport { useTransaction } from \"../utils/use-transaction.js\";\n\nconst MAX_LEN = 1000;\n\nexport interface CommentsSectionProps {\n contract: string;\n tokenId: string;\n className?: string;\n}\n\nexport function CommentsSection({ contract, tokenId, className }: CommentsSectionProps) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const hasWallet = !!walletAddress;\n const { ReportDialog } = app;\n const { comments, isLoading, mutate } = useComments(contract, tokenId);\n const tx = useTransaction();\n\n const [text, setText] = useState(\"\");\n const [reportTarget, setReportTarget] = useState<ReportTarget | null>(null);\n\n const messagesRef = useRef<HTMLDivElement>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const composeRef = useRef<HTMLTextAreaElement>(null);\n\n const byteLen = new TextEncoder().encode(text).length;\n const canSubmit = text.trim().length > 0 && byteLen <= MAX_LEN && !!STARKNET_NFTCOMMENTS_CONTRACT;\n const isProcessing = tx.phase === \"preparing\" || tx.phase === \"submitting\" || tx.phase === \"confirming\";\n\n const isOwn = (author: string) =>\n !!walletAddress && normalizeAddress(\"STARKNET\", author) === normalizeAddress(\"STARKNET\", walletAddress);\n\n const isNearBottom = () => {\n const el = messagesRef.current;\n if (!el) return true;\n return el.scrollHeight - el.scrollTop - el.clientHeight < 100;\n };\n\n useEffect(() => {\n if (isNearBottom()) {\n bottomRef.current?.scrollIntoView({ behavior: \"smooth\" });\n }\n\n }, [comments.length]);\n\n const handleTextInput = (e: React.ChangeEvent<HTMLTextAreaElement>) => {\n setText(e.target.value);\n e.target.style.height = \"auto\";\n e.target.style.height = Math.min(e.target.scrollHeight, 96) + \"px\";\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (e.key === \"Enter\" && !e.shiftKey && canSubmit && !isProcessing) {\n e.preventDefault();\n post();\n }\n };\n\n const post = () => {\n const body = text.trim();\n void tx\n .run(async (signer) => {\n await runIntentCalls(signer, () =>\n app.getClient().api.intents.create(\"comment\", { author: signer.address, nftContract: contract, tokenId, text: body }),\n );\n })\n .then((ok) => {\n if (!ok) return;\n setText(\"\");\n if (composeRef.current) composeRef.current.style.height = \"auto\";\n void mutate();\n });\n };\n\n const handleStartConversation = () => {\n if (hasWallet) composeRef.current?.focus();\n };\n\n return (\n <div className={cn(\"flex flex-col h-[480px] overflow-hidden\", className)}>\n\n <div ref={messagesRef} className=\"flex-1 overflow-y-auto px-4 py-4\">\n {isLoading ? (\n <div className=\"space-y-4\">\n {([\n { own: false, w: \"w-40\" },\n { own: true, w: \"w-56\" },\n { own: false, w: \"w-48\" },\n { own: true, w: \"w-32\" },\n ] as const).map((item, i) => (\n <div key={i} className={`flex ${item.own ? \"justify-end\" : \"justify-start\"} gap-2`}>\n {!item.own && <Skeleton className=\"h-8 w-8 rounded-full shrink-0\" />}\n <Skeleton\n className={`h-10 ${item.w} rounded-2xl ${item.own ? \"rounded-tr-sm\" : \"rounded-tl-sm\"}`}\n />\n </div>\n ))}\n </div>\n ) : comments.length === 0 ? (\n <div className=\"flex flex-col items-center justify-center h-full gap-4 text-center px-4\">\n <div className=\"flex h-16 w-16 items-center justify-center rounded-full\" style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue) / 0.15), hsl(var(--brand-purple) / 0.15))\" }}>\n <MessageCircle className=\"h-7 w-7\" style={{ color: \"hsl(var(--brand-blue))\" }} />\n </div>\n <div>\n <p className=\"text-sm font-semibold\">Nothing here yet</p>\n <p className=\"text-xs text-muted-foreground mt-1 leading-relaxed max-w-[220px]\">\n Your comment will be minted onchain — attached to this NFT forever.\n </p>\n </div>\n <Button\n size=\"sm\"\n onClick={handleStartConversation}\n className=\"rounded-full text-white px-5\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n Write the first comment\n </Button>\n </div>\n ) : (\n <div className=\"space-y-5\">\n {comments.map((comment) => {\n const own = isOwn(comment.author);\n const avatarSeed = parseInt(comment.author.slice(2, 8), 16) % 360;\n const avatarBg = own\n ? \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\"\n : `linear-gradient(135deg, hsl(${avatarSeed}, 65%, 45%), hsl(${(avatarSeed + 60) % 360}, 65%, 55%))`;\n\n return (\n <div\n key={comment.id}\n className={`group flex gap-2.5 ${own ? \"flex-row-reverse\" : \"flex-row\"}`}\n >\n\n <Link href={profileHref({ address: comment.author })} className=\"shrink-0 mt-0.5\">\n <div\n className=\"h-9 w-9 rounded-full flex items-center justify-center text-2xs font-bold text-white select-none ring-2 ring-background hover:ring-primary/40 transition-all\"\n style={{ background: avatarBg }}\n >\n {comment.author.slice(2, 5).toUpperCase()}\n </div>\n </Link>\n\n <div className={`flex flex-col max-w-[75%] gap-1 ${own ? \"items-end\" : \"items-start\"}`}>\n\n <div className={`flex items-center gap-2 px-1 ${own ? \"flex-row-reverse\" : \"flex-row\"}`}>\n <Link\n href={profileHref({ address: comment.author })}\n className=\"text-xs font-semibold text-foreground hover:underline underline-offset-2\"\n >\n {own ? \"You\" : <AddressDisplay address={comment.author} chars={5} showCopy={false} />}\n </Link>\n <span className=\"text-2xs text-muted-foreground\" title={comment.postedAt}>\n {timeAgo(comment.postedAt)}\n </span>\n </div>\n\n <div className=\"relative\">\n {own ? (\n <div\n className=\"px-3.5 py-2.5 text-sm leading-relaxed break-words rounded-2xl rounded-tr-sm text-white\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n {comment.content}\n </div>\n ) : (\n <div className=\"px-3.5 py-2.5 text-sm leading-relaxed break-words bg-muted rounded-2xl rounded-tl-sm border border-border/50\">\n {comment.content}\n </div>\n )}\n {!own && hasWallet && (\n <button\n className=\"absolute -top-1 -right-5 opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground/40 hover:text-destructive/70\"\n title=\"Report comment\"\n aria-label=\"Report comment\"\n onClick={() => setReportTarget({ type: \"COMMENT\", commentId: comment.id })}\n >\n <Flag className=\"h-3 w-3\" />\n </button>\n )}\n </div>\n\n {comment.txHash && (\n <a\n href={`${EXPLORER_URL}/tx/${comment.txHash}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-1 px-1 text-2xs font-medium transition-colors\"\n style={{ color: \"hsl(var(--brand-blue) / 0.55)\" }}\n onMouseEnter={(e) => (e.currentTarget.style.color = \"hsl(var(--brand-blue))\")}\n onMouseLeave={(e) => (e.currentTarget.style.color = \"hsl(var(--brand-blue) / 0.55)\")}\n >\n <span>⛓</span>\n <span>onchain proof</span>\n <ExternalLink className=\"h-2.5 w-2.5\" />\n </a>\n )}\n </div>\n </div>\n );\n })}\n <div ref={bottomRef} />\n </div>\n )}\n </div>\n\n <div className=\"border-t border-border/60 shrink-0\">\n {!hasWallet ? (\n <div className=\"flex items-center justify-center px-4 h-16\">\n <button type=\"button\" onClick={app.onRequireWallet} className=\"text-sm text-primary hover:underline\">\n {app.connectLabel ?? \"Connect\"} to comment\n </button>\n </div>\n ) : (\n <div className=\"px-3 pt-2 pb-3 space-y-2\">\n\n <div className=\"flex items-center gap-1.5\">\n <Zap className=\"h-3 w-3\" style={{ color: \"hsl(var(--brand-blue))\" }} />\n <span className=\"text-2xs font-semibold\" style={{ color: \"hsl(var(--brand-blue))\" }}>\n Mint your message onchain\n </span>\n </div>\n\n <div\n className=\"rounded-xl border bg-background/60 transition-all focus-within:ring-2\"\n style={{\n borderColor: \"hsl(var(--border))\",\n }}\n onFocusCapture={(e) => {\n (e.currentTarget as HTMLDivElement).style.borderColor = \"hsl(var(--brand-blue) / 0.6)\";\n (e.currentTarget as HTMLDivElement).style.boxShadow = \"0 0 0 3px hsl(var(--brand-blue) / 0.12)\";\n }}\n onBlurCapture={(e) => {\n (e.currentTarget as HTMLDivElement).style.borderColor = \"hsl(var(--border))\";\n (e.currentTarget as HTMLDivElement).style.boxShadow = \"\";\n }}\n >\n <Textarea\n ref={composeRef}\n placeholder=\"Say something onchain… it's permanent.\"\n value={text}\n onChange={handleTextInput}\n onKeyDown={handleKeyDown}\n rows={2}\n className=\"resize-none min-h-[52px] max-h-[120px] w-full border-0 bg-transparent focus-visible:ring-0 focus-visible:ring-offset-0 px-3 pt-2.5 pb-1 text-sm rounded-xl\"\n disabled={isProcessing}\n />\n <div className=\"flex items-center justify-between px-3 pb-2.5\">\n <span className=\"text-2xs text-muted-foreground/40 flex items-center gap-1\">\n Enter ↵ to post\n </span>\n <div className=\"flex items-center gap-2\">\n {byteLen > 800 && (\n <span className={`text-2xs ${byteLen > MAX_LEN ? \"text-destructive\" : \"text-muted-foreground\"}`}>\n {byteLen}/{MAX_LEN}\n </span>\n )}\n <button\n onClick={post}\n disabled={!canSubmit || isProcessing}\n className=\"flex items-center gap-1.5 h-7 px-3 text-xs font-semibold rounded-full text-white transition-all hover:opacity-90 active:scale-95 disabled:opacity-40 disabled:cursor-not-allowed\"\n style={{ background: \"linear-gradient(135deg, hsl(var(--brand-blue)), hsl(var(--brand-purple)))\" }}\n >\n {isProcessing ? <Loader2 className=\"h-3 w-3 animate-spin\" /> : <Send className=\"h-3 w-3\" />}\n Post onchain\n </button>\n </div>\n </div>\n </div>\n </div>\n )}\n </div>\n\n {reportTarget && ReportDialog && (\n <ReportDialog\n target={reportTarget}\n open={!!reportTarget}\n onOpenChange={(open) => { if (!open) setReportTarget(null); }}\n />\n )}\n\n <TransactionDialog tx={tx} title=\"Comment\" workingLabel=\"Posting your comment…\" firstStepLabel=\"Prepare comment\">\n <TransactionSuccess\n name=\"Comment\"\n title=\"Comment posted!\"\n description=\"Your comment is onchain and will appear here once indexed (~30s).\"\n txHash={tx.txHash}\n actions={[{ label: \"Done\", onClick: tx.reset }]}\n >\n <RewardEarned actionType=\"comment\" />\n </TransactionSuccess>\n </TransactionDialog>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -47,7 +47,7 @@ var import_coin_launch_preview = require("../coin-launch-preview.js");
47
47
  var import_currency_icon = require("../currency-icon.js");
48
48
  var import_gradient_button = require("../gradient-button.js");
49
49
  var import_claim_route_shell = require("../claim-route-shell.js");
50
- var import_creation_success = require("../creation-success.js");
50
+ var import_transaction_success = require("../transaction-success.js");
51
51
  var import_transaction_dialog = require("../transaction-dialog.js");
52
52
  var import_wallet_required = require("../wallet-required.js");
53
53
  var import_medialane_app = require("../medialane-app.js");
@@ -182,15 +182,17 @@ function CoinCreate({ aside, tradeHref }) {
182
182
  description: "Secure your account to design and launch your own coin with permanently-locked liquidity, in a few clicks.",
183
183
  children: [
184
184
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_transaction_dialog.TransactionDialog, { tx, title: "Launch your coin", workingLabel: "Launching your coin\u2026", firstStepLabel: "Deploy your coin", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
185
- import_creation_success.CreationSuccess,
185
+ import_transaction_success.TransactionSuccess,
186
186
  {
187
187
  name: name || "Your coin",
188
188
  image: imagePreview,
189
- caption: "Your coin is live",
190
- primary: coinAddress ? { href: tradeHref(coinAddress), label: "View & trade your coin" } : { href: "/launchpad", label: "Back to Launchpad" },
191
- secondary: coinAddress ? { href: "/launchpad", label: "Back to Launchpad" } : void 0,
192
- onAgain: handleReset,
193
- againLabel: "Launch another coin",
189
+ title: "Coin launched",
190
+ description: "The supply is fixed and the liquidity is locked.",
191
+ actions: [
192
+ ...coinAddress ? [{ href: tradeHref(coinAddress), label: "View & trade your coin" }] : [],
193
+ { href: "/launchpad", label: "Back to Launchpad" },
194
+ { label: "Launch another coin", onClick: handleReset }
195
+ ],
194
196
  children: [
195
197
  profileStatus === "saving" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "text-xs text-muted-foreground flex items-center justify-center gap-1.5", children: [
196
198
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { className: "h-3 w-3 animate-spin" }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/launchpad/coin-create.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState, type ReactNode } from \"react\";\nimport { ArrowRight, Coins, ImagePlus, Loader2, X } from \"lucide-react\";\nimport { SUPPORTED_TOKENS, formatAmount, getTokenBySymbol, normalizeAddress } from \"@medialane/sdk\";\nimport { acceptFor } from \"../../utils/upload-limits.js\";\nimport {\n SUGGESTED_DEFAULT_PRICE,\n buybackQuoteRaw,\n coinToRaw as toRaw,\n fdvHuman,\n parseCreatorCoinCreated,\n teamCoinsRaw,\n validateCoinName as validateName,\n validateCoinSupply as validateSupply,\n validateCoinSymbol as validateSymbol,\n validatePrice,\n assertTransactionSucceeded,\n type CreatorCoinReceiptLike,\n} from \"@medialane/sdk/starknet\";\nimport Image from \"../image.js\";\nimport Link from \"../link.js\";\nimport { Input } from \"../input.js\";\nimport { Label } from \"../label.js\";\nimport { Textarea } from \"../textarea.js\";\nimport { CoinLaunchPreview, type CoinPreviewData } from \"../coin-launch-preview.js\";\nimport { CurrencyAmount, CurrencyIcon } from \"../currency-icon.js\";\nimport { GradientButton } from \"../gradient-button.js\";\nimport { ClaimRouteShell } from \"../claim-route-shell.js\";\nimport { CreationSuccess } from \"../creation-success.js\";\nimport { TransactionDialog } from \"../transaction-dialog.js\";\nimport { WalletRequired } from \"../wallet-required.js\";\nimport { useMedialaneApp } from \"../medialane-app.js\";\nimport { RewardEarned } from \"../rewards/reward-earned.js\";\nimport { cn } from \"../../utils/cn.js\";\nimport { suggestLaunchpadSymbol } from \"../../utils/launchpad-defaults.js\";\nimport { runIntentCalls } from \"../../utils/run-intent-calls.js\";\nimport { useTransaction } from \"../../utils/use-transaction.js\";\nimport { useLaunchpadImageUpload } from \"../../utils/use-launchpad-image-upload.js\";\nimport { useTokenBalance } from \"../../utils/media-wallet/use-erc20-balance.js\";\n\nconst QUOTE_OPTIONS = SUPPORTED_TOKENS.map((t) => t.symbol);\ntype Quote = (typeof QUOTE_OPTIONS)[number];\n\nconst SUPPLY_PRESETS = [\n { label: \"1M\", value: \"1000000\" },\n { label: \"100M\", value: \"100000000\" },\n { label: \"1B\", value: \"1000000000\" },\n];\n\ntype ProfileStatus = \"idle\" | \"saving\" | \"saved\" | \"failed\";\n\nexport interface CoinCreateProps {\n aside?: ReactNode;\n tradeHref: (coinAddress: string) => string;\n}\n\nexport function CoinCreate({ aside, tradeHref }: CoinCreateProps) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const tx = useTransaction();\n const [name, setName] = useState(\"\");\n const [symbol, setSymbol] = useState(\"\");\n const [autoSymbol, setAutoSymbol] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [supply, setSupply] = useState(\"\");\n const [quote, setQuote] = useState<Quote>(\"STRK\");\n const [price, setPrice] = useState(String(SUGGESTED_DEFAULT_PRICE));\n const [teamPct, setTeamPct] = useState(5);\n const [coinAddress, setCoinAddress] = useState<string | null>(null);\n const [profileStatus, setProfileStatus] = useState<ProfileStatus>(\"idle\");\n\n const upload = useLaunchpadImageUpload({ successMessage: \"Image ready\" });\n const { imagePreview, imageUri, imageUploading, uploadError, uploadSuccess, fileInputRef, handleImageSelect, clearImage } = upload;\n\n const quoteToken = getTokenBySymbol(quote)!;\n const { rawBalance } = useTokenBalance(quote, walletAddress ?? null);\n\n const priceNum = Number(price);\n const nameErr = name ? validateName(name) : null;\n const symErr = symbol ? validateSymbol(symbol) : null;\n const supplyErr = supply ? validateSupply(supply) : null;\n const priceErr = price ? validatePrice(quoteToken.decimals, priceNum) : \"Price is required\";\n const identityValid = !validateName(name) && !validateSymbol(symbol);\n const economicsValid = !validateSupply(supply) && !priceErr;\n\n const handleNameChange = (v: string) => {\n setName(v);\n const suggested = suggestLaunchpadSymbol(v);\n if (suggested && (!symbol || symbol === autoSymbol)) {\n setSymbol(suggested);\n setAutoSymbol(suggested);\n }\n };\n\n const preview = useMemo(() => {\n if (validateSupply(supply) || validatePrice(quoteToken.decimals, priceNum)) return null;\n const supplyHuman = Number(supply);\n const supplyRaw = toRaw(BigInt(supply));\n const teamRaw = teamCoinsRaw(supplyRaw, teamPct);\n const buybackRaw = buybackQuoteRaw(teamRaw, priceNum, quoteToken.decimals);\n return {\n fdv: fdvHuman(supplyHuman, priceNum),\n teamCoins: supplyHuman * (teamPct / 100),\n buybackRaw,\n buybackHuman: formatAmount(buybackRaw.toString(), quoteToken.decimals),\n };\n }, [supply, priceNum, teamPct, quoteToken.decimals]);\n\n const insufficient = preview != null && rawBalance != null && rawBalance < preview.buybackRaw;\n const canLaunch = identityValid && economicsValid && preview != null && teamPct > 0 && !insufficient && !imageUploading;\n\n const previewData: CoinPreviewData = {\n name,\n symbol,\n description,\n imageUrl: imagePreview,\n supplyHuman: economicsValid && supply ? Number(supply) : null,\n price: priceErr ? SUGGESTED_DEFAULT_PRICE : priceNum,\n quoteSymbol: quote,\n teamPct,\n };\n\n const handleLaunchClick = () => {\n if (!canLaunch || !walletAddress || !preview) return;\n const owner = normalizeAddress(\"STARKNET\", walletAddress);\n const supplyRaw = toRaw(BigInt(supply));\n const teamRaw = teamCoinsRaw(supplyRaw, teamPct);\n const buybackRaw = buybackQuoteRaw(teamRaw, priceNum, quoteToken.decimals);\n void tx.run(async (signer) => {\n await app.ensureSignedIn?.();\n const client = app.getClient();\n const api = client.api;\n\n const { txHash: deployHash } = await runIntentCalls(signer, () =>\n api.intents.create(\"create-coin\", { owner, name, symbol, initialSupply: supplyRaw.toString() }),\n );\n const deployReceipt = await assertTransactionSucceeded(client.provider, deployHash);\n const address = parseCreatorCoinCreated(deployReceipt as CreatorCoinReceiptLike);\n\n await runIntentCalls(signer, () =>\n api.intents.create(\"launch-coin\", {\n owner,\n creatorCoin: address,\n quoteToken: quoteToken.address,\n price: priceNum,\n initialHolders: teamPct > 0 ? [owner] : [],\n initialHoldersAmounts: teamPct > 0 ? [teamRaw.toString()] : [],\n transferRestrictionDelay: 0,\n quoteFundAmount: buybackRaw.toString(),\n }),\n );\n await api.coins.sync(address, owner).catch(() => {});\n setCoinAddress(address);\n\n if (imageUri || description) {\n setProfileStatus(\"saving\");\n await api.collections\n .updateProfile(address, { ...(imageUri ? { image: imageUri } : {}), ...(description ? { description } : {}) })\n .then(() => setProfileStatus(\"saved\"))\n .catch(() => setProfileStatus(\"failed\"));\n }\n });\n };\n\n const handleReset = () => {\n tx.reset();\n setCoinAddress(null);\n setProfileStatus(\"idle\");\n setName(\"\");\n setSymbol(\"\");\n setAutoSymbol(\"\");\n setDescription(\"\");\n setSupply(\"\");\n setPrice(String(SUGGESTED_DEFAULT_PRICE));\n setTeamPct(5);\n clearImage();\n };\n\n return (\n <WalletRequired\n icon={Coins}\n iconClassName=\"text-brand-orange\"\n title=\"Launch a Creator Coin\"\n description=\"Secure your account to design and launch your own coin with permanently-locked liquidity, in a few clicks.\"\n >\n <TransactionDialog tx={tx} title=\"Launch your coin\" workingLabel=\"Launching your coin…\" firstStepLabel=\"Deploy your coin\">\n <CreationSuccess\n name={name || \"Your coin\"}\n image={imagePreview}\n caption=\"Your coin is live\"\n primary={coinAddress ? { href: tradeHref(coinAddress), label: \"View & trade your coin\" } : { href: \"/launchpad\", label: \"Back to Launchpad\" }}\n secondary={coinAddress ? { href: \"/launchpad\", label: \"Back to Launchpad\" } : undefined}\n onAgain={handleReset}\n againLabel=\"Launch another coin\"\n >\n {profileStatus === \"saving\" && (\n <p className=\"text-xs text-muted-foreground flex items-center justify-center gap-1.5\">\n <Loader2 className=\"h-3 w-3 animate-spin\" /> Saving your coin&apos;s image &amp; description…\n </p>\n )}\n {profileStatus === \"failed\" && (\n <p className=\"text-xs text-muted-foreground text-center\">\n Couldn&apos;t save the image &amp; description right now. Add them anytime from your collection settings.\n </p>\n )}\n <RewardEarned actionType=\"launch_coin\" />\n </CreationSuccess>\n </TransactionDialog>\n\n <ClaimRouteShell\n icon={<Coins className=\"h-4 w-4 text-white\" />}\n title=\"Design your Creator Coin\"\n subtitle=\"A few steps to design and launch your coin.\"\n aside={\n <>\n <CoinLaunchPreview data={previewData} />\n {aside}\n </>\n }\n >\n <div className=\"space-y-7\">\n\n <section className=\"space-y-4\">\n <div>\n <h3 className=\"text-lg font-bold\">Give it a face</h3>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label>Coin image</Label>\n <div className=\"flex items-center gap-4\">\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n className=\"relative h-24 w-24 shrink-0 rounded-full overflow-hidden border border-dashed border-border bg-muted/20 flex items-center justify-center\"\n >\n {imagePreview ? (\n\n <Image src={imagePreview} alt=\"Coin\" fill unoptimized className=\"object-cover\" />\n ) : (\n <ImagePlus className=\"h-6 w-6 text-muted-foreground\" />\n )}\n {imageUploading && (\n <span className=\"absolute inset-0 bg-background/70 flex items-center justify-center\">\n <Loader2 className=\"h-4 w-4 animate-spin text-primary\" />\n </span>\n )}\n </button>\n <div className=\"space-y-1 text-xs text-muted-foreground\">\n <p>JPG, PNG, GIF, SVG or WebP</p>\n {imagePreview && (\n <button type=\"button\" onClick={clearImage} className=\"inline-flex items-center gap-1 text-muted-foreground active:text-foreground\">\n <X className=\"h-3 w-3\" /> Remove\n </button>\n )}\n {uploadError && <p className=\"text-destructive\">{uploadError}</p>}\n {uploadSuccess && <p className=\"text-emerald-500\">✓ {uploadSuccess}</p>}\n </div>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={acceptFor(\"image\")}\n className=\"hidden\"\n onChange={(e) => { const f = e.target.files?.[0]; if (f) void handleImageSelect(f); }}\n />\n </div>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"name\">Name</Label>\n <Input id=\"name\" value={name} onChange={(e) => handleNameChange(e.target.value)} placeholder=\"My Coin\" />\n {nameErr && <p className=\"text-xs text-destructive\">{nameErr}</p>}\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"symbol\">Symbol</Label>\n <Input id=\"symbol\" value={symbol} onChange={(e) => setSymbol(e.target.value.toUpperCase())} placeholder=\"COIN\" />\n {symErr && <p className=\"text-xs text-destructive\">{symErr}</p>}\n </div>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"description\">Description</Label>\n <Textarea\n id=\"description\"\n value={description}\n onChange={(e) => setDescription(e.target.value.slice(0, 500))}\n placeholder=\"Tell your community what this coin is about…\"\n rows={3}\n />\n </div>\n\n </section>\n\n <div className=\"h-px bg-border/60\" />\n\n <section className=\"space-y-4\">\n <div>\n <h3 className=\"text-lg font-bold\">Set the numbers</h3>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"supply\">Total supply</Label>\n <div className=\"flex gap-2 mb-1\">\n {SUPPLY_PRESETS.map((p) => (\n <button\n key={p.label}\n type=\"button\"\n onClick={() => setSupply(p.value)}\n className={cn(\n \"rounded-lg border px-3.5 py-1.5 text-sm font-medium\",\n supply === p.value ? \"border-brand-orange bg-brand-orange/10 text-brand-orange\" : \"border-border text-muted-foreground\",\n )}\n >\n {p.label}\n </button>\n ))}\n </div>\n <div className=\"relative\">\n <Input\n id=\"supply\" inputMode=\"numeric\"\n value={supply ? Number(supply).toLocaleString() : \"\"}\n onChange={(e) => setSupply(e.target.value.replace(/[^\\d]/g, \"\"))}\n placeholder=\"1,000,000\"\n className=\"pr-16 text-lg font-semibold tabular-nums\"\n />\n <span className=\"pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-sm font-medium text-muted-foreground\">\n coins\n </span>\n </div>\n {supplyErr && <p className=\"text-xs text-destructive\">{supplyErr}</p>}\n </div>\n\n <div className=\"space-y-1.5\">\n <Label>Pair</Label>\n <div className=\"flex gap-2 flex-wrap\">\n {QUOTE_OPTIONS.map((q) => (\n <button\n key={q}\n type=\"button\"\n onClick={() => setQuote(q)}\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-lg border px-3.5 py-1.5 text-sm font-medium\",\n quote === q ? \"border-brand-maeve bg-brand-maeve/10 text-brand-maeve\" : \"border-border text-muted-foreground\",\n )}\n >\n <CurrencyIcon symbol={q} size={16} />\n {q}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"price\">Price ({quote} per coin)</Label>\n <div className=\"relative\">\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2\">\n <CurrencyIcon symbol={quote} size={16} />\n </span>\n <Input\n id=\"price\" inputMode=\"decimal\" value={price}\n onChange={(e) => setPrice(e.target.value.replace(/[^0-9.]/g, \"\"))}\n placeholder={String(SUGGESTED_DEFAULT_PRICE)}\n className=\"pl-9\"\n />\n </div>\n {priceErr && price && <p className=\"text-xs text-destructive\">{priceErr}</p>}\n </div>\n\n {preview && (\n <div className=\"rounded-xl bg-muted/50 dark:bg-muted/30 p-4\">\n <p className=\"text-2xs uppercase tracking-wide text-muted-foreground\">Starting market cap</p>\n <p className=\"text-2xl font-bold tabular-nums text-brand-maeve\">\n <CurrencyAmount amount={preview.fdv.toLocaleString()} symbol={quote} iconSize={18} />\n </p>\n </div>\n )}\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"alloc\">Your allocation: {teamPct}%</Label>\n <input\n id=\"alloc\" type=\"range\" min={1} max={10} step={1}\n value={teamPct} onChange={(e) => setTeamPct(Number(e.target.value))}\n className=\"w-full accent-[hsl(var(--brand-orange))]\"\n />\n {preview && (\n <p className={cn(\"text-sm font-semibold\", insufficient ? \"text-destructive\" : \"text-foreground\")}>\n <CurrencyAmount amount={preview.buybackHuman} symbol={quote} iconSize={14} /> required\n </p>\n )}\n {insufficient && (\n <p className=\"text-xs text-destructive\">\n Your wallet doesn&apos;t have enough {quote}. Add funds, or adjust the numbers above.\n </p>\n )}\n </div>\n\n </section>\n\n <div className=\"h-px bg-border/60\" />\n\n <section className=\"space-y-4\">\n <GradientButton\n big\n onClick={handleLaunchClick}\n disabled={!canLaunch || tx.phase !== \"idle\"}\n className={!canLaunch || tx.phase !== \"idle\" ? \"opacity-40 pointer-events-none\" : \"\"}\n >\n {tx.phase !== \"idle\" ? <><Loader2 className=\"h-4 w-4 mr-1.5 animate-spin\" /> Launching…</> : <>Launch your coin <ArrowRight className=\"h-4 w-4 ml-1.5\" /></>}\n </GradientButton>\n <p className=\"text-xs text-muted-foreground text-center\">\n <Link href=\"/claim/memecoin\" className=\"underline active:text-foreground\">\n Already launched a coin? Claim it instead.\n </Link>\n </p>\n </section>\n </div>\n </ClaimRouteShell>\n </WalletRequired>\n );\n}\n"],"mappings":"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","names":["validateName","validateSymbol","validateSupply","toRaw","Image","Link"]}
1
+ {"version":3,"sources":["../../../src/components/launchpad/coin-create.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState, type ReactNode } from \"react\";\nimport { ArrowRight, Coins, ImagePlus, Loader2, X } from \"lucide-react\";\nimport { SUPPORTED_TOKENS, formatAmount, getTokenBySymbol, normalizeAddress } from \"@medialane/sdk\";\nimport { acceptFor } from \"../../utils/upload-limits.js\";\nimport {\n SUGGESTED_DEFAULT_PRICE,\n buybackQuoteRaw,\n coinToRaw as toRaw,\n fdvHuman,\n parseCreatorCoinCreated,\n teamCoinsRaw,\n validateCoinName as validateName,\n validateCoinSupply as validateSupply,\n validateCoinSymbol as validateSymbol,\n validatePrice,\n assertTransactionSucceeded,\n type CreatorCoinReceiptLike,\n} from \"@medialane/sdk/starknet\";\nimport Image from \"../image.js\";\nimport Link from \"../link.js\";\nimport { Input } from \"../input.js\";\nimport { Label } from \"../label.js\";\nimport { Textarea } from \"../textarea.js\";\nimport { CoinLaunchPreview, type CoinPreviewData } from \"../coin-launch-preview.js\";\nimport { CurrencyAmount, CurrencyIcon } from \"../currency-icon.js\";\nimport { GradientButton } from \"../gradient-button.js\";\nimport { ClaimRouteShell } from \"../claim-route-shell.js\";\nimport { TransactionSuccess } from \"../transaction-success.js\";\nimport { TransactionDialog } from \"../transaction-dialog.js\";\nimport { WalletRequired } from \"../wallet-required.js\";\nimport { useMedialaneApp } from \"../medialane-app.js\";\nimport { RewardEarned } from \"../rewards/reward-earned.js\";\nimport { cn } from \"../../utils/cn.js\";\nimport { suggestLaunchpadSymbol } from \"../../utils/launchpad-defaults.js\";\nimport { runIntentCalls } from \"../../utils/run-intent-calls.js\";\nimport { useTransaction } from \"../../utils/use-transaction.js\";\nimport { useLaunchpadImageUpload } from \"../../utils/use-launchpad-image-upload.js\";\nimport { useTokenBalance } from \"../../utils/media-wallet/use-erc20-balance.js\";\n\nconst QUOTE_OPTIONS = SUPPORTED_TOKENS.map((t) => t.symbol);\ntype Quote = (typeof QUOTE_OPTIONS)[number];\n\nconst SUPPLY_PRESETS = [\n { label: \"1M\", value: \"1000000\" },\n { label: \"100M\", value: \"100000000\" },\n { label: \"1B\", value: \"1000000000\" },\n];\n\ntype ProfileStatus = \"idle\" | \"saving\" | \"saved\" | \"failed\";\n\nexport interface CoinCreateProps {\n aside?: ReactNode;\n tradeHref: (coinAddress: string) => string;\n}\n\nexport function CoinCreate({ aside, tradeHref }: CoinCreateProps) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const tx = useTransaction();\n const [name, setName] = useState(\"\");\n const [symbol, setSymbol] = useState(\"\");\n const [autoSymbol, setAutoSymbol] = useState(\"\");\n const [description, setDescription] = useState(\"\");\n const [supply, setSupply] = useState(\"\");\n const [quote, setQuote] = useState<Quote>(\"STRK\");\n const [price, setPrice] = useState(String(SUGGESTED_DEFAULT_PRICE));\n const [teamPct, setTeamPct] = useState(5);\n const [coinAddress, setCoinAddress] = useState<string | null>(null);\n const [profileStatus, setProfileStatus] = useState<ProfileStatus>(\"idle\");\n\n const upload = useLaunchpadImageUpload({ successMessage: \"Image ready\" });\n const { imagePreview, imageUri, imageUploading, uploadError, uploadSuccess, fileInputRef, handleImageSelect, clearImage } = upload;\n\n const quoteToken = getTokenBySymbol(quote)!;\n const { rawBalance } = useTokenBalance(quote, walletAddress ?? null);\n\n const priceNum = Number(price);\n const nameErr = name ? validateName(name) : null;\n const symErr = symbol ? validateSymbol(symbol) : null;\n const supplyErr = supply ? validateSupply(supply) : null;\n const priceErr = price ? validatePrice(quoteToken.decimals, priceNum) : \"Price is required\";\n const identityValid = !validateName(name) && !validateSymbol(symbol);\n const economicsValid = !validateSupply(supply) && !priceErr;\n\n const handleNameChange = (v: string) => {\n setName(v);\n const suggested = suggestLaunchpadSymbol(v);\n if (suggested && (!symbol || symbol === autoSymbol)) {\n setSymbol(suggested);\n setAutoSymbol(suggested);\n }\n };\n\n const preview = useMemo(() => {\n if (validateSupply(supply) || validatePrice(quoteToken.decimals, priceNum)) return null;\n const supplyHuman = Number(supply);\n const supplyRaw = toRaw(BigInt(supply));\n const teamRaw = teamCoinsRaw(supplyRaw, teamPct);\n const buybackRaw = buybackQuoteRaw(teamRaw, priceNum, quoteToken.decimals);\n return {\n fdv: fdvHuman(supplyHuman, priceNum),\n teamCoins: supplyHuman * (teamPct / 100),\n buybackRaw,\n buybackHuman: formatAmount(buybackRaw.toString(), quoteToken.decimals),\n };\n }, [supply, priceNum, teamPct, quoteToken.decimals]);\n\n const insufficient = preview != null && rawBalance != null && rawBalance < preview.buybackRaw;\n const canLaunch = identityValid && economicsValid && preview != null && teamPct > 0 && !insufficient && !imageUploading;\n\n const previewData: CoinPreviewData = {\n name,\n symbol,\n description,\n imageUrl: imagePreview,\n supplyHuman: economicsValid && supply ? Number(supply) : null,\n price: priceErr ? SUGGESTED_DEFAULT_PRICE : priceNum,\n quoteSymbol: quote,\n teamPct,\n };\n\n const handleLaunchClick = () => {\n if (!canLaunch || !walletAddress || !preview) return;\n const owner = normalizeAddress(\"STARKNET\", walletAddress);\n const supplyRaw = toRaw(BigInt(supply));\n const teamRaw = teamCoinsRaw(supplyRaw, teamPct);\n const buybackRaw = buybackQuoteRaw(teamRaw, priceNum, quoteToken.decimals);\n void tx.run(async (signer) => {\n await app.ensureSignedIn?.();\n const client = app.getClient();\n const api = client.api;\n\n const { txHash: deployHash } = await runIntentCalls(signer, () =>\n api.intents.create(\"create-coin\", { owner, name, symbol, initialSupply: supplyRaw.toString() }),\n );\n const deployReceipt = await assertTransactionSucceeded(client.provider, deployHash);\n const address = parseCreatorCoinCreated(deployReceipt as CreatorCoinReceiptLike);\n\n await runIntentCalls(signer, () =>\n api.intents.create(\"launch-coin\", {\n owner,\n creatorCoin: address,\n quoteToken: quoteToken.address,\n price: priceNum,\n initialHolders: teamPct > 0 ? [owner] : [],\n initialHoldersAmounts: teamPct > 0 ? [teamRaw.toString()] : [],\n transferRestrictionDelay: 0,\n quoteFundAmount: buybackRaw.toString(),\n }),\n );\n await api.coins.sync(address, owner).catch(() => {});\n setCoinAddress(address);\n\n if (imageUri || description) {\n setProfileStatus(\"saving\");\n await api.collections\n .updateProfile(address, { ...(imageUri ? { image: imageUri } : {}), ...(description ? { description } : {}) })\n .then(() => setProfileStatus(\"saved\"))\n .catch(() => setProfileStatus(\"failed\"));\n }\n });\n };\n\n const handleReset = () => {\n tx.reset();\n setCoinAddress(null);\n setProfileStatus(\"idle\");\n setName(\"\");\n setSymbol(\"\");\n setAutoSymbol(\"\");\n setDescription(\"\");\n setSupply(\"\");\n setPrice(String(SUGGESTED_DEFAULT_PRICE));\n setTeamPct(5);\n clearImage();\n };\n\n return (\n <WalletRequired\n icon={Coins}\n iconClassName=\"text-brand-orange\"\n title=\"Launch a Creator Coin\"\n description=\"Secure your account to design and launch your own coin with permanently-locked liquidity, in a few clicks.\"\n >\n <TransactionDialog tx={tx} title=\"Launch your coin\" workingLabel=\"Launching your coin…\" firstStepLabel=\"Deploy your coin\">\n <TransactionSuccess\n name={name || \"Your coin\"}\n image={imagePreview}\n title=\"Coin launched\"\n description=\"The supply is fixed and the liquidity is locked.\"\n actions={[\n ...(coinAddress ? [{ href: tradeHref(coinAddress), label: \"View & trade your coin\" }] : []),\n { href: \"/launchpad\", label: \"Back to Launchpad\" },\n { label: \"Launch another coin\", onClick: handleReset },\n ]}\n >\n {profileStatus === \"saving\" && (\n <p className=\"text-xs text-muted-foreground flex items-center justify-center gap-1.5\">\n <Loader2 className=\"h-3 w-3 animate-spin\" /> Saving your coin&apos;s image &amp; description…\n </p>\n )}\n {profileStatus === \"failed\" && (\n <p className=\"text-xs text-muted-foreground text-center\">\n Couldn&apos;t save the image &amp; description right now. Add them anytime from your collection settings.\n </p>\n )}\n <RewardEarned actionType=\"launch_coin\" />\n </TransactionSuccess>\n </TransactionDialog>\n\n <ClaimRouteShell\n icon={<Coins className=\"h-4 w-4 text-white\" />}\n title=\"Design your Creator Coin\"\n subtitle=\"A few steps to design and launch your coin.\"\n aside={\n <>\n <CoinLaunchPreview data={previewData} />\n {aside}\n </>\n }\n >\n <div className=\"space-y-7\">\n\n <section className=\"space-y-4\">\n <div>\n <h3 className=\"text-lg font-bold\">Give it a face</h3>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label>Coin image</Label>\n <div className=\"flex items-center gap-4\">\n <button\n type=\"button\"\n onClick={() => fileInputRef.current?.click()}\n className=\"relative h-24 w-24 shrink-0 rounded-full overflow-hidden border border-dashed border-border bg-muted/20 flex items-center justify-center\"\n >\n {imagePreview ? (\n\n <Image src={imagePreview} alt=\"Coin\" fill unoptimized className=\"object-cover\" />\n ) : (\n <ImagePlus className=\"h-6 w-6 text-muted-foreground\" />\n )}\n {imageUploading && (\n <span className=\"absolute inset-0 bg-background/70 flex items-center justify-center\">\n <Loader2 className=\"h-4 w-4 animate-spin text-primary\" />\n </span>\n )}\n </button>\n <div className=\"space-y-1 text-xs text-muted-foreground\">\n <p>JPG, PNG, GIF, SVG or WebP</p>\n {imagePreview && (\n <button type=\"button\" onClick={clearImage} className=\"inline-flex items-center gap-1 text-muted-foreground active:text-foreground\">\n <X className=\"h-3 w-3\" /> Remove\n </button>\n )}\n {uploadError && <p className=\"text-destructive\">{uploadError}</p>}\n {uploadSuccess && <p className=\"text-emerald-500\">✓ {uploadSuccess}</p>}\n </div>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={acceptFor(\"image\")}\n className=\"hidden\"\n onChange={(e) => { const f = e.target.files?.[0]; if (f) void handleImageSelect(f); }}\n />\n </div>\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"name\">Name</Label>\n <Input id=\"name\" value={name} onChange={(e) => handleNameChange(e.target.value)} placeholder=\"My Coin\" />\n {nameErr && <p className=\"text-xs text-destructive\">{nameErr}</p>}\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"symbol\">Symbol</Label>\n <Input id=\"symbol\" value={symbol} onChange={(e) => setSymbol(e.target.value.toUpperCase())} placeholder=\"COIN\" />\n {symErr && <p className=\"text-xs text-destructive\">{symErr}</p>}\n </div>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"description\">Description</Label>\n <Textarea\n id=\"description\"\n value={description}\n onChange={(e) => setDescription(e.target.value.slice(0, 500))}\n placeholder=\"Tell your community what this coin is about…\"\n rows={3}\n />\n </div>\n\n </section>\n\n <div className=\"h-px bg-border/60\" />\n\n <section className=\"space-y-4\">\n <div>\n <h3 className=\"text-lg font-bold\">Set the numbers</h3>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"supply\">Total supply</Label>\n <div className=\"flex gap-2 mb-1\">\n {SUPPLY_PRESETS.map((p) => (\n <button\n key={p.label}\n type=\"button\"\n onClick={() => setSupply(p.value)}\n className={cn(\n \"rounded-lg border px-3.5 py-1.5 text-sm font-medium\",\n supply === p.value ? \"border-brand-orange bg-brand-orange/10 text-brand-orange\" : \"border-border text-muted-foreground\",\n )}\n >\n {p.label}\n </button>\n ))}\n </div>\n <div className=\"relative\">\n <Input\n id=\"supply\" inputMode=\"numeric\"\n value={supply ? Number(supply).toLocaleString() : \"\"}\n onChange={(e) => setSupply(e.target.value.replace(/[^\\d]/g, \"\"))}\n placeholder=\"1,000,000\"\n className=\"pr-16 text-lg font-semibold tabular-nums\"\n />\n <span className=\"pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-sm font-medium text-muted-foreground\">\n coins\n </span>\n </div>\n {supplyErr && <p className=\"text-xs text-destructive\">{supplyErr}</p>}\n </div>\n\n <div className=\"space-y-1.5\">\n <Label>Pair</Label>\n <div className=\"flex gap-2 flex-wrap\">\n {QUOTE_OPTIONS.map((q) => (\n <button\n key={q}\n type=\"button\"\n onClick={() => setQuote(q)}\n className={cn(\n \"inline-flex items-center gap-1.5 rounded-lg border px-3.5 py-1.5 text-sm font-medium\",\n quote === q ? \"border-brand-maeve bg-brand-maeve/10 text-brand-maeve\" : \"border-border text-muted-foreground\",\n )}\n >\n <CurrencyIcon symbol={q} size={16} />\n {q}\n </button>\n ))}\n </div>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"price\">Price ({quote} per coin)</Label>\n <div className=\"relative\">\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2\">\n <CurrencyIcon symbol={quote} size={16} />\n </span>\n <Input\n id=\"price\" inputMode=\"decimal\" value={price}\n onChange={(e) => setPrice(e.target.value.replace(/[^0-9.]/g, \"\"))}\n placeholder={String(SUGGESTED_DEFAULT_PRICE)}\n className=\"pl-9\"\n />\n </div>\n {priceErr && price && <p className=\"text-xs text-destructive\">{priceErr}</p>}\n </div>\n\n {preview && (\n <div className=\"rounded-xl bg-muted/50 dark:bg-muted/30 p-4\">\n <p className=\"text-2xs uppercase tracking-wide text-muted-foreground\">Starting market cap</p>\n <p className=\"text-2xl font-bold tabular-nums text-brand-maeve\">\n <CurrencyAmount amount={preview.fdv.toLocaleString()} symbol={quote} iconSize={18} />\n </p>\n </div>\n )}\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"alloc\">Your allocation: {teamPct}%</Label>\n <input\n id=\"alloc\" type=\"range\" min={1} max={10} step={1}\n value={teamPct} onChange={(e) => setTeamPct(Number(e.target.value))}\n className=\"w-full accent-[hsl(var(--brand-orange))]\"\n />\n {preview && (\n <p className={cn(\"text-sm font-semibold\", insufficient ? \"text-destructive\" : \"text-foreground\")}>\n <CurrencyAmount amount={preview.buybackHuman} symbol={quote} iconSize={14} /> required\n </p>\n )}\n {insufficient && (\n <p className=\"text-xs text-destructive\">\n Your wallet doesn&apos;t have enough {quote}. Add funds, or adjust the numbers above.\n </p>\n )}\n </div>\n\n </section>\n\n <div className=\"h-px bg-border/60\" />\n\n <section className=\"space-y-4\">\n <GradientButton\n big\n onClick={handleLaunchClick}\n disabled={!canLaunch || tx.phase !== \"idle\"}\n className={!canLaunch || tx.phase !== \"idle\" ? \"opacity-40 pointer-events-none\" : \"\"}\n >\n {tx.phase !== \"idle\" ? <><Loader2 className=\"h-4 w-4 mr-1.5 animate-spin\" /> Launching…</> : <>Launch your coin <ArrowRight className=\"h-4 w-4 ml-1.5\" /></>}\n </GradientButton>\n <p className=\"text-xs text-muted-foreground text-center\">\n <Link href=\"/claim/memecoin\" className=\"underline active:text-foreground\">\n Already launched a coin? Claim it instead.\n </Link>\n </p>\n </section>\n </div>\n </ClaimRouteShell>\n </WalletRequired>\n );\n}\n"],"mappings":"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","names":["validateName","validateSymbol","validateSupply","toRaw","Image","Link"]}
@@ -26,7 +26,7 @@ import { CoinLaunchPreview } from "../coin-launch-preview.js";
26
26
  import { CurrencyAmount, CurrencyIcon } from "../currency-icon.js";
27
27
  import { GradientButton } from "../gradient-button.js";
28
28
  import { ClaimRouteShell } from "../claim-route-shell.js";
29
- import { CreationSuccess } from "../creation-success.js";
29
+ import { TransactionSuccess } from "../transaction-success.js";
30
30
  import { TransactionDialog } from "../transaction-dialog.js";
31
31
  import { WalletRequired } from "../wallet-required.js";
32
32
  import { useMedialaneApp } from "../medialane-app.js";
@@ -161,15 +161,17 @@ function CoinCreate({ aside, tradeHref }) {
161
161
  description: "Secure your account to design and launch your own coin with permanently-locked liquidity, in a few clicks.",
162
162
  children: [
163
163
  /* @__PURE__ */ jsx(TransactionDialog, { tx, title: "Launch your coin", workingLabel: "Launching your coin\u2026", firstStepLabel: "Deploy your coin", children: /* @__PURE__ */ jsxs(
164
- CreationSuccess,
164
+ TransactionSuccess,
165
165
  {
166
166
  name: name || "Your coin",
167
167
  image: imagePreview,
168
- caption: "Your coin is live",
169
- primary: coinAddress ? { href: tradeHref(coinAddress), label: "View & trade your coin" } : { href: "/launchpad", label: "Back to Launchpad" },
170
- secondary: coinAddress ? { href: "/launchpad", label: "Back to Launchpad" } : void 0,
171
- onAgain: handleReset,
172
- againLabel: "Launch another coin",
168
+ title: "Coin launched",
169
+ description: "The supply is fixed and the liquidity is locked.",
170
+ actions: [
171
+ ...coinAddress ? [{ href: tradeHref(coinAddress), label: "View & trade your coin" }] : [],
172
+ { href: "/launchpad", label: "Back to Launchpad" },
173
+ { label: "Launch another coin", onClick: handleReset }
174
+ ],
173
175
  children: [
174
176
  profileStatus === "saving" && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground flex items-center justify-center gap-1.5", children: [
175
177
  /* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 animate-spin" }),