@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
@@ -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":";AAqMY,SAkBF,UAjBI,KADF;AAnMZ,SAAS,SAAS,gBAAgC;AAClD,SAAS,YAAY,OAAO,WAAW,SAAS,SAAS;AACzD,SAAS,kBAAkB,cAAc,kBAAkB,wBAAwB;AACnF,SAAS,iBAAiB;AAC1B;AAAA,EACE;AAAA,EACA;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA,oBAAoB;AAAA,EACpB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB;AAAA,EACA;AAAA,OAEK;AACP,OAAO,WAAW;AAClB,OAAO,UAAU;AACjB,SAAS,aAAa;AACtB,SAAS,aAAa;AACtB,SAAS,gBAAgB;AACzB,SAAS,yBAA+C;AACxD,SAAS,gBAAgB,oBAAoB;AAC7C,SAAS,sBAAsB;AAC/B,SAAS,uBAAuB;AAChC,SAAS,uBAAuB;AAChC,SAAS,yBAAyB;AAClC,SAAS,sBAAsB;AAC/B,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,UAAU;AACnB,SAAS,8BAA8B;AACvC,SAAS,sBAAsB;AAC/B,SAAS,sBAAsB;AAC/B,SAAS,+BAA+B;AACxC,SAAS,uBAAuB;AAEhC,MAAM,gBAAgB,iBAAiB,IAAI,CAAC,MAAM,EAAE,MAAM;AAG1D,MAAM,iBAAiB;AAAA,EACrB,EAAE,OAAO,MAAM,OAAO,UAAU;AAAA,EAChC,EAAE,OAAO,QAAQ,OAAO,YAAY;AAAA,EACpC,EAAE,OAAO,MAAM,OAAO,aAAa;AACrC;AASO,SAAS,WAAW,EAAE,OAAO,UAAU,GAAoB;AAChE,QAAM,MAAM,gBAAgB;AAC5B,QAAM,gBAAgB,IAAI;AAC1B,QAAM,KAAK,eAAe;AAC1B,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,EAAE;AACnC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,EAAE;AACvC,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,EAAE;AAC/C,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,EAAE;AACjD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,EAAE;AACvC,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAgB,MAAM;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,OAAO,uBAAuB,CAAC;AAClE,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,CAAC;AACxC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAwB,IAAI;AAClE,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAwB,MAAM;AAExE,QAAM,SAAS,wBAAwB,EAAE,gBAAgB,cAAc,CAAC;AACxE,QAAM,EAAE,cAAc,UAAU,gBAAgB,aAAa,eAAe,cAAc,mBAAmB,WAAW,IAAI;AAE5H,QAAM,aAAa,iBAAiB,KAAK;AACzC,QAAM,EAAE,WAAW,IAAI,gBAAgB,OAAO,iBAAiB,IAAI;AAEnE,QAAM,WAAW,OAAO,KAAK;AAC7B,QAAM,UAAU,OAAO,aAAa,IAAI,IAAI;AAC5C,QAAM,SAAS,SAAS,eAAe,MAAM,IAAI;AACjD,QAAM,YAAY,SAAS,eAAe,MAAM,IAAI;AACpD,QAAM,WAAW,QAAQ,cAAc,WAAW,UAAU,QAAQ,IAAI;AACxE,QAAM,gBAAgB,CAAC,aAAa,IAAI,KAAK,CAAC,eAAe,MAAM;AACnE,QAAM,iBAAiB,CAAC,eAAe,MAAM,KAAK,CAAC;AAEnD,QAAM,mBAAmB,CAAC,MAAc;AACtC,YAAQ,CAAC;AACT,UAAM,YAAY,uBAAuB,CAAC;AAC1C,QAAI,cAAc,CAAC,UAAU,WAAW,aAAa;AACnD,gBAAU,SAAS;AACnB,oBAAc,SAAS;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,UAAU,QAAQ,MAAM;AAC5B,QAAI,eAAe,MAAM,KAAK,cAAc,WAAW,UAAU,QAAQ,EAAG,QAAO;AACnF,UAAM,cAAc,OAAO,MAAM;AACjC,UAAM,YAAY,MAAM,OAAO,MAAM,CAAC;AACtC,UAAM,UAAU,aAAa,WAAW,OAAO;AAC/C,UAAM,aAAa,gBAAgB,SAAS,UAAU,WAAW,QAAQ;AACzE,WAAO;AAAA,MACL,KAAK,SAAS,aAAa,QAAQ;AAAA,MACnC,WAAW,eAAe,UAAU;AAAA,MACpC;AAAA,MACA,cAAc,aAAa,WAAW,SAAS,GAAG,WAAW,QAAQ;AAAA,IACvE;AAAA,EACF,GAAG,CAAC,QAAQ,UAAU,SAAS,WAAW,QAAQ,CAAC;AAEnD,QAAM,eAAe,WAAW,QAAQ,cAAc,QAAQ,aAAa,QAAQ;AACnF,QAAM,YAAY,iBAAiB,kBAAkB,WAAW,QAAQ,UAAU,KAAK,CAAC,gBAAgB,CAAC;AAEzG,QAAM,cAA+B;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,aAAa,kBAAkB,SAAS,OAAO,MAAM,IAAI;AAAA,IACzD,OAAO,WAAW,0BAA0B;AAAA,IAC5C,aAAa;AAAA,IACb;AAAA,EACF;AAEA,QAAM,oBAAoB,MAAM;AAC9B,QAAI,CAAC,aAAa,CAAC,iBAAiB,CAAC,QAAS;AAC9C,UAAM,QAAQ,iBAAiB,YAAY,aAAa;AACxD,UAAM,YAAY,MAAM,OAAO,MAAM,CAAC;AACtC,UAAM,UAAU,aAAa,WAAW,OAAO;AAC/C,UAAM,aAAa,gBAAgB,SAAS,UAAU,WAAW,QAAQ;AACzE,SAAK,GAAG,IAAI,OAAO,WAAW;AAC5B,YAAM,IAAI,iBAAiB;AAC3B,YAAM,SAAS,IAAI,UAAU;AAC7B,YAAM,MAAM,OAAO;AAEnB,YAAM,EAAE,QAAQ,WAAW,IAAI,MAAM;AAAA,QAAe;AAAA,QAAQ,MAC1D,IAAI,QAAQ,OAAO,eAAe,EAAE,OAAO,MAAM,QAAQ,eAAe,UAAU,SAAS,EAAE,CAAC;AAAA,MAChG;AACA,YAAM,gBAAgB,MAAM,2BAA2B,OAAO,UAAU,UAAU;AAClF,YAAM,UAAU,wBAAwB,aAAuC;AAE/E,YAAM;AAAA,QAAe;AAAA,QAAQ,MAC3B,IAAI,QAAQ,OAAO,eAAe;AAAA,UAChC;AAAA,UACA,aAAa;AAAA,UACb,YAAY,WAAW;AAAA,UACvB,OAAO;AAAA,UACP,gBAAgB,UAAU,IAAI,CAAC,KAAK,IAAI,CAAC;AAAA,UACzC,uBAAuB,UAAU,IAAI,CAAC,QAAQ,SAAS,CAAC,IAAI,CAAC;AAAA,UAC7D,0BAA0B;AAAA,UAC1B,iBAAiB,WAAW,SAAS;AAAA,QACvC,CAAC;AAAA,MACH;AACA,YAAM,IAAI,MAAM,KAAK,SAAS,KAAK,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACnD,qBAAe,OAAO;AAEtB,UAAI,YAAY,aAAa;AAC3B,yBAAiB,QAAQ;AACzB,cAAM,IAAI,YACP,cAAc,SAAS,EAAE,GAAI,WAAW,EAAE,OAAO,SAAS,IAAI,CAAC,GAAI,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC,EAAG,CAAC,EAC5G,KAAK,MAAM,iBAAiB,OAAO,CAAC,EACpC,MAAM,MAAM,iBAAiB,QAAQ,CAAC;AAAA,MAC3C;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,cAAc,MAAM;AACxB,OAAG,MAAM;AACT,mBAAe,IAAI;AACnB,qBAAiB,MAAM;AACvB,YAAQ,EAAE;AACV,cAAU,EAAE;AACZ,kBAAc,EAAE;AAChB,mBAAe,EAAE;AACjB,cAAU,EAAE;AACZ,aAAS,OAAO,uBAAuB,CAAC;AACxC,eAAW,CAAC;AACZ,eAAW;AAAA,EACb;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,eAAc;AAAA,MACd,OAAM;AAAA,MACN,aAAY;AAAA,MAEZ;AAAA,4BAAC,qBAAkB,IAAQ,OAAM,oBAAmB,cAAa,6BAAuB,gBAAe,oBACrG;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,QAAQ;AAAA,YACd,OAAO;AAAA,YACP,SAAQ;AAAA,YACR,SAAS,cAAc,EAAE,MAAM,UAAU,WAAW,GAAG,OAAO,yBAAyB,IAAI,EAAE,MAAM,cAAc,OAAO,oBAAoB;AAAA,YAC5I,WAAW,cAAc,EAAE,MAAM,cAAc,OAAO,oBAAoB,IAAI;AAAA,YAC9E,SAAS;AAAA,YACT,YAAW;AAAA,YAEV;AAAA,gCAAkB,YACjB,qBAAC,OAAE,WAAU,0EACX;AAAA,oCAAC,WAAQ,WAAU,wBAAuB;AAAA,gBAAE;AAAA,iBAC9C;AAAA,cAED,kBAAkB,YACjB,oBAAC,OAAE,WAAU,6CAA4C,8GAEzD;AAAA,cAEF,oBAAC,gBAAa,YAAW,eAAc;AAAA;AAAA;AAAA,QACzC,GACF;AAAA,QAEA;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,oBAAC,SAAM,WAAU,sBAAqB;AAAA,YAC5C,OAAM;AAAA,YACN,UAAS;AAAA,YACT,OACE,iCACE;AAAA,kCAAC,qBAAkB,MAAM,aAAa;AAAA,cACrC;AAAA,eACH;AAAA,YAGF,+BAAC,SAAI,WAAU,aAEb;AAAA,mCAAC,aAAQ,WAAU,aACjB;AAAA,oCAAC,SACC,8BAAC,QAAG,WAAU,qBAAoB,4BAAc,GAClD;AAAA,gBAEE,qBAAC,SAAI,WAAU,eACb;AAAA,sCAAC,SAAM,wBAAU;AAAA,kBACjB,qBAAC,SAAI,WAAU,2BACb;AAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,MAAK;AAAA,wBACL,SAAS,MAAM,aAAa,SAAS,MAAM;AAAA,wBAC3C,WAAU;AAAA,wBAET;AAAA,yCAEC,oBAAC,SAAM,KAAK,cAAc,KAAI,QAAO,MAAI,MAAC,aAAW,MAAC,WAAU,gBAAe,IAE/E,oBAAC,aAAU,WAAU,iCAAgC;AAAA,0BAEtD,kBACC,oBAAC,UAAK,WAAU,sEACd,8BAAC,WAAQ,WAAU,qCAAoC,GACzD;AAAA;AAAA;AAAA,oBAEJ;AAAA,oBACA,qBAAC,SAAI,WAAU,2CACb;AAAA,0CAAC,OAAE,wCAA0B;AAAA,sBAC5B,gBACC,qBAAC,YAAO,MAAK,UAAS,SAAS,YAAY,WAAU,+EACnD;AAAA,4CAAC,KAAE,WAAU,WAAU;AAAA,wBAAE;AAAA,yBAC3B;AAAA,sBAED,eAAe,oBAAC,OAAE,WAAU,oBAAoB,uBAAY;AAAA,sBAC5D,iBAAiB,qBAAC,OAAE,WAAU,oBAAmB;AAAA;AAAA,wBAAG;AAAA,yBAAc;AAAA,uBACrE;AAAA,oBACA;AAAA,sBAAC;AAAA;AAAA,wBACC,KAAK;AAAA,wBACL,MAAK;AAAA,wBACL,QAAQ,UAAU,OAAO;AAAA,wBACzB,WAAU;AAAA,wBACV,UAAU,CAAC,MAAM;AAAE,gCAAM,IAAI,EAAE,OAAO,QAAQ,CAAC;AAAG,8BAAI,EAAG,MAAK,kBAAkB,CAAC;AAAA,wBAAG;AAAA;AAAA,oBACtF;AAAA,qBACF;AAAA,mBACF;AAAA,gBAEA,qBAAC,SAAI,WAAU,6BACb;AAAA,uCAAC,SAAI,WAAU,eACb;AAAA,wCAAC,SAAM,SAAQ,QAAO,kBAAI;AAAA,oBAC1B,oBAAC,SAAM,IAAG,QAAO,OAAO,MAAM,UAAU,CAAC,MAAM,iBAAiB,EAAE,OAAO,KAAK,GAAG,aAAY,WAAU;AAAA,oBACtG,WAAW,oBAAC,OAAE,WAAU,4BAA4B,mBAAQ;AAAA,qBAC/D;AAAA,kBACA,qBAAC,SAAI,WAAU,eACb;AAAA,wCAAC,SAAM,SAAQ,UAAS,oBAAM;AAAA,oBAC9B,oBAAC,SAAM,IAAG,UAAS,OAAO,QAAQ,UAAU,CAAC,MAAM,UAAU,EAAE,OAAO,MAAM,YAAY,CAAC,GAAG,aAAY,QAAO;AAAA,oBAC9G,UAAU,oBAAC,OAAE,WAAU,4BAA4B,kBAAO;AAAA,qBAC7D;AAAA,mBACF;AAAA,gBAEA,qBAAC,SAAI,WAAU,eACb;AAAA,sCAAC,SAAM,SAAQ,eAAc,yBAAW;AAAA,kBACxC;AAAA,oBAAC;AAAA;AAAA,sBACC,IAAG;AAAA,sBACH,OAAO;AAAA,sBACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,MAAM,MAAM,GAAG,GAAG,CAAC;AAAA,sBAC5D,aAAY;AAAA,sBACZ,MAAM;AAAA;AAAA,kBACR;AAAA,mBACF;AAAA,iBAEJ;AAAA,cAEA,oBAAC,SAAI,WAAU,qBAAoB;AAAA,cAEnC,qBAAC,aAAQ,WAAU,aACjB;AAAA,oCAAC,SACC,8BAAC,QAAG,WAAU,qBAAoB,6BAAe,GACnD;AAAA,gBACE,qBAAC,SAAI,WAAU,eACb;AAAA,sCAAC,SAAM,SAAQ,UAAS,0BAAY;AAAA,kBACpC,oBAAC,SAAI,WAAU,mBACZ,yBAAe,IAAI,CAAC,MACnB;AAAA,oBAAC;AAAA;AAAA,sBAEC,MAAK;AAAA,sBACL,SAAS,MAAM,UAAU,EAAE,KAAK;AAAA,sBAChC,WAAW;AAAA,wBACT;AAAA,wBACA,WAAW,EAAE,QAAQ,6DAA6D;AAAA,sBACpF;AAAA,sBAEC,YAAE;AAAA;AAAA,oBARE,EAAE;AAAA,kBAST,CACD,GACH;AAAA,kBACA,qBAAC,SAAI,WAAU,YACb;AAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,IAAG;AAAA,wBAAS,WAAU;AAAA,wBACtB,OAAO,SAAS,OAAO,MAAM,EAAE,eAAe,IAAI;AAAA,wBAClD,UAAU,CAAC,MAAM,UAAU,EAAE,OAAO,MAAM,QAAQ,UAAU,EAAE,CAAC;AAAA,wBAC/D,aAAY;AAAA,wBACZ,WAAU;AAAA;AAAA,oBACZ;AAAA,oBACA,oBAAC,UAAK,WAAU,2GAA0G,mBAE1H;AAAA,qBACF;AAAA,kBACC,aAAa,oBAAC,OAAE,WAAU,4BAA4B,qBAAU;AAAA,mBACnE;AAAA,gBAEA,qBAAC,SAAI,WAAU,eACb;AAAA,sCAAC,SAAM,kBAAI;AAAA,kBACX,oBAAC,SAAI,WAAU,wBACZ,wBAAc,IAAI,CAAC,MAClB;AAAA,oBAAC;AAAA;AAAA,sBAEC,MAAK;AAAA,sBACL,SAAS,MAAM,SAAS,CAAC;AAAA,sBACzB,WAAW;AAAA,wBACT;AAAA,wBACA,UAAU,IAAI,0DAA0D;AAAA,sBAC1E;AAAA,sBAEA;AAAA,4CAAC,gBAAa,QAAQ,GAAG,MAAM,IAAI;AAAA,wBAClC;AAAA;AAAA;AAAA,oBATI;AAAA,kBAUP,CACD,GACH;AAAA,mBACF;AAAA,gBAEA,qBAAC,SAAI,WAAU,eACb;AAAA,uCAAC,SAAM,SAAQ,SAAQ;AAAA;AAAA,oBAAQ;AAAA,oBAAM;AAAA,qBAAU;AAAA,kBAC/C,qBAAC,SAAI,WAAU,YACb;AAAA,wCAAC,UAAK,WAAU,gEACd,8BAAC,gBAAa,QAAQ,OAAO,MAAM,IAAI,GACzC;AAAA,oBACA;AAAA,sBAAC;AAAA;AAAA,wBACC,IAAG;AAAA,wBAAQ,WAAU;AAAA,wBAAU,OAAO;AAAA,wBACtC,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,MAAM,QAAQ,YAAY,EAAE,CAAC;AAAA,wBAChE,aAAa,OAAO,uBAAuB;AAAA,wBAC3C,WAAU;AAAA;AAAA,oBACZ;AAAA,qBACF;AAAA,kBACC,YAAY,SAAS,oBAAC,OAAE,WAAU,4BAA4B,oBAAS;AAAA,mBAC1E;AAAA,gBAEC,WACC,qBAAC,SAAI,WAAU,+CACb;AAAA,sCAAC,OAAE,WAAU,0DAAyD,iCAAmB;AAAA,kBACzF,oBAAC,OAAE,WAAU,oDACX,8BAAC,kBAAe,QAAQ,QAAQ,IAAI,eAAe,GAAG,QAAQ,OAAO,UAAU,IAAI,GACrF;AAAA,mBACF;AAAA,gBAGF,qBAAC,SAAI,WAAU,eACb;AAAA,uCAAC,SAAM,SAAQ,SAAQ;AAAA;AAAA,oBAAkB;AAAA,oBAAQ;AAAA,qBAAC;AAAA,kBAClD;AAAA,oBAAC;AAAA;AAAA,sBACC,IAAG;AAAA,sBAAQ,MAAK;AAAA,sBAAQ,KAAK;AAAA,sBAAG,KAAK;AAAA,sBAAI,MAAM;AAAA,sBAC/C,OAAO;AAAA,sBAAS,UAAU,CAAC,MAAM,WAAW,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,sBAClE,WAAU;AAAA;AAAA,kBACZ;AAAA,kBACC,WACC,qBAAC,OAAE,WAAW,GAAG,yBAAyB,eAAe,qBAAqB,iBAAiB,GAC7F;AAAA,wCAAC,kBAAe,QAAQ,QAAQ,cAAc,QAAQ,OAAO,UAAU,IAAI;AAAA,oBAAE;AAAA,qBAC/E;AAAA,kBAED,gBACC,qBAAC,OAAE,WAAU,4BAA2B;AAAA;AAAA,oBACA;AAAA,oBAAM;AAAA,qBAC9C;AAAA,mBAEJ;AAAA,iBAEJ;AAAA,cAEA,oBAAC,SAAI,WAAU,qBAAoB;AAAA,cAEnC,qBAAC,aAAQ,WAAU,aACf;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,KAAG;AAAA,oBACH,SAAS;AAAA,oBACT,UAAU,CAAC,aAAa,GAAG,UAAU;AAAA,oBACrC,WAAW,CAAC,aAAa,GAAG,UAAU,SAAS,mCAAmC;AAAA,oBAEjF,aAAG,UAAU,SAAS,iCAAE;AAAA,0CAAC,WAAQ,WAAU,+BAA8B;AAAA,sBAAE;AAAA,uBAAW,IAAM,iCAAE;AAAA;AAAA,sBAAiB,oBAAC,cAAW,WAAU,kBAAiB;AAAA,uBAAE;AAAA;AAAA,gBAC3J;AAAA,gBACA,oBAAC,OAAE,WAAU,6CACX,8BAAC,QAAK,MAAK,mBAAkB,WAAU,oCAAmC,wDAE1E,GACF;AAAA,iBACJ;AAAA,eACF;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
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":[]}
@@ -48,7 +48,7 @@ var import_input = require("../input.js");
48
48
  var import_textarea = require("../textarea.js");
