{l.description || "The creator has not added a description yet. The contract details below are recorded on-chain."}
-{v.error}
: null} diff --git a/app/src/components/launchpad/LaunchForm.tsx b/app/src/components/launchpad/LaunchForm.tsx index b591e739..975cb1ee 100644 --- a/app/src/components/launchpad/LaunchForm.tsx +++ b/app/src/components/launchpad/LaunchForm.tsx @@ -22,6 +22,7 @@ import { BUY_PRESETS, defaultFirstBuy, gasReserveInQuote, suggestFirstBuy } from import { getFirstBuyDeclined, getFirstBuyDeclinedServer, setFirstBuyDeclined, subscribeFirstBuyDeclined } from "@/lib/launchpad/first-buy-session"; import { encodeV4ExactInSingle, type PoolKey } from "@/lib/launchpad/swap"; import { GITLAWB_SITE } from "@/lib/launchpad/gitlawb"; +import { parseXHandle } from "@/lib/launchpad/xHandle"; import { CHAINS, CHAIN_LABELS, CHAIN_KEYS, DEFAULT_CHAIN, BUILDER_DATA_SUFFIX, explorerTx, shortAddr, type ChainKey } from "@/lib/chainPublic"; import { friendlyError } from "@/lib/errors"; import { Spinner } from "@/components/Skeleton"; @@ -274,6 +275,8 @@ export default function LaunchForm({ ethUsd, gitlawbUsd = null, initialChain = D if (quoteKey === "gitlawb" && quote.usd === null && !customMcap.trim() && startTick === null) errors.push("GITLAWB price unavailable right now: enter a custom starting market cap in GITLAWB, or reload."); if (image && !/^https:\/\//.test(image.trim())) errors.push("Image must be an https URL."); if (website && !/^https:\/\//.test(website.trim())) errors.push("Website must be an https URL."); + const xParsed = parseXHandle(x); + if (!xParsed.ok) errors.push("X: enter a handle or an x.com link."); const split = useMemo(() => buildRecipients(rows), [rows]); if (feePips > 0 && beneficiary === "custom") errors.push(...split.errors); if (initialBuyRaw === undefined) errors.push(`First buy: enter an amount in ${quote.symbol}, or leave it empty.`); @@ -647,7 +650,7 @@ export default function LaunchForm({ ethUsd, gitlawbUsd = null, initialChain = D - setX(e.target.value)} placeholder="@handle" /> + setX(e.target.value)} onBlur={() => { if (xParsed.ok && xParsed.handle) setX(`@${xParsed.handle}`); }} placeholder="@handle or x.com link" autoCapitalize="none" spellCheck={false} />