49
49
  var import_form = require("../form.js");
50
50
  var import_claim_route_shell = require("../claim-route-shell.js");
51
- var import_creation_success = require("../creation-success.js");
51
+ var import_transaction_success = require("../transaction-success.js");
52
52
  var import_external_link_field = require("../external-link-field.js");
53
53
  var import_medialane_collection_card = require("../medialane-collection-card.js");
54
54
  var import_transaction_dialog = require("../transaction-dialog.js");
@@ -98,22 +98,21 @@ function CollectionCreateForm({ preset, aside }) {
98
98
  (0, import_react.useEffect)(() => {
99
99
  if (tx.phase !== "success") return;
100
100
  let alive = true;
101
- const api = app.getClient().api;
101
+ const client = app.getClient();
102
102
  if (deployedAddress) {
103
103
  setViewHref((0, import_sdk.collectionHref)("STARKNET", deployedAddress));
104
- if (preset.registerAfterDeploy) void api.collections.register(deployedAddress).catch(() => {
104
+ if (preset.registerAfterDeploy) void client.api.collections.register(deployedAddress).catch(() => {
105
105
  });
106
- } else if (createdId && walletAddress) {
107
- api.collections.list({ owner: walletAddress, limit: 50 }).then((res) => {
108
- const created = (res.data ?? []).find((c) => c.collectionId === createdId);
109
- if (alive && created) setViewHref((0, import_sdk.collectionHref)("STARKNET", created.contractAddress));
106
+ } else if (createdId) {
107
+ (0, import_starknet.createdCollectionAddress)(client.provider, (0, import_sdk.getCoordinates)("STARKNET").collection721, createdId).then((address) => {
108
+ if (alive && address) setViewHref((0, import_sdk.collectionHref)("STARKNET", address));
110
109
  }).catch(() => {
111
110
  });
112
111
  }
113
112
  return () => {
114
113
  alive = false;
115
114
  };
116
- }, [tx.phase, deployedAddress, createdId, walletAddress, app, preset.registerAfterDeploy]);
115
+ }, [tx.phase, deployedAddress, createdId, app, preset.registerAfterDeploy]);
117
116
  const handleAgain = () => {
118
117
  tx.reset();
119
118
  setViewHref(null);
@@ -155,15 +154,13 @@ function CollectionCreateForm({ preset, aside }) {
155
154
  const actions = preset.actions({ address: deployedAddress, collectionHref: viewHref });
156
155
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_wallet_required.WalletRequired, { icon: Icon, iconClassName: preset.iconClass, title: preset.signedOut.title, description: preset.signedOut.description, children: [
157
156
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_transaction_dialog.TransactionDialog, { tx, title: preset.dialog.title, workingLabel: preset.dialog.workingLabel, firstStepLabel: preset.dialog.firstStepLabel, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
158
- import_creation_success.CreationSuccess,
157
+ import_transaction_success.TransactionSuccess,
159
158
  {
160
159
  name: name || preset.success.fallbackName,
161
160
  image: imagePreview,
162
- caption: preset.success.caption,
163
- primary: actions.primary,
164
- secondary: actions.secondary,
165
- onAgain: handleAgain,
166
- againLabel: preset.success.againLabel,
161
+ title: preset.success.title,
162
+ description: preset.success.description,
163
+ actions: [actions.primary, actions.secondary, { label: preset.success.againLabel, onClick: handleAgain }],
167
164
  children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_reward_earned.RewardEarned, { actionType: preset.success.reward })
168
165
  }
169
166
  ) }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/launchpad/collection-create-form.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport * as z from \"zod\";\nimport { ImagePlus, Loader2, X } from \"lucide-react\";\nimport { buildCollectionMetadata, collectionHref, getCoordinates, profileHref } from \"@medialane/sdk\";\nimport { acceptFor } from \"../../utils/upload-limits.js\";\nimport { FIELD_LIMITS } from \"../../utils/field-limits.js\";\nimport { createdCollectionFromReceipt, deployedCollectionFromReceipt } from \"@medialane/sdk/starknet\";\nimport Image from \"../image.js\";\nimport { Button } from \"../button.js\";\nimport { Input } from \"../input.js\";\nimport { Textarea } from \"../textarea.js\";\nimport { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from \"../form.js\";\nimport { ClaimRouteShell } from \"../claim-route-shell.js\";\nimport { CreationSuccess } from \"../creation-success.js\";\nimport { ExternalLinkField } from \"../external-link-field.js\";\nimport { MedialaneCollectionCard } from \"../medialane-collection-card.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 { runIntentCalls } from \"../../utils/run-intent-calls.js\";\nimport { uploadJsonToIpfs } from \"../../utils/ipfs-upload.js\";\nimport { useTransaction } from \"../../utils/use-transaction.js\";\nimport { useLaunchpadImageUpload } from \"../../utils/use-launchpad-image-upload.js\";\nimport { invalidatePortfolioCache } from \"../../utils/portfolio-cache.js\";\nimport { suggestLaunchpadSymbol } from \"../../utils/launchpad-defaults.js\";\nimport type { CollectionCreatePreset } from \"./collection-create-presets.js\";\n\nconst schema = z.object({\n name: z.string().min(1, \"Name required\").max(FIELD_LIMITS.name),\n symbol: z\n .string()\n .min(1, \"Symbol required\")\n .max(FIELD_LIMITS.symbol, `Max ${FIELD_LIMITS.symbol} characters`)\n .regex(/^[A-Z0-9]+$/, \"Uppercase letters and numbers only\"),\n description: z.string().max(FIELD_LIMITS.description).optional(),\n external_link: z\n .string()\n .max(500)\n .refine((v) => !v || v.startsWith(\"http://\") || v.startsWith(\"https://\"), {\n message: \"Must start with http:// or https://\",\n })\n .optional(),\n});\ntype FormValues = z.infer<typeof schema>;\n\nexport interface CollectionCreateFormProps {\n preset: CollectionCreatePreset;\n aside?: ReactNode;\n}\n\nexport function CollectionCreateForm({ preset, aside }: CollectionCreateFormProps) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const tx = useTransaction();\n const upload = useLaunchpadImageUpload({ successMessage: \"Image uploaded\" });\n const { imageFile, imagePreview, imageUri, imageUploading, uploadError, fileInputRef, handleImageSelect, clearImage } = upload;\n const [autoSymbol, setAutoSymbol] = useState(\"\");\n const [viewHref, setViewHref] = useState<string | null>(null);\n const Icon = preset.icon;\n\n const form = useForm<FormValues>({\n resolver: zodResolver(schema),\n defaultValues: { name: \"\", symbol: \"\", description: \"\", external_link: \"\" },\n });\n const name = form.watch(\"name\");\n\n useEffect(() => {\n if (!preset.suggestSymbol) return;\n const suggested = suggestLaunchpadSymbol(name);\n if (!suggested) return;\n const current = form.getValues(\"symbol\");\n if (!current || current === autoSymbol) {\n form.setValue(\"symbol\", suggested, { shouldDirty: false });\n setAutoSymbol(suggested);\n }\n }, [autoSymbol, name, form, preset.suggestSymbol]);\n\n const deployedAddress =\n tx.receipt && preset.service ? deployedCollectionFromReceipt(tx.receipt, preset.service) : null;\n const createdId =\n tx.receipt && !preset.service ? createdCollectionFromReceipt(tx.receipt, getCoordinates(\"STARKNET\").collection721)?.collectionId ?? null : null;\n\n useEffect(() => {\n if (tx.phase !== \"success\") return;\n let alive = true;\n const api = app.getClient().api;\n if (deployedAddress) {\n setViewHref(collectionHref(\"STARKNET\", deployedAddress));\n if (preset.registerAfterDeploy) void api.collections.register(deployedAddress).catch(() => {});\n } else if (createdId && walletAddress) {\n api.collections\n .list({ owner: walletAddress, limit: 50 })\n .then((res) => {\n const created = (res.data ?? []).find((c) => c.collectionId === createdId);\n if (alive && created) setViewHref(collectionHref(\"STARKNET\", created.contractAddress));\n })\n .catch(() => {});\n }\n return () => {\n alive = false;\n };\n }, [tx.phase, deployedAddress, createdId, walletAddress, app, preset.registerAfterDeploy]);\n\n const handleAgain = () => {\n tx.reset();\n setViewHref(null);\n setAutoSymbol(\"\");\n form.reset();\n clearImage();\n };\n\n const onSubmit = (values: FormValues) => {\n if (imageFile && !imageUri && !imageUploading) return;\n if (!walletAddress) return;\n void tx.run(async (signer) => {\n await app.ensureSignedIn?.();\n const api = app.getClient().api;\n const baseUri = await uploadJsonToIpfs(\n api,\n buildCollectionMetadata({\n name: values.name,\n description: values.description,\n image: imageUri,\n externalLink: values.external_link,\n owner: walletAddress,\n }),\n );\n await runIntentCalls(signer, () =>\n api.intents.create(\"create-collection\", {\n owner: walletAddress,\n name: values.name,\n symbol: values.symbol,\n baseUri,\n ...(preset.service ? { service: preset.service } : {}),\n }),\n );\n invalidatePortfolioCache(walletAddress);\n });\n };\n\n const { copy } = preset;\n const busy = tx.phase !== \"idle\" || imageUploading;\n const actions = preset.actions({ address: deployedAddress, collectionHref: viewHref });\n\n return (\n <WalletRequired icon={Icon} iconClassName={preset.iconClass} title={preset.signedOut.title} description={preset.signedOut.description}>\n <TransactionDialog tx={tx} title={preset.dialog.title} workingLabel={preset.dialog.workingLabel} firstStepLabel={preset.dialog.firstStepLabel}>\n <CreationSuccess\n name={name || preset.success.fallbackName}\n image={imagePreview}\n caption={preset.success.caption}\n primary={actions.primary}\n secondary={actions.secondary}\n onAgain={handleAgain}\n againLabel={preset.success.againLabel}\n >\n <RewardEarned actionType={preset.success.reward} />\n </CreationSuccess>\n </TransactionDialog>\n\n <ClaimRouteShell\n icon={<Icon className=\"h-4 w-4 text-white\" />}\n title={preset.shell.title}\n subtitle={preset.shell.subtitle}\n aside={\n <>\n <MedialaneCollectionCard\n image={imagePreview}\n name={name}\n collection={form.watch(\"symbol\") || preset.cardFallbackSymbol}\n creator={walletAddress ? `${walletAddress.slice(0, 6)}…${walletAddress.slice(-4)}` : undefined}\n creatorHref={walletAddress ? profileHref({ address: walletAddress }) : undefined}\n />\n {aside}\n </>\n }\n >\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-5\">\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">{copy.imageHeading}</p>\n <div className=\"flex items-start gap-4\">\n <div\n className=\"relative h-28 w-28 rounded-xl border-2 border-dashed border-border bg-muted flex items-center justify-center overflow-hidden shrink-0 cursor-pointer hover:border-primary/50 transition-colors\"\n role=\"button\"\n tabIndex={0}\n aria-label={`Upload ${copy.imageHeading.toLowerCase()}`}\n onClick={() => !imageUploading && fileInputRef.current?.click()}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!imageUploading) fileInputRef.current?.click();\n }\n }}\n >\n {imagePreview ? (\n <Image src={imagePreview} alt={copy.imageHeading} fill unoptimized className=\"object-cover\" />\n ) : (\n <ImagePlus className=\"h-8 w-8 text-muted-foreground\" />\n )}\n {imageUploading && (\n <div className=\"absolute inset-0 bg-background/70 flex items-center justify-center\">\n <Loader2 className=\"h-5 w-5 animate-spin text-primary\" />\n </div>\n )}\n </div>\n <div className=\"space-y-2 flex-1\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={acceptFor(\"image\")}\n className=\"hidden\"\n onChange={(e) => {\n const f = e.target.files?.[0];\n if (f) void handleImageSelect(f);\n }}\n />\n <Button type=\"button\" variant=\"outline\" size=\"sm\" disabled={imageUploading} onClick={() => fileInputRef.current?.click()}>\n {imageUploading ? (\n <>\n <Loader2 className=\"h-3.5 w-3.5 mr-1.5 animate-spin\" />\n Uploading…\n </>\n ) : imageFile ? (\n \"Change image\"\n ) : (\n \"Upload image\"\n )}\n </Button>\n {imageFile && (\n <button\n type=\"button\"\n onClick={clearImage}\n className=\"flex items-center gap-1 text-xs text-muted-foreground hover:text-destructive transition-colors\"\n >\n <X className=\"h-3 w-3\" /> Remove\n </button>\n )}\n <p className=\"text-xs text-muted-foreground\">\n JPG, PNG, GIF, SVG or WebP\n {imageUri && <span className=\"ml-2 text-emerald-500 font-medium\">✓ Uploaded</span>}\n </p>\n {copy.imageHelp && <p className=\"text-xs text-muted-foreground\">{copy.imageHelp}</p>}\n {uploadError && <p className=\"text-xs text-destructive\">{uploadError}</p>}\n </div>\n </div>\n </div>\n\n <FormField control={form.control} name=\"name\" render={({ field }) => (\n <FormItem>\n <FormLabel>{copy.nameLabel}</FormLabel>\n <FormControl><Input placeholder={copy.namePlaceholder} {...field} /></FormControl>\n <FormDescription>{copy.nameHint}</FormDescription>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"symbol\" render={({ field }) => (\n <FormItem>\n <FormLabel>Symbol *</FormLabel>\n <FormControl>\n <Input\n placeholder={copy.symbolPlaceholder}\n maxLength={FIELD_LIMITS.symbol}\n {...field}\n onChange={(e) => field.onChange(e.target.value.toUpperCase())}\n />\n </FormControl>\n <FormDescription>{copy.symbolHint}</FormDescription>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"description\" render={({ field }) => (\n <FormItem>\n <FormLabel>Description <span className=\"text-muted-foreground font-normal\">(optional)</span></FormLabel>\n <FormControl><Textarea placeholder={copy.descriptionPlaceholder} rows={3} {...field} /></FormControl>\n {copy.descriptionHint && <FormDescription>{copy.descriptionHint}</FormDescription>}\n <FormMessage />\n </FormItem>\n )} />\n\n <ExternalLinkField form={form} address={walletAddress} />\n\n <button\n type=\"submit\"\n disabled={busy}\n className={`w-full h-12 text-base font-semibold text-white rounded-xl flex items-center justify-center gap-2 transition-all hover:brightness-110 active:scale-[0.98] ${preset.buttonClass} ${busy ? \"opacity-40 pointer-events-none\" : \"\"}`}\n >\n <Icon className=\"h-4 w-4\" />\n {copy.submit}\n </button>\n {copy.footnotes.map((note) => (\n <p key={note} className=\"text-xs text-center text-muted-foreground\">{note}</p>\n ))}\n </form>\n </Form>\n </ClaimRouteShell>\n </WalletRequired>\n );\n}\n"],"mappings":"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","names":["Image"]}
1
+ {"version":3,"sources":["../../../src/components/launchpad/collection-create-form.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport * as z from \"zod\";\nimport { ImagePlus, Loader2, X } from \"lucide-react\";\nimport { buildCollectionMetadata, collectionHref, getCoordinates, profileHref } from \"@medialane/sdk\";\nimport { acceptFor } from \"../../utils/upload-limits.js\";\nimport { FIELD_LIMITS } from \"../../utils/field-limits.js\";\nimport { createdCollectionAddress, createdCollectionFromReceipt, deployedCollectionFromReceipt } from \"@medialane/sdk/starknet\";\nimport Image from \"../image.js\";\nimport { Button } from \"../button.js\";\nimport { Input } from \"../input.js\";\nimport { Textarea } from \"../textarea.js\";\nimport { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from \"../form.js\";\nimport { ClaimRouteShell } from \"../claim-route-shell.js\";\nimport { TransactionSuccess } from \"../transaction-success.js\";\nimport { ExternalLinkField } from \"../external-link-field.js\";\nimport { MedialaneCollectionCard } from \"../medialane-collection-card.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 { runIntentCalls } from \"../../utils/run-intent-calls.js\";\nimport { uploadJsonToIpfs } from \"../../utils/ipfs-upload.js\";\nimport { useTransaction } from \"../../utils/use-transaction.js\";\nimport { useLaunchpadImageUpload } from \"../../utils/use-launchpad-image-upload.js\";\nimport { invalidatePortfolioCache } from \"../../utils/portfolio-cache.js\";\nimport { suggestLaunchpadSymbol } from \"../../utils/launchpad-defaults.js\";\nimport type { CollectionCreatePreset } from \"./collection-create-presets.js\";\n\nconst schema = z.object({\n name: z.string().min(1, \"Name required\").max(FIELD_LIMITS.name),\n symbol: z\n .string()\n .min(1, \"Symbol required\")\n .max(FIELD_LIMITS.symbol, `Max ${FIELD_LIMITS.symbol} characters`)\n .regex(/^[A-Z0-9]+$/, \"Uppercase letters and numbers only\"),\n description: z.string().max(FIELD_LIMITS.description).optional(),\n external_link: z\n .string()\n .max(500)\n .refine((v) => !v || v.startsWith(\"http://\") || v.startsWith(\"https://\"), {\n message: \"Must start with http:// or https://\",\n })\n .optional(),\n});\ntype FormValues = z.infer<typeof schema>;\n\nexport interface CollectionCreateFormProps {\n preset: CollectionCreatePreset;\n aside?: ReactNode;\n}\n\nexport function CollectionCreateForm({ preset, aside }: CollectionCreateFormProps) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const tx = useTransaction();\n const upload = useLaunchpadImageUpload({ successMessage: \"Image uploaded\" });\n const { imageFile, imagePreview, imageUri, imageUploading, uploadError, fileInputRef, handleImageSelect, clearImage } = upload;\n const [autoSymbol, setAutoSymbol] = useState(\"\");\n const [viewHref, setViewHref] = useState<string | null>(null);\n const Icon = preset.icon;\n\n const form = useForm<FormValues>({\n resolver: zodResolver(schema),\n defaultValues: { name: \"\", symbol: \"\", description: \"\", external_link: \"\" },\n });\n const name = form.watch(\"name\");\n\n useEffect(() => {\n if (!preset.suggestSymbol) return;\n const suggested = suggestLaunchpadSymbol(name);\n if (!suggested) return;\n const current = form.getValues(\"symbol\");\n if (!current || current === autoSymbol) {\n form.setValue(\"symbol\", suggested, { shouldDirty: false });\n setAutoSymbol(suggested);\n }\n }, [autoSymbol, name, form, preset.suggestSymbol]);\n\n const deployedAddress =\n tx.receipt && preset.service ? deployedCollectionFromReceipt(tx.receipt, preset.service) : null;\n const createdId =\n tx.receipt && !preset.service ? createdCollectionFromReceipt(tx.receipt, getCoordinates(\"STARKNET\").collection721)?.collectionId ?? null : null;\n\n useEffect(() => {\n if (tx.phase !== \"success\") return;\n let alive = true;\n const client = app.getClient();\n if (deployedAddress) {\n setViewHref(collectionHref(\"STARKNET\", deployedAddress));\n if (preset.registerAfterDeploy) void client.api.collections.register(deployedAddress).catch(() => {});\n } else if (createdId) {\n createdCollectionAddress(client.provider, getCoordinates(\"STARKNET\").collection721, createdId)\n .then((address) => {\n if (alive && address) setViewHref(collectionHref(\"STARKNET\", address));\n })\n .catch(() => {});\n }\n return () => {\n alive = false;\n };\n }, [tx.phase, deployedAddress, createdId, app, preset.registerAfterDeploy]);\n\n const handleAgain = () => {\n tx.reset();\n setViewHref(null);\n setAutoSymbol(\"\");\n form.reset();\n clearImage();\n };\n\n const onSubmit = (values: FormValues) => {\n if (imageFile && !imageUri && !imageUploading) return;\n if (!walletAddress) return;\n void tx.run(async (signer) => {\n await app.ensureSignedIn?.();\n const api = app.getClient().api;\n const baseUri = await uploadJsonToIpfs(\n api,\n buildCollectionMetadata({\n name: values.name,\n description: values.description,\n image: imageUri,\n externalLink: values.external_link,\n owner: walletAddress,\n }),\n );\n await runIntentCalls(signer, () =>\n api.intents.create(\"create-collection\", {\n owner: walletAddress,\n name: values.name,\n symbol: values.symbol,\n baseUri,\n ...(preset.service ? { service: preset.service } : {}),\n }),\n );\n invalidatePortfolioCache(walletAddress);\n });\n };\n\n const { copy } = preset;\n const busy = tx.phase !== \"idle\" || imageUploading;\n const actions = preset.actions({ address: deployedAddress, collectionHref: viewHref });\n\n return (\n <WalletRequired icon={Icon} iconClassName={preset.iconClass} title={preset.signedOut.title} description={preset.signedOut.description}>\n <TransactionDialog tx={tx} title={preset.dialog.title} workingLabel={preset.dialog.workingLabel} firstStepLabel={preset.dialog.firstStepLabel}>\n <TransactionSuccess\n name={name || preset.success.fallbackName}\n image={imagePreview}\n title={preset.success.title}\n description={preset.success.description}\n actions={[actions.primary, actions.secondary, { label: preset.success.againLabel, onClick: handleAgain }]}\n >\n <RewardEarned actionType={preset.success.reward} />\n </TransactionSuccess>\n </TransactionDialog>\n\n <ClaimRouteShell\n icon={<Icon className=\"h-4 w-4 text-white\" />}\n title={preset.shell.title}\n subtitle={preset.shell.subtitle}\n aside={\n <>\n <MedialaneCollectionCard\n image={imagePreview}\n name={name}\n collection={form.watch(\"symbol\") || preset.cardFallbackSymbol}\n creator={walletAddress ? `${walletAddress.slice(0, 6)}…${walletAddress.slice(-4)}` : undefined}\n creatorHref={walletAddress ? profileHref({ address: walletAddress }) : undefined}\n />\n {aside}\n </>\n }\n >\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-5\">\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">{copy.imageHeading}</p>\n <div className=\"flex items-start gap-4\">\n <div\n className=\"relative h-28 w-28 rounded-xl border-2 border-dashed border-border bg-muted flex items-center justify-center overflow-hidden shrink-0 cursor-pointer hover:border-primary/50 transition-colors\"\n role=\"button\"\n tabIndex={0}\n aria-label={`Upload ${copy.imageHeading.toLowerCase()}`}\n onClick={() => !imageUploading && fileInputRef.current?.click()}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!imageUploading) fileInputRef.current?.click();\n }\n }}\n >\n {imagePreview ? (\n <Image src={imagePreview} alt={copy.imageHeading} fill unoptimized className=\"object-cover\" />\n ) : (\n <ImagePlus className=\"h-8 w-8 text-muted-foreground\" />\n )}\n {imageUploading && (\n <div className=\"absolute inset-0 bg-background/70 flex items-center justify-center\">\n <Loader2 className=\"h-5 w-5 animate-spin text-primary\" />\n </div>\n )}\n </div>\n <div className=\"space-y-2 flex-1\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={acceptFor(\"image\")}\n className=\"hidden\"\n onChange={(e) => {\n const f = e.target.files?.[0];\n if (f) void handleImageSelect(f);\n }}\n />\n <Button type=\"button\" variant=\"outline\" size=\"sm\" disabled={imageUploading} onClick={() => fileInputRef.current?.click()}>\n {imageUploading ? (\n <>\n <Loader2 className=\"h-3.5 w-3.5 mr-1.5 animate-spin\" />\n Uploading…\n </>\n ) : imageFile ? (\n \"Change image\"\n ) : (\n \"Upload image\"\n )}\n </Button>\n {imageFile && (\n <button\n type=\"button\"\n onClick={clearImage}\n className=\"flex items-center gap-1 text-xs text-muted-foreground hover:text-destructive transition-colors\"\n >\n <X className=\"h-3 w-3\" /> Remove\n </button>\n )}\n <p className=\"text-xs text-muted-foreground\">\n JPG, PNG, GIF, SVG or WebP\n {imageUri && <span className=\"ml-2 text-emerald-500 font-medium\">✓ Uploaded</span>}\n </p>\n {copy.imageHelp && <p className=\"text-xs text-muted-foreground\">{copy.imageHelp}</p>}\n {uploadError && <p className=\"text-xs text-destructive\">{uploadError}</p>}\n </div>\n </div>\n </div>\n\n <FormField control={form.control} name=\"name\" render={({ field }) => (\n <FormItem>\n <FormLabel>{copy.nameLabel}</FormLabel>\n <FormControl><Input placeholder={copy.namePlaceholder} {...field} /></FormControl>\n <FormDescription>{copy.nameHint}</FormDescription>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"symbol\" render={({ field }) => (\n <FormItem>\n <FormLabel>Symbol *</FormLabel>\n <FormControl>\n <Input\n placeholder={copy.symbolPlaceholder}\n maxLength={FIELD_LIMITS.symbol}\n {...field}\n onChange={(e) => field.onChange(e.target.value.toUpperCase())}\n />\n </FormControl>\n <FormDescription>{copy.symbolHint}</FormDescription>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"description\" render={({ field }) => (\n <FormItem>\n <FormLabel>Description <span className=\"text-muted-foreground font-normal\">(optional)</span></FormLabel>\n <FormControl><Textarea placeholder={copy.descriptionPlaceholder} rows={3} {...field} /></FormControl>\n {copy.descriptionHint && <FormDescription>{copy.descriptionHint}</FormDescription>}\n <FormMessage />\n </FormItem>\n )} />\n\n <ExternalLinkField form={form} address={walletAddress} />\n\n <button\n type=\"submit\"\n disabled={busy}\n className={`w-full h-12 text-base font-semibold text-white rounded-xl flex items-center justify-center gap-2 transition-all hover:brightness-110 active:scale-[0.98] ${preset.buttonClass} ${busy ? \"opacity-40 pointer-events-none\" : \"\"}`}\n >\n <Icon className=\"h-4 w-4\" />\n {copy.submit}\n </button>\n {copy.footnotes.map((note) => (\n <p key={note} className=\"text-xs text-center text-muted-foreground\">{note}</p>\n ))}\n </form>\n </Form>\n </ClaimRouteShell>\n </WalletRequired>\n );\n}\n"],"mappings":"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","names":["Image"]}
@@ -8,14 +8,14 @@ import { ImagePlus, Loader2, X } from "lucide-react";
8
8
  import { buildCollectionMetadata, collectionHref, getCoordinates, profileHref } from "@medialane/sdk";
9
9
  import { acceptFor } from "../../utils/upload-limits.js";
10
10
  import { FIELD_LIMITS } from "../../utils/field-limits.js";
11
- import { createdCollectionFromReceipt, deployedCollectionFromReceipt } from "@medialane/sdk/starknet";
11
+ import { createdCollectionAddress, createdCollectionFromReceipt, deployedCollectionFromReceipt } from "@medialane/sdk/starknet";
12
12
  import Image from "../image.js";
13
13
  import { Button } from "../button.js";
14
14
  import { Input } from "../input.js";
15
15
  import { Textarea } from "../textarea.js";
16
16
  import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from "../form.js";
17
17
  import { ClaimRouteShell } from "../claim-route-shell.js";
18
- import { CreationSuccess } from "../creation-success.js";
18
+ import { TransactionSuccess } from "../transaction-success.js";
19
19
  import { ExternalLinkField } from "../external-link-field.js";
20
20
  import { MedialaneCollectionCard } from "../medialane-collection-card.js";
21
21
  import { TransactionDialog } from "../transaction-dialog.js";
@@ -65,22 +65,21 @@ function CollectionCreateForm({ preset, aside }) {
65
65
  useEffect(() => {
66
66
  if (tx.phase !== "success") return;
67
67
  let alive = true;
68
- const api = app.getClient().api;
68
+ const client = app.getClient();
69
69
  if (deployedAddress) {
70
70
  setViewHref(collectionHref("STARKNET", deployedAddress));
71
- if (preset.registerAfterDeploy) void api.collections.register(deployedAddress).catch(() => {
71
+ if (preset.registerAfterDeploy) void client.api.collections.register(deployedAddress).catch(() => {
72
72
  });
73
- } else if (createdId && walletAddress) {
74
- api.collections.list({ owner: walletAddress, limit: 50 }).then((res) => {
75
- const created = (res.data ?? []).find((c) => c.collectionId === createdId);
76
- if (alive && created) setViewHref(collectionHref("STARKNET", created.contractAddress));
73
+ } else if (createdId) {
74
+ createdCollectionAddress(client.provider, getCoordinates("STARKNET").collection721, createdId).then((address) => {
75
+ if (alive && address) setViewHref(collectionHref("STARKNET", address));
77
76
  }).catch(() => {
78
77
  });
79
78
  }
80
79
  return () => {
81
80
  alive = false;
82
81
  };
83
- }, [tx.phase, deployedAddress, createdId, walletAddress, app, preset.registerAfterDeploy]);
82
+ }, [tx.phase, deployedAddress, createdId, app, preset.registerAfterDeploy]);
84
83
  const handleAgain = () => {
85
84
  tx.reset();
86
85
  setViewHref(null);
@@ -122,15 +121,13 @@ function CollectionCreateForm({ preset, aside }) {
122
121
  const actions = preset.actions({ address: deployedAddress, collectionHref: viewHref });
123
122
  return /* @__PURE__ */ jsxs(WalletRequired, { icon: Icon, iconClassName: preset.iconClass, title: preset.signedOut.title, description: preset.signedOut.description, children: [
124
123
  /* @__PURE__ */ jsx(TransactionDialog, { tx, title: preset.dialog.title, workingLabel: preset.dialog.workingLabel, firstStepLabel: preset.dialog.firstStepLabel, children: /* @__PURE__ */ jsx(
125
- CreationSuccess,
124
+ TransactionSuccess,
126
125
  {
127
126
  name: name || preset.success.fallbackName,
128
127
  image: imagePreview,
129
- caption: preset.success.caption,
130
- primary: actions.primary,
131
- secondary: actions.secondary,
132
- onAgain: handleAgain,
133
- againLabel: preset.success.againLabel,
128
+ title: preset.success.title,
129
+ description: preset.success.description,
130
+ actions: [actions.primary, actions.secondary, { label: preset.success.againLabel, onClick: handleAgain }],
134
131
  children: /* @__PURE__ */ jsx(RewardEarned, { actionType: preset.success.reward })
135
132
  }
136
133
  ) }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/launchpad/collection-create-form.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport * as z from \"zod\";\nimport { ImagePlus, Loader2, X } from \"lucide-react\";\nimport { buildCollectionMetadata, collectionHref, getCoordinates, profileHref } from \"@medialane/sdk\";\nimport { acceptFor } from \"../../utils/upload-limits.js\";\nimport { FIELD_LIMITS } from \"../../utils/field-limits.js\";\nimport { createdCollectionFromReceipt, deployedCollectionFromReceipt } from \"@medialane/sdk/starknet\";\nimport Image from \"../image.js\";\nimport { Button } from \"../button.js\";\nimport { Input } from \"../input.js\";\nimport { Textarea } from \"../textarea.js\";\nimport { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from \"../form.js\";\nimport { ClaimRouteShell } from \"../claim-route-shell.js\";\nimport { CreationSuccess } from \"../creation-success.js\";\nimport { ExternalLinkField } from \"../external-link-field.js\";\nimport { MedialaneCollectionCard } from \"../medialane-collection-card.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 { runIntentCalls } from \"../../utils/run-intent-calls.js\";\nimport { uploadJsonToIpfs } from \"../../utils/ipfs-upload.js\";\nimport { useTransaction } from \"../../utils/use-transaction.js\";\nimport { useLaunchpadImageUpload } from \"../../utils/use-launchpad-image-upload.js\";\nimport { invalidatePortfolioCache } from \"../../utils/portfolio-cache.js\";\nimport { suggestLaunchpadSymbol } from \"../../utils/launchpad-defaults.js\";\nimport type { CollectionCreatePreset } from \"./collection-create-presets.js\";\n\nconst schema = z.object({\n name: z.string().min(1, \"Name required\").max(FIELD_LIMITS.name),\n symbol: z\n .string()\n .min(1, \"Symbol required\")\n .max(FIELD_LIMITS.symbol, `Max ${FIELD_LIMITS.symbol} characters`)\n .regex(/^[A-Z0-9]+$/, \"Uppercase letters and numbers only\"),\n description: z.string().max(FIELD_LIMITS.description).optional(),\n external_link: z\n .string()\n .max(500)\n .refine((v) => !v || v.startsWith(\"http://\") || v.startsWith(\"https://\"), {\n message: \"Must start with http:// or https://\",\n })\n .optional(),\n});\ntype FormValues = z.infer<typeof schema>;\n\nexport interface CollectionCreateFormProps {\n preset: CollectionCreatePreset;\n aside?: ReactNode;\n}\n\nexport function CollectionCreateForm({ preset, aside }: CollectionCreateFormProps) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const tx = useTransaction();\n const upload = useLaunchpadImageUpload({ successMessage: \"Image uploaded\" });\n const { imageFile, imagePreview, imageUri, imageUploading, uploadError, fileInputRef, handleImageSelect, clearImage } = upload;\n const [autoSymbol, setAutoSymbol] = useState(\"\");\n const [viewHref, setViewHref] = useState<string | null>(null);\n const Icon = preset.icon;\n\n const form = useForm<FormValues>({\n resolver: zodResolver(schema),\n defaultValues: { name: \"\", symbol: \"\", description: \"\", external_link: \"\" },\n });\n const name = form.watch(\"name\");\n\n useEffect(() => {\n if (!preset.suggestSymbol) return;\n const suggested = suggestLaunchpadSymbol(name);\n if (!suggested) return;\n const current = form.getValues(\"symbol\");\n if (!current || current === autoSymbol) {\n form.setValue(\"symbol\", suggested, { shouldDirty: false });\n setAutoSymbol(suggested);\n }\n }, [autoSymbol, name, form, preset.suggestSymbol]);\n\n const deployedAddress =\n tx.receipt && preset.service ? deployedCollectionFromReceipt(tx.receipt, preset.service) : null;\n const createdId =\n tx.receipt && !preset.service ? createdCollectionFromReceipt(tx.receipt, getCoordinates(\"STARKNET\").collection721)?.collectionId ?? null : null;\n\n useEffect(() => {\n if (tx.phase !== \"success\") return;\n let alive = true;\n const api = app.getClient().api;\n if (deployedAddress) {\n setViewHref(collectionHref(\"STARKNET\", deployedAddress));\n if (preset.registerAfterDeploy) void api.collections.register(deployedAddress).catch(() => {});\n } else if (createdId && walletAddress) {\n api.collections\n .list({ owner: walletAddress, limit: 50 })\n .then((res) => {\n const created = (res.data ?? []).find((c) => c.collectionId === createdId);\n if (alive && created) setViewHref(collectionHref(\"STARKNET\", created.contractAddress));\n })\n .catch(() => {});\n }\n return () => {\n alive = false;\n };\n }, [tx.phase, deployedAddress, createdId, walletAddress, app, preset.registerAfterDeploy]);\n\n const handleAgain = () => {\n tx.reset();\n setViewHref(null);\n setAutoSymbol(\"\");\n form.reset();\n clearImage();\n };\n\n const onSubmit = (values: FormValues) => {\n if (imageFile && !imageUri && !imageUploading) return;\n if (!walletAddress) return;\n void tx.run(async (signer) => {\n await app.ensureSignedIn?.();\n const api = app.getClient().api;\n const baseUri = await uploadJsonToIpfs(\n api,\n buildCollectionMetadata({\n name: values.name,\n description: values.description,\n image: imageUri,\n externalLink: values.external_link,\n owner: walletAddress,\n }),\n );\n await runIntentCalls(signer, () =>\n api.intents.create(\"create-collection\", {\n owner: walletAddress,\n name: values.name,\n symbol: values.symbol,\n baseUri,\n ...(preset.service ? { service: preset.service } : {}),\n }),\n );\n invalidatePortfolioCache(walletAddress);\n });\n };\n\n const { copy } = preset;\n const busy = tx.phase !== \"idle\" || imageUploading;\n const actions = preset.actions({ address: deployedAddress, collectionHref: viewHref });\n\n return (\n <WalletRequired icon={Icon} iconClassName={preset.iconClass} title={preset.signedOut.title} description={preset.signedOut.description}>\n <TransactionDialog tx={tx} title={preset.dialog.title} workingLabel={preset.dialog.workingLabel} firstStepLabel={preset.dialog.firstStepLabel}>\n <CreationSuccess\n name={name || preset.success.fallbackName}\n image={imagePreview}\n caption={preset.success.caption}\n primary={actions.primary}\n secondary={actions.secondary}\n onAgain={handleAgain}\n againLabel={preset.success.againLabel}\n >\n <RewardEarned actionType={preset.success.reward} />\n </CreationSuccess>\n </TransactionDialog>\n\n <ClaimRouteShell\n icon={<Icon className=\"h-4 w-4 text-white\" />}\n title={preset.shell.title}\n subtitle={preset.shell.subtitle}\n aside={\n <>\n <MedialaneCollectionCard\n image={imagePreview}\n name={name}\n collection={form.watch(\"symbol\") || preset.cardFallbackSymbol}\n creator={walletAddress ? `${walletAddress.slice(0, 6)}…${walletAddress.slice(-4)}` : undefined}\n creatorHref={walletAddress ? profileHref({ address: walletAddress }) : undefined}\n />\n {aside}\n </>\n }\n >\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-5\">\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">{copy.imageHeading}</p>\n <div className=\"flex items-start gap-4\">\n <div\n className=\"relative h-28 w-28 rounded-xl border-2 border-dashed border-border bg-muted flex items-center justify-center overflow-hidden shrink-0 cursor-pointer hover:border-primary/50 transition-colors\"\n role=\"button\"\n tabIndex={0}\n aria-label={`Upload ${copy.imageHeading.toLowerCase()}`}\n onClick={() => !imageUploading && fileInputRef.current?.click()}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!imageUploading) fileInputRef.current?.click();\n }\n }}\n >\n {imagePreview ? (\n <Image src={imagePreview} alt={copy.imageHeading} fill unoptimized className=\"object-cover\" />\n ) : (\n <ImagePlus className=\"h-8 w-8 text-muted-foreground\" />\n )}\n {imageUploading && (\n <div className=\"absolute inset-0 bg-background/70 flex items-center justify-center\">\n <Loader2 className=\"h-5 w-5 animate-spin text-primary\" />\n </div>\n )}\n </div>\n <div className=\"space-y-2 flex-1\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={acceptFor(\"image\")}\n className=\"hidden\"\n onChange={(e) => {\n const f = e.target.files?.[0];\n if (f) void handleImageSelect(f);\n }}\n />\n <Button type=\"button\" variant=\"outline\" size=\"sm\" disabled={imageUploading} onClick={() => fileInputRef.current?.click()}>\n {imageUploading ? (\n <>\n <Loader2 className=\"h-3.5 w-3.5 mr-1.5 animate-spin\" />\n Uploading…\n </>\n ) : imageFile ? (\n \"Change image\"\n ) : (\n \"Upload image\"\n )}\n </Button>\n {imageFile && (\n <button\n type=\"button\"\n onClick={clearImage}\n className=\"flex items-center gap-1 text-xs text-muted-foreground hover:text-destructive transition-colors\"\n >\n <X className=\"h-3 w-3\" /> Remove\n </button>\n )}\n <p className=\"text-xs text-muted-foreground\">\n JPG, PNG, GIF, SVG or WebP\n {imageUri && <span className=\"ml-2 text-emerald-500 font-medium\">✓ Uploaded</span>}\n </p>\n {copy.imageHelp && <p className=\"text-xs text-muted-foreground\">{copy.imageHelp}</p>}\n {uploadError && <p className=\"text-xs text-destructive\">{uploadError}</p>}\n </div>\n </div>\n </div>\n\n <FormField control={form.control} name=\"name\" render={({ field }) => (\n <FormItem>\n <FormLabel>{copy.nameLabel}</FormLabel>\n <FormControl><Input placeholder={copy.namePlaceholder} {...field} /></FormControl>\n <FormDescription>{copy.nameHint}</FormDescription>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"symbol\" render={({ field }) => (\n <FormItem>\n <FormLabel>Symbol *</FormLabel>\n <FormControl>\n <Input\n placeholder={copy.symbolPlaceholder}\n maxLength={FIELD_LIMITS.symbol}\n {...field}\n onChange={(e) => field.onChange(e.target.value.toUpperCase())}\n />\n </FormControl>\n <FormDescription>{copy.symbolHint}</FormDescription>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"description\" render={({ field }) => (\n <FormItem>\n <FormLabel>Description <span className=\"text-muted-foreground font-normal\">(optional)</span></FormLabel>\n <FormControl><Textarea placeholder={copy.descriptionPlaceholder} rows={3} {...field} /></FormControl>\n {copy.descriptionHint && <FormDescription>{copy.descriptionHint}</FormDescription>}\n <FormMessage />\n </FormItem>\n )} />\n\n <ExternalLinkField form={form} address={walletAddress} />\n\n <button\n type=\"submit\"\n disabled={busy}\n className={`w-full h-12 text-base font-semibold text-white rounded-xl flex items-center justify-center gap-2 transition-all hover:brightness-110 active:scale-[0.98] ${preset.buttonClass} ${busy ? \"opacity-40 pointer-events-none\" : \"\"}`}\n >\n <Icon className=\"h-4 w-4\" />\n {copy.submit}\n </button>\n {copy.footnotes.map((note) => (\n <p key={note} className=\"text-xs text-center text-muted-foreground\">{note}</p>\n ))}\n </form>\n </Form>\n </ClaimRouteShell>\n </WalletRequired>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/components/launchpad/collection-create-form.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState, type ReactNode } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { zodResolver } from \"@hookform/resolvers/zod\";\nimport * as z from \"zod\";\nimport { ImagePlus, Loader2, X } from \"lucide-react\";\nimport { buildCollectionMetadata, collectionHref, getCoordinates, profileHref } from \"@medialane/sdk\";\nimport { acceptFor } from \"../../utils/upload-limits.js\";\nimport { FIELD_LIMITS } from \"../../utils/field-limits.js\";\nimport { createdCollectionAddress, createdCollectionFromReceipt, deployedCollectionFromReceipt } from \"@medialane/sdk/starknet\";\nimport Image from \"../image.js\";\nimport { Button } from \"../button.js\";\nimport { Input } from \"../input.js\";\nimport { Textarea } from \"../textarea.js\";\nimport { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage } from \"../form.js\";\nimport { ClaimRouteShell } from \"../claim-route-shell.js\";\nimport { TransactionSuccess } from \"../transaction-success.js\";\nimport { ExternalLinkField } from \"../external-link-field.js\";\nimport { MedialaneCollectionCard } from \"../medialane-collection-card.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 { runIntentCalls } from \"../../utils/run-intent-calls.js\";\nimport { uploadJsonToIpfs } from \"../../utils/ipfs-upload.js\";\nimport { useTransaction } from \"../../utils/use-transaction.js\";\nimport { useLaunchpadImageUpload } from \"../../utils/use-launchpad-image-upload.js\";\nimport { invalidatePortfolioCache } from \"../../utils/portfolio-cache.js\";\nimport { suggestLaunchpadSymbol } from \"../../utils/launchpad-defaults.js\";\nimport type { CollectionCreatePreset } from \"./collection-create-presets.js\";\n\nconst schema = z.object({\n name: z.string().min(1, \"Name required\").max(FIELD_LIMITS.name),\n symbol: z\n .string()\n .min(1, \"Symbol required\")\n .max(FIELD_LIMITS.symbol, `Max ${FIELD_LIMITS.symbol} characters`)\n .regex(/^[A-Z0-9]+$/, \"Uppercase letters and numbers only\"),\n description: z.string().max(FIELD_LIMITS.description).optional(),\n external_link: z\n .string()\n .max(500)\n .refine((v) => !v || v.startsWith(\"http://\") || v.startsWith(\"https://\"), {\n message: \"Must start with http:// or https://\",\n })\n .optional(),\n});\ntype FormValues = z.infer<typeof schema>;\n\nexport interface CollectionCreateFormProps {\n preset: CollectionCreatePreset;\n aside?: ReactNode;\n}\n\nexport function CollectionCreateForm({ preset, aside }: CollectionCreateFormProps) {\n const app = useMedialaneApp();\n const walletAddress = app.walletAddress;\n const tx = useTransaction();\n const upload = useLaunchpadImageUpload({ successMessage: \"Image uploaded\" });\n const { imageFile, imagePreview, imageUri, imageUploading, uploadError, fileInputRef, handleImageSelect, clearImage } = upload;\n const [autoSymbol, setAutoSymbol] = useState(\"\");\n const [viewHref, setViewHref] = useState<string | null>(null);\n const Icon = preset.icon;\n\n const form = useForm<FormValues>({\n resolver: zodResolver(schema),\n defaultValues: { name: \"\", symbol: \"\", description: \"\", external_link: \"\" },\n });\n const name = form.watch(\"name\");\n\n useEffect(() => {\n if (!preset.suggestSymbol) return;\n const suggested = suggestLaunchpadSymbol(name);\n if (!suggested) return;\n const current = form.getValues(\"symbol\");\n if (!current || current === autoSymbol) {\n form.setValue(\"symbol\", suggested, { shouldDirty: false });\n setAutoSymbol(suggested);\n }\n }, [autoSymbol, name, form, preset.suggestSymbol]);\n\n const deployedAddress =\n tx.receipt && preset.service ? deployedCollectionFromReceipt(tx.receipt, preset.service) : null;\n const createdId =\n tx.receipt && !preset.service ? createdCollectionFromReceipt(tx.receipt, getCoordinates(\"STARKNET\").collection721)?.collectionId ?? null : null;\n\n useEffect(() => {\n if (tx.phase !== \"success\") return;\n let alive = true;\n const client = app.getClient();\n if (deployedAddress) {\n setViewHref(collectionHref(\"STARKNET\", deployedAddress));\n if (preset.registerAfterDeploy) void client.api.collections.register(deployedAddress).catch(() => {});\n } else if (createdId) {\n createdCollectionAddress(client.provider, getCoordinates(\"STARKNET\").collection721, createdId)\n .then((address) => {\n if (alive && address) setViewHref(collectionHref(\"STARKNET\", address));\n })\n .catch(() => {});\n }\n return () => {\n alive = false;\n };\n }, [tx.phase, deployedAddress, createdId, app, preset.registerAfterDeploy]);\n\n const handleAgain = () => {\n tx.reset();\n setViewHref(null);\n setAutoSymbol(\"\");\n form.reset();\n clearImage();\n };\n\n const onSubmit = (values: FormValues) => {\n if (imageFile && !imageUri && !imageUploading) return;\n if (!walletAddress) return;\n void tx.run(async (signer) => {\n await app.ensureSignedIn?.();\n const api = app.getClient().api;\n const baseUri = await uploadJsonToIpfs(\n api,\n buildCollectionMetadata({\n name: values.name,\n description: values.description,\n image: imageUri,\n externalLink: values.external_link,\n owner: walletAddress,\n }),\n );\n await runIntentCalls(signer, () =>\n api.intents.create(\"create-collection\", {\n owner: walletAddress,\n name: values.name,\n symbol: values.symbol,\n baseUri,\n ...(preset.service ? { service: preset.service } : {}),\n }),\n );\n invalidatePortfolioCache(walletAddress);\n });\n };\n\n const { copy } = preset;\n const busy = tx.phase !== \"idle\" || imageUploading;\n const actions = preset.actions({ address: deployedAddress, collectionHref: viewHref });\n\n return (\n <WalletRequired icon={Icon} iconClassName={preset.iconClass} title={preset.signedOut.title} description={preset.signedOut.description}>\n <TransactionDialog tx={tx} title={preset.dialog.title} workingLabel={preset.dialog.workingLabel} firstStepLabel={preset.dialog.firstStepLabel}>\n <TransactionSuccess\n name={name || preset.success.fallbackName}\n image={imagePreview}\n title={preset.success.title}\n description={preset.success.description}\n actions={[actions.primary, actions.secondary, { label: preset.success.againLabel, onClick: handleAgain }]}\n >\n <RewardEarned actionType={preset.success.reward} />\n </TransactionSuccess>\n </TransactionDialog>\n\n <ClaimRouteShell\n icon={<Icon className=\"h-4 w-4 text-white\" />}\n title={preset.shell.title}\n subtitle={preset.shell.subtitle}\n aside={\n <>\n <MedialaneCollectionCard\n image={imagePreview}\n name={name}\n collection={form.watch(\"symbol\") || preset.cardFallbackSymbol}\n creator={walletAddress ? `${walletAddress.slice(0, 6)}…${walletAddress.slice(-4)}` : undefined}\n creatorHref={walletAddress ? profileHref({ address: walletAddress }) : undefined}\n />\n {aside}\n </>\n }\n >\n <Form {...form}>\n <form onSubmit={form.handleSubmit(onSubmit)} className=\"space-y-5\">\n <div className=\"space-y-2\">\n <p className=\"text-sm font-medium\">{copy.imageHeading}</p>\n <div className=\"flex items-start gap-4\">\n <div\n className=\"relative h-28 w-28 rounded-xl border-2 border-dashed border-border bg-muted flex items-center justify-center overflow-hidden shrink-0 cursor-pointer hover:border-primary/50 transition-colors\"\n role=\"button\"\n tabIndex={0}\n aria-label={`Upload ${copy.imageHeading.toLowerCase()}`}\n onClick={() => !imageUploading && fileInputRef.current?.click()}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n if (!imageUploading) fileInputRef.current?.click();\n }\n }}\n >\n {imagePreview ? (\n <Image src={imagePreview} alt={copy.imageHeading} fill unoptimized className=\"object-cover\" />\n ) : (\n <ImagePlus className=\"h-8 w-8 text-muted-foreground\" />\n )}\n {imageUploading && (\n <div className=\"absolute inset-0 bg-background/70 flex items-center justify-center\">\n <Loader2 className=\"h-5 w-5 animate-spin text-primary\" />\n </div>\n )}\n </div>\n <div className=\"space-y-2 flex-1\">\n <input\n ref={fileInputRef}\n type=\"file\"\n accept={acceptFor(\"image\")}\n className=\"hidden\"\n onChange={(e) => {\n const f = e.target.files?.[0];\n if (f) void handleImageSelect(f);\n }}\n />\n <Button type=\"button\" variant=\"outline\" size=\"sm\" disabled={imageUploading} onClick={() => fileInputRef.current?.click()}>\n {imageUploading ? (\n <>\n <Loader2 className=\"h-3.5 w-3.5 mr-1.5 animate-spin\" />\n Uploading…\n </>\n ) : imageFile ? (\n \"Change image\"\n ) : (\n \"Upload image\"\n )}\n </Button>\n {imageFile && (\n <button\n type=\"button\"\n onClick={clearImage}\n className=\"flex items-center gap-1 text-xs text-muted-foreground hover:text-destructive transition-colors\"\n >\n <X className=\"h-3 w-3\" /> Remove\n </button>\n )}\n <p className=\"text-xs text-muted-foreground\">\n JPG, PNG, GIF, SVG or WebP\n {imageUri && <span className=\"ml-2 text-emerald-500 font-medium\">✓ Uploaded</span>}\n </p>\n {copy.imageHelp && <p className=\"text-xs text-muted-foreground\">{copy.imageHelp}</p>}\n {uploadError && <p className=\"text-xs text-destructive\">{uploadError}</p>}\n </div>\n </div>\n </div>\n\n <FormField control={form.control} name=\"name\" render={({ field }) => (\n <FormItem>\n <FormLabel>{copy.nameLabel}</FormLabel>\n <FormControl><Input placeholder={copy.namePlaceholder} {...field} /></FormControl>\n <FormDescription>{copy.nameHint}</FormDescription>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"symbol\" render={({ field }) => (\n <FormItem>\n <FormLabel>Symbol *</FormLabel>\n <FormControl>\n <Input\n placeholder={copy.symbolPlaceholder}\n maxLength={FIELD_LIMITS.symbol}\n {...field}\n onChange={(e) => field.onChange(e.target.value.toUpperCase())}\n />\n </FormControl>\n <FormDescription>{copy.symbolHint}</FormDescription>\n <FormMessage />\n </FormItem>\n )} />\n\n <FormField control={form.control} name=\"description\" render={({ field }) => (\n <FormItem>\n <FormLabel>Description <span className=\"text-muted-foreground font-normal\">(optional)</span></FormLabel>\n <FormControl><Textarea placeholder={copy.descriptionPlaceholder} rows={3} {...field} /></FormControl>\n {copy.descriptionHint && <FormDescription>{copy.descriptionHint}</FormDescription>}\n <FormMessage />\n </FormItem>\n )} />\n\n <ExternalLinkField form={form} address={walletAddress} />\n\n <button\n type=\"submit\"\n disabled={busy}\n className={`w-full h-12 text-base font-semibold text-white rounded-xl flex items-center justify-center gap-2 transition-all hover:brightness-110 active:scale-[0.98] ${preset.buttonClass} ${busy ? \"opacity-40 pointer-events-none\" : \"\"}`}\n >\n <Icon className=\"h-4 w-4\" />\n {copy.submit}\n </button>\n {copy.footnotes.map((note) => (\n <p key={note} className=\"text-xs text-center text-muted-foreground\">{note}</p>\n ))}\n </form>\n </Form>\n </ClaimRouteShell>\n </WalletRequired>\n );\n}\n"],"mappings":"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","names":[]}
@@ -34,7 +34,7 @@ const CLUB_PRESET = {
34
34
  signedOut: { title: "Secure your account to create a club", description: "Create a club, then mint membership cards for your community." },
35
35
  shell: { title: "Create Club", subtitle: "One club \u2014 create membership tiers and mint cards to your community." },
36
36
  dialog: { title: "Create club", workingLabel: "Creating your club\u2026", firstStepLabel: "Prepare metadata" },
37
- success: { caption: "Your club is live", fallbackName: "Your club", reward: "create_club", againLabel: "Create another" },
37
+ success: { title: "Club created", description: "Each membership you create is recorded onchain under your wallet.", fallbackName: "Your club", reward: "create_club", againLabel: "Create another" },
38
38
  cardFallbackSymbol: "Club",
39
39
  copy: {
40
40
  imageHeading: "Club image",
@@ -59,7 +59,7 @@ const TICKETS_PRESET = {
59
59
  signedOut: { title: "Secure your account to create tickets", description: "Create a tickets collection, then mint tickets to your audience." },
60
60
  shell: { title: "Create Ticket Collection", subtitle: "One collection \u2014 create tickets and mint them to your audience." },
61
61
  dialog: { title: "Create tickets collection", workingLabel: "Creating your collection\u2026", firstStepLabel: "Prepare metadata" },
62
- success: { caption: "Your collection is live", fallbackName: "Your collection", reward: "create_ticket_collection", againLabel: "Create another" },
62
+ success: { title: "Ticket collection created", description: "Each ticket you mint into it is recorded onchain under your wallet.", fallbackName: "Your collection", reward: "create_ticket_collection", againLabel: "Create another" },
63
63
  cardFallbackSymbol: "Tickets",
64
64
  copy: {
65
65
  imageHeading: "Collection image",
@@ -84,7 +84,7 @@ const EDITIONS_PRESET = {
84
84
  signedOut: { title: "Secure your account to create a collection", description: "Create a collection where each piece can have multiple editions." },
85
85
  shell: { title: "Create an Edition Collection", subtitle: "Create a collection where each piece can have multiple editions \u2014 free to publish, and it's yours." },
86
86
  dialog: { title: "Create collection", workingLabel: "Creating your collection\u2026", firstStepLabel: "Prepare metadata" },
87
- success: { caption: "Your collection is live", fallbackName: "Your collection", reward: "create_collection", againLabel: "Create another" },
87
+ success: { title: "Collection created", description: "Each asset you mint into it carries its own license terms.", fallbackName: "Your collection", reward: "create_collection", againLabel: "Create another" },
88
88
  cardFallbackSymbol: "Editions",
89
89
  copy: {
90
90
  imageHeading: "Collection image",
@@ -117,7 +117,7 @@ const SINGLE_PRESET = {
117
117
  signedOut: { title: "Secure your account to create a collection", description: "Set up a collection to mint your work into." },
118
118
  shell: { title: "Create a Collection", subtitle: "Set up a collection to mint your work into \u2014 free to publish, and it's yours." },
119
119
  dialog: { title: "Create collection", workingLabel: "Creating your collection\u2026", firstStepLabel: "Prepare metadata" },
120
- success: { caption: "Your collection is live", fallbackName: "Your collection", reward: "create_collection", againLabel: "Create another" },
120
+ success: { title: "Collection created", description: "Each asset you mint into it carries its own license terms.", fallbackName: "Your collection", reward: "create_collection", againLabel: "Create another" },
121
121
  cardFallbackSymbol: "Collection",
122
122
  copy: {
123
123
  imageHeading: "Collection image",
@@ -132,10 +132,10 @@ const SINGLE_PRESET = {
132
132
  },
133
133
  suggestSymbol: false,
134
134
  registerAfterDeploy: false,
135
- actions: ({ collectionHref }) => ({
136
- primary: { href: "/launchpad/single-editions", label: "Mint an asset" },
137
- secondary: collectionHref ? { href: collectionHref, label: "View collection" } : void 0
138
- })
135
+ actions: ({ collectionHref }) => {
136
+ const mint = { href: "/launchpad/single-editions", label: "Mint an asset" };
137
+ return collectionHref ? { primary: { href: collectionHref, label: "View collection" }, secondary: mint } : { primary: mint };
138
+ }
139
139
  };
140
140
  // Annotate the CommonJS export names for ESM import in node:
141
141
  0 && (module.exports = {