@hammerock/cca-widget 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/AuctionCard.tsx","../src/useAuction.ts","../src/wallet.ts","../src/styles.ts","../src/mount.ts"],"sourcesContent":["export { AuctionCard } from \"./AuctionCard\";\nexport type { AuctionCardProps } from \"./AuctionCard\";\nexport { useAuction } from \"./useAuction\";\nexport type { AuctionData, UseAuctionResult } from \"./useAuction\";\nexport { connectWallet, hasInjectedWallet, getInjectedProvider } from \"./wallet\";\nexport type { ConnectedWallet, Eip1193Provider } from \"./wallet\";\nexport { mount } from \"./mount\";\nexport type { MountHandle } from \"./mount\";\n","import { useMemo, useState } from \"react\";\nimport {\n alignPriceToTickBoundary,\n buildBidTransactions,\n checkBidReadiness,\n decimalToQ96,\n describeBidBlocker,\n getPrevTickHint,\n formatQ96,\n formatQ96Compact,\n formatTokenAmount,\n mpsToFraction,\n} from \"@hammerock/cca-sdk\";\nimport type { Address } from \"@hammerock/cca-sdk\";\nimport { useAuction } from \"./useAuction\";\nimport { connectWallet, hasInjectedWallet } from \"./wallet\";\nimport type { ConnectedWallet } from \"./wallet\";\nimport { styles } from \"./styles\";\n\nexport interface AuctionCardProps {\n /** Address of the ContinuousClearingAuction to display. */\n auction: Address;\n /** Public RPC the widget reads through. Never put a keyed URL here - the\n * widget runs in the visitor's browser. */\n rpcUrl: string;\n /** Chain id the auction lives on. Must be a supported testnet. */\n chainId: number;\n /** Optional deployed AuctionStateLens. Omit to use the eth_call override. */\n lensAddress?: Address;\n /** How often to re-read live state, in ms. */\n pollIntervalMs?: number;\n /** Hide the bid form and render read-only. */\n readOnly?: boolean;\n}\n\ntype TxState =\n | { kind: \"idle\" }\n | { kind: \"working\"; message: string }\n | { kind: \"sent\"; hash: string }\n | { kind: \"error\"; message: string };\n\nexport function AuctionCard(props: AuctionCardProps) {\n const { data, error, loading, client, refresh } = useAuction(props);\n\n const [wallet, setWallet] = useState<ConnectedWallet | null>(null);\n const [maxPrice, setMaxPrice] = useState(\"\");\n const [amount, setAmount] = useState(\"\");\n const [tx, setTx] = useState<TxState>({ kind: \"idle\" });\n\n const parsed = useMemo(() => {\n let maxPriceQ96 = 0n;\n let amountUnits = 0n;\n let parseError: string | null = null;\n\n try {\n if (maxPrice.trim()) maxPriceQ96 = decimalToQ96(maxPrice.trim());\n } catch {\n parseError = \"Maximum price must be a decimal number.\";\n }\n\n if (amount.trim() && data) {\n const decimals = data.currency.decimals;\n if (!/^\\d+(\\.\\d+)?$/.test(amount.trim())) {\n parseError = \"Bid amount must be a decimal number.\";\n } else {\n const [whole = \"0\", frac = \"\"] = amount.trim().split(\".\");\n const padded = (frac + \"0\".repeat(decimals)).slice(0, decimals);\n amountUnits = BigInt(whole) * 10n ** BigInt(decimals) + BigInt(padded || \"0\");\n }\n }\n\n return { maxPriceQ96, amountUnits, parseError };\n }, [maxPrice, amount, data]);\n\n if (loading && !data) {\n return (\n <div style={styles.card}>\n <div style={styles.muted}>Loading auction…</div>\n </div>\n );\n }\n\n if (error && !data) {\n return (\n <div style={styles.card}>\n <div style={styles.error}>Could not load auction</div>\n <div style={styles.muted}>{error.message.split(\"\\n\")[0]}</div>\n </div>\n );\n }\n\n if (!data) return null;\n\n const { info, state, token, currency, status } = data;\n const hasCleared = state.totalCleared > 0n;\n const schedulePercent = (mpsToFraction(state.checkpoint.cumulativeMps) * 100).toFixed(0);\n\n // The single source of truth for whether bidding is possible. An ended\n // auction disables the button with a stated reason rather than failing on\n // submit, which is the common way these embeds break.\n const blocker = describeBidBlocker({\n status,\n amount: parsed.amountUnits,\n maxPriceQ96: parsed.maxPriceQ96,\n floorPriceQ96: info.floorPriceQ96,\n tickSpacing: info.tickSpacing,\n });\n\n // The contract only accepts prices on a tick boundary, so show the bidder the\n // price that will actually be submitted rather than surprising them later.\n const alignedPriceQ96 =\n parsed.maxPriceQ96 > 0n\n ? alignPriceToTickBoundary(parsed.maxPriceQ96, info.tickSpacing)\n : 0n;\n const priceWasSnapped = alignedPriceQ96 > 0n && alignedPriceQ96 !== parsed.maxPriceQ96;\n\n const bidDisabled =\n props.readOnly ||\n status !== \"live\" ||\n tx.kind === \"working\" ||\n parsed.parseError !== null ||\n blocker !== null;\n\n async function onConnect() {\n if (!client) return;\n setTx({ kind: \"working\", message: \"Connecting wallet…\" });\n try {\n setWallet(await connectWallet(client.chain));\n setTx({ kind: \"idle\" });\n } catch (cause) {\n setTx({ kind: \"error\", message: (cause as Error).message });\n }\n }\n\n async function onSubmitBid() {\n if (!client || !wallet || !data) return;\n\n try {\n setTx({ kind: \"working\", message: \"Checking balance…\" });\n\n const readiness = await checkBidReadiness(client, {\n auction: props.auction,\n currency: data.info.currency,\n bidder: wallet.address,\n amount: parsed.amountUnits,\n });\n\n if (!readiness.hasBalance) {\n setTx({\n kind: \"error\",\n message: `Insufficient ${data.currency.symbol}. You hold ${formatTokenAmount(readiness.balance, data.currency)}.`,\n });\n return;\n }\n\n // ERC-20 bids go through Permit2, so there may be two approvals before\n // the bid itself. buildBidTransactions returns exactly the steps needed.\n const prevTickPriceQ96 = await getPrevTickHint(client, props.auction, parsed.maxPriceQ96);\n\n const steps = buildBidTransactions({\n auction: props.auction,\n currency: data.info.currency,\n maxPriceQ96: parsed.maxPriceQ96,\n amount: parsed.amountUnits,\n owner: wallet.address,\n readiness,\n prevTickPriceQ96,\n // Snapped DOWN to a tick boundary; the contract rejects any other price.\n tickSpacing: data.info.tickSpacing,\n });\n\n let hash = \"\" as `0x${string}`;\n for (const [index, step] of steps.entries()) {\n setTx({ kind: \"working\", message: `${step.label} (${index + 1}/${steps.length})…` });\n hash = await wallet.walletClient.sendTransaction({\n account: wallet.address,\n chain: client.chain,\n to: step.request.to,\n data: step.request.data,\n value: step.request.value,\n });\n // Approvals must land before the next step can read them.\n if (index < steps.length - 1) {\n await client.publicClient.waitForTransactionReceipt({ hash });\n }\n }\n\n setTx({ kind: \"sent\", hash });\n refresh();\n } catch (cause) {\n const message = (cause as Error).message.split(\"\\n\")[0] ?? \"Transaction failed.\";\n setTx({ kind: \"error\", message });\n }\n }\n\n const explorer = client?.chain.blockExplorers?.default?.url;\n\n return (\n <div style={styles.card}>\n <div style={styles.headerRow}>\n <div>\n <div style={styles.symbol}>{token.symbol}</div>\n <div style={styles.muted}>{token.name}</div>\n </div>\n <StatusPill status={status} isGraduated={state.isGraduated} />\n </div>\n\n <div style={styles.priceBlock}>\n <div style={styles.label}>Clearing price</div>\n <div style={styles.price}>\n {formatQ96Compact(state.checkpoint.clearingPriceQ96)}{\" \"}\n <span style={styles.priceUnit}>\n {currency.symbol} / {token.symbol}\n </span>\n </div>\n </div>\n\n <dl style={styles.grid}>\n <Row label=\"Raised\" value={formatTokenAmount(state.currencyRaised, currency)} />\n <Row\n label=\"Cleared\"\n value={\n hasCleared\n ? `${formatTokenAmount(state.totalCleared, token)} of ${formatTokenAmount(info.totalSupply, token)}`\n : \"Nothing cleared\"\n }\n />\n <Row\n label=\"Supply schedule\"\n value={`${schedulePercent}% released`}\n hint=\"Schedule progress, not the amount sold.\"\n />\n <Row\n label={status === \"pending\" ? \"Starts in\" : status === \"live\" ? \"Time left\" : \"Closed\"}\n value={\n status === \"ended\"\n ? `block ${info.endBlock.toString()}`\n : `~${formatMinutes(data.secondsRemaining)} (${data.blocksRemaining.toString()} blocks)`\n }\n />\n </dl>\n\n {props.readOnly ? null : (\n <div style={styles.form}>\n {status !== \"live\" ? (\n // Say why, rather than showing a button that would revert.\n <div style={styles.notice}>\n {status === \"ended\"\n ? \"This auction has ended. Bidding is closed.\"\n : \"This auction has not opened yet.\"}\n </div>\n ) : (\n <>\n <label style={styles.label} htmlFor=\"beacon-max-price\">\n Max price ({currency.symbol} per {token.symbol})\n </label>\n <input\n id=\"beacon-max-price\"\n style={styles.input}\n value={maxPrice}\n onChange={(event) => setMaxPrice(event.target.value)}\n placeholder={formatQ96(info.floorPriceQ96)}\n inputMode=\"decimal\"\n />\n\n {priceWasSnapped ? (\n <div style={styles.muted}>\n Will bid at {formatQ96Compact(alignedPriceQ96)} {currency.symbol} — prices snap\n down to the auction&apos;s tick spacing.\n </div>\n ) : null}\n\n <label style={styles.label} htmlFor=\"beacon-amount\">\n Bid amount ({currency.symbol})\n </label>\n <input\n id=\"beacon-amount\"\n style={styles.input}\n value={amount}\n onChange={(event) => setAmount(event.target.value)}\n placeholder=\"0.0\"\n inputMode=\"decimal\"\n />\n </>\n )}\n\n {wallet === null ? (\n <button\n type=\"button\"\n style={{ ...styles.button, ...(status !== \"live\" ? styles.buttonDisabled : {}) }}\n disabled={status !== \"live\" || !hasInjectedWallet()}\n onClick={() => void onConnect()}\n >\n {hasInjectedWallet() ? \"Connect wallet\" : \"No browser wallet detected\"}\n </button>\n ) : (\n <button\n type=\"button\"\n style={{ ...styles.button, ...(bidDisabled ? styles.buttonDisabled : {}) }}\n disabled={bidDisabled}\n onClick={() => void onSubmitBid()}\n title={blocker ?? undefined}\n >\n {tx.kind === \"working\" ? tx.message : \"Submit bid\"}\n </button>\n )}\n\n {wallet ? (\n <div style={styles.muted}>\n Connected {wallet.address.slice(0, 6)}…{wallet.address.slice(-4)}\n </div>\n ) : null}\n\n {parsed.parseError ? <div style={styles.error}>{parsed.parseError}</div> : null}\n {blocker && status === \"live\" && !parsed.parseError ? (\n <div style={styles.muted}>{blocker}</div>\n ) : null}\n\n {tx.kind === \"error\" ? <div style={styles.error}>{tx.message}</div> : null}\n {tx.kind === \"sent\" ? (\n <div style={styles.success}>\n Bid submitted.{\" \"}\n {explorer ? (\n <a\n href={`${explorer}/tx/${tx.hash}`}\n target=\"_blank\"\n rel=\"noreferrer\"\n style={styles.link}\n >\n View transaction\n </a>\n ) : (\n tx.hash\n )}\n </div>\n ) : null}\n </div>\n )}\n\n <div style={styles.footer}>\n Powered by <strong>Beacon</strong> · Uniswap CCA\n </div>\n </div>\n );\n}\n\nfunction Row({ label, value, hint }: { label: string; value: string; hint?: string }) {\n return (\n <div style={styles.row}>\n <dt style={styles.label} title={hint}>\n {label}\n </dt>\n <dd style={styles.value}>{value}</dd>\n </div>\n );\n}\n\nfunction StatusPill({ status, isGraduated }: { status: string; isGraduated: boolean }) {\n const palette =\n status === \"live\"\n ? styles.pillLive\n : status === \"pending\"\n ? styles.pillPending\n : styles.pillEnded;\n\n return (\n <div style={styles.pillRow}>\n <span style={{ ...styles.pill, ...palette }}>\n {status === \"live\" ? \"Live\" : status === \"pending\" ? \"Upcoming\" : \"Ended\"}\n </span>\n {isGraduated ? <span style={{ ...styles.pill, ...styles.pillGraduated }}>Graduated</span> : null}\n </div>\n );\n}\n\nfunction formatMinutes(seconds: number): string {\n if (seconds <= 0) return \"0m\";\n const hours = Math.floor(seconds / 3600);\n const minutes = Math.round((seconds % 3600) / 60);\n return hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;\n}\n","import { useCallback, useEffect, useRef, useState } from \"react\";\nimport {\n createBeaconClient,\n deriveStatus,\n getAuctionInfo,\n getAuctionState,\n getTokenMetadata,\n} from \"@hammerock/cca-sdk\";\nimport type {\n Address,\n AuctionInfo,\n AuctionState,\n AuctionStatus,\n BeaconClient,\n TokenMetadata,\n} from \"@hammerock/cca-sdk\";\n\n/**\n * Everything the card renders, read through @hammerock/cca-sdk.\n *\n * The widget runs on somebody else's website, so it reads through whatever\n * public RPC the embedder passes in. It never needs a lens deployment: the SDK\n * runs `AuctionStateLens` through an `eth_call` state override.\n */\nexport interface AuctionData {\n info: AuctionInfo;\n state: AuctionState;\n token: TokenMetadata;\n currency: TokenMetadata;\n status: AuctionStatus;\n headBlock: bigint;\n blocksRemaining: bigint;\n secondsRemaining: number;\n}\n\nexport interface UseAuctionResult {\n data: AuctionData | null;\n error: Error | null;\n loading: boolean;\n client: BeaconClient | null;\n refresh: () => void;\n}\n\nexport function useAuction(options: {\n auction: Address;\n rpcUrl: string;\n chainId: number;\n lensAddress?: Address;\n pollIntervalMs?: number;\n}): UseAuctionResult {\n const { auction, rpcUrl, chainId, lensAddress, pollIntervalMs = 12_000 } = options;\n\n const [data, setData] = useState<AuctionData | null>(null);\n const [error, setError] = useState<Error | null>(null);\n const [loading, setLoading] = useState(true);\n const [nonce, setNonce] = useState(0);\n\n // Immutable per-auction data, cached across polls. Held in a ref rather than\n // read from `data` so the polling effect does not need `data` as a\n // dependency - which would restart the timer on every tick.\n const staticRef = useRef<{\n info?: AuctionInfo;\n token?: TokenMetadata;\n currency?: TokenMetadata;\n }>({});\n\n /** Set once the auction has closed, so polling can stop. */\n const endedAtRef = useRef(false);\n\n const clientRef = useRef<BeaconClient | null>(null);\n if (!clientRef.current) {\n try {\n clientRef.current = createBeaconClient({ rpcUrl, chainId, lensAddress });\n } catch {\n clientRef.current = null;\n }\n }\n\n const refresh = useCallback(() => setNonce((value) => value + 1), []);\n\n useEffect(() => {\n const client = clientRef.current;\n if (!client) {\n setError(new Error(`Unsupported or non-testnet chain id ${chainId}.`));\n setLoading(false);\n return;\n }\n\n let cancelled = false;\n\n async function load(isInitial: boolean) {\n try {\n if (isInitial) setLoading(true);\n\n const [info, state, headBlock] = await Promise.all([\n // Config is immutable, so only read it once.\n staticRef.current.info ?? getAuctionInfo(client!, auction),\n getAuctionState(client!, auction),\n client!.publicClient.getBlockNumber(),\n ]);\n\n const [token, currency] = await Promise.all([\n staticRef.current.token ?? getTokenMetadata(client!, info.token),\n staticRef.current.currency ?? getTokenMetadata(client!, info.currency),\n ]);\n\n staticRef.current = { info, token, currency };\n\n if (cancelled) return;\n\n const status = deriveStatus(info, headBlock);\n endedAtRef.current = status === \"ended\";\n const blocksRemaining =\n status === \"pending\"\n ? info.startBlock - headBlock\n : status === \"live\"\n ? info.endBlock - headBlock\n : 0n;\n\n setData({\n info,\n state,\n token,\n currency,\n status,\n headBlock,\n blocksRemaining,\n secondsRemaining: Number(blocksRemaining) * client!.blockTimeSeconds,\n });\n setError(null);\n } catch (cause) {\n if (!cancelled) setError(cause as Error);\n } finally {\n if (!cancelled) setLoading(false);\n }\n }\n\n void load(true);\n\n // An ended auction cannot change, so stop polling once it has closed.\n const timer = setInterval(() => {\n if (staticRef.current.info && endedAtRef.current) {\n clearInterval(timer);\n return;\n }\n void load(false);\n }, pollIntervalMs);\n\n return () => {\n cancelled = true;\n clearInterval(timer);\n };\n }, [auction, chainId, pollIntervalMs, nonce]);\n\n return { data, error, loading, client: clientRef.current, refresh };\n}\n","/**\n * Wallet access for the bid form.\n *\n * Deliberately uses the EIP-1193 provider the browser already exposes\n * (`window.ethereum`) through viem, rather than wagmi.\n *\n * Reasoning: this widget's whole point is that a project can drop it into their\n * own site. wagmi requires the host page to wrap the tree in `WagmiProvider`\n * plus a React Query client, which a plain marketing site cannot do at all, and\n * which the vanilla `<script>` mount path would have to bundle wholesale. Going\n * straight to EIP-1193 keeps the widget self-contained and works identically in\n * the React and vanilla builds. A host that already uses wagmi can pass its own\n * wallet client in instead.\n */\nimport { createWalletClient, custom } from \"viem\";\nimport type { Address, Chain, WalletClient } from \"viem\";\n\n/** The subset of EIP-1193 the widget needs. */\nexport interface Eip1193Provider {\n request(args: { method: string; params?: unknown[] }): Promise<unknown>;\n on?(event: string, handler: (...args: unknown[]) => void): void;\n removeListener?(event: string, handler: (...args: unknown[]) => void): void;\n}\n\ndeclare global {\n interface Window {\n ethereum?: Eip1193Provider;\n }\n}\n\nexport function getInjectedProvider(): Eip1193Provider | undefined {\n return typeof window === \"undefined\" ? undefined : window.ethereum;\n}\n\nexport function hasInjectedWallet(): boolean {\n return getInjectedProvider() !== undefined;\n}\n\nexport interface ConnectedWallet {\n address: Address;\n walletClient: WalletClient;\n chainId: number;\n}\n\n/** Prompt the wallet to connect, and switch chain if it is on the wrong one. */\nexport async function connectWallet(chain: Chain): Promise<ConnectedWallet> {\n const provider = getInjectedProvider();\n if (!provider) {\n throw new Error(\"No browser wallet found. Install MetaMask or another EIP-1193 wallet.\");\n }\n\n const accounts = (await provider.request({ method: \"eth_requestAccounts\" })) as Address[];\n const address = accounts[0];\n if (!address) throw new Error(\"Wallet returned no accounts.\");\n\n const currentChainId = Number(\n (await provider.request({ method: \"eth_chainId\" })) as string,\n );\n\n if (currentChainId !== chain.id) {\n await switchChain(provider, chain);\n }\n\n const walletClient = createWalletClient({ account: address, chain, transport: custom(provider) });\n return { address, walletClient, chainId: chain.id };\n}\n\nasync function switchChain(provider: Eip1193Provider, chain: Chain): Promise<void> {\n const chainIdHex = `0x${chain.id.toString(16)}`;\n try {\n await provider.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: chainIdHex }],\n });\n } catch (error) {\n // 4902: the wallet does not know this chain yet, so offer to add it.\n const code = (error as { code?: number }).code;\n if (code !== 4902) throw error;\n\n await provider.request({\n method: \"wallet_addEthereumChain\",\n params: [\n {\n chainId: chainIdHex,\n chainName: chain.name,\n nativeCurrency: chain.nativeCurrency,\n rpcUrls: [chain.rpcUrls.default.http[0]],\n blockExplorerUrls: chain.blockExplorers?.default?.url\n ? [chain.blockExplorers.default.url]\n : undefined,\n },\n ],\n });\n }\n}\n","import type { CSSProperties } from \"react\";\n\n/**\n * Inline styles rather than a stylesheet.\n *\n * The widget is dropped into other people's pages. Shipping a CSS file would\n * require the host to import it, and global class names would collide with\n * theirs. Inline styles are self-contained and cannot leak either way.\n */\nconst border = \"#2a2a2e\";\nconst surface = \"#141417\";\nconst text = \"#f4f4f5\";\nconst muted = \"#8b8b93\";\n\nexport const styles = {\n card: {\n boxSizing: \"border-box\",\n width: \"100%\",\n maxWidth: 360,\n padding: 16,\n borderRadius: 12,\n border: `1px solid ${border}`,\n background: surface,\n color: text,\n fontFamily:\n \"ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\",\n fontSize: 14,\n lineHeight: 1.45,\n },\n headerRow: {\n display: \"flex\",\n alignItems: \"flex-start\",\n justifyContent: \"space-between\",\n gap: 8,\n },\n symbol: { fontSize: 18, fontWeight: 600 },\n pillRow: { display: \"flex\", flexWrap: \"wrap\", gap: 4, justifyContent: \"flex-end\" },\n pill: {\n display: \"inline-block\",\n padding: \"2px 8px\",\n borderRadius: 999,\n fontSize: 11,\n fontWeight: 500,\n whiteSpace: \"nowrap\",\n },\n pillLive: { background: \"rgba(16,185,129,0.15)\", color: \"#6ee7b7\" },\n pillPending: { background: \"rgba(14,165,233,0.15)\", color: \"#7dd3fc\" },\n pillEnded: { background: \"rgba(113,113,122,0.18)\", color: \"#c4c4cc\" },\n pillGraduated: { background: \"rgba(139,92,246,0.18)\", color: \"#c4b5fd\" },\n\n priceBlock: { marginTop: 14 },\n price: { fontSize: 22, fontWeight: 600, fontVariantNumeric: \"tabular-nums\", wordBreak: \"break-all\" },\n priceUnit: { fontSize: 12, fontWeight: 400, color: muted },\n\n grid: { margin: \"14px 0 0\", display: \"grid\", gap: 8 },\n row: { display: \"flex\", alignItems: \"baseline\", justifyContent: \"space-between\", gap: 12, margin: 0 },\n label: { fontSize: 11, textTransform: \"uppercase\", letterSpacing: \"0.04em\", color: muted, margin: 0 },\n value: { margin: 0, fontSize: 13, textAlign: \"right\", fontVariantNumeric: \"tabular-nums\" },\n\n form: { marginTop: 16, display: \"grid\", gap: 6, borderTop: `1px solid ${border}`, paddingTop: 14 },\n input: {\n boxSizing: \"border-box\",\n width: \"100%\",\n padding: \"8px 10px\",\n borderRadius: 8,\n border: `1px solid ${border}`,\n background: \"#0d0d0f\",\n color: text,\n fontSize: 14,\n outline: \"none\",\n },\n button: {\n marginTop: 6,\n padding: \"10px 12px\",\n borderRadius: 8,\n border: \"none\",\n background: text,\n color: \"#0d0d0f\",\n fontSize: 14,\n fontWeight: 600,\n cursor: \"pointer\",\n },\n buttonDisabled: {\n background: \"#2a2a2e\",\n color: muted,\n cursor: \"not-allowed\",\n },\n notice: {\n padding: \"8px 10px\",\n borderRadius: 8,\n background: \"rgba(113,113,122,0.12)\",\n color: muted,\n fontSize: 12,\n },\n muted: { color: muted, fontSize: 12 },\n error: { color: \"#fca5a5\", fontSize: 12, wordBreak: \"break-word\" },\n success: { color: \"#6ee7b7\", fontSize: 12, wordBreak: \"break-word\" },\n link: { color: \"#7dd3fc\" },\n footer: {\n marginTop: 14,\n paddingTop: 10,\n borderTop: `1px solid ${border}`,\n color: muted,\n fontSize: 11,\n textAlign: \"center\",\n },\n} satisfies Record<string, CSSProperties>;\n","/**\n * Vanilla-JS entry point so non-React sites can embed the widget:\n *\n * <div id=\"beacon\"></div>\n * <script src=\"https://your-cdn/mount.global.js\"></script>\n * <script>\n * BeaconCCA.mount('#beacon', {\n * auction: '0x...', chainId: 11155111, rpcUrl: 'https://...'\n * });\n * </script>\n *\n * React and the SDK are bundled into this build, so the host page needs nothing.\n */\nimport { createElement } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport type { Root } from \"react-dom/client\";\nimport { AuctionCard } from \"./AuctionCard\";\nimport type { AuctionCardProps } from \"./AuctionCard\";\n\nconst roots = new WeakMap<Element, Root>();\n\nexport interface MountHandle {\n update(next: Partial<AuctionCardProps>): void;\n unmount(): void;\n}\n\nexport function mount(target: string | Element, props: AuctionCardProps): MountHandle {\n const element = typeof target === \"string\" ? document.querySelector(target) : target;\n if (!element) {\n throw new Error(`Beacon widget: no element matched ${String(target)}`);\n }\n\n // Re-mounting into the same node reuses its root, so calling mount() twice\n // updates in place instead of leaking a second React tree.\n let root = roots.get(element);\n if (!root) {\n root = createRoot(element);\n roots.set(element, root);\n }\n\n let current = props;\n root.render(createElement(AuctionCard, current));\n\n return {\n update(next) {\n current = { ...current, ...next };\n root!.render(createElement(AuctionCard, current));\n },\n unmount() {\n root!.unmount();\n roots.delete(element);\n },\n };\n}\n\nexport { AuctionCard };\nexport type { AuctionCardProps };\n"],"mappings":"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","names":["import_react","import_cca_sdk","import_react"]}
@@ -0,0 +1,84 @@
1
+ import * as react from 'react';
2
+ import { Address, AuctionInfo, AuctionState, TokenMetadata, AuctionStatus, BeaconClient } from '@hammerock/cca-sdk';
3
+ import { Address as Address$1, WalletClient, Chain } from 'viem';
4
+
5
+ interface AuctionCardProps {
6
+ /** Address of the ContinuousClearingAuction to display. */
7
+ auction: Address;
8
+ /** Public RPC the widget reads through. Never put a keyed URL here - the
9
+ * widget runs in the visitor's browser. */
10
+ rpcUrl: string;
11
+ /** Chain id the auction lives on. Must be a supported testnet. */
12
+ chainId: number;
13
+ /** Optional deployed AuctionStateLens. Omit to use the eth_call override. */
14
+ lensAddress?: Address;
15
+ /** How often to re-read live state, in ms. */
16
+ pollIntervalMs?: number;
17
+ /** Hide the bid form and render read-only. */
18
+ readOnly?: boolean;
19
+ }
20
+ declare function AuctionCard(props: AuctionCardProps): react.JSX.Element | null;
21
+
22
+ /**
23
+ * Everything the card renders, read through @hammerock/cca-sdk.
24
+ *
25
+ * The widget runs on somebody else's website, so it reads through whatever
26
+ * public RPC the embedder passes in. It never needs a lens deployment: the SDK
27
+ * runs `AuctionStateLens` through an `eth_call` state override.
28
+ */
29
+ interface AuctionData {
30
+ info: AuctionInfo;
31
+ state: AuctionState;
32
+ token: TokenMetadata;
33
+ currency: TokenMetadata;
34
+ status: AuctionStatus;
35
+ headBlock: bigint;
36
+ blocksRemaining: bigint;
37
+ secondsRemaining: number;
38
+ }
39
+ interface UseAuctionResult {
40
+ data: AuctionData | null;
41
+ error: Error | null;
42
+ loading: boolean;
43
+ client: BeaconClient | null;
44
+ refresh: () => void;
45
+ }
46
+ declare function useAuction(options: {
47
+ auction: Address;
48
+ rpcUrl: string;
49
+ chainId: number;
50
+ lensAddress?: Address;
51
+ pollIntervalMs?: number;
52
+ }): UseAuctionResult;
53
+
54
+ /** The subset of EIP-1193 the widget needs. */
55
+ interface Eip1193Provider {
56
+ request(args: {
57
+ method: string;
58
+ params?: unknown[];
59
+ }): Promise<unknown>;
60
+ on?(event: string, handler: (...args: unknown[]) => void): void;
61
+ removeListener?(event: string, handler: (...args: unknown[]) => void): void;
62
+ }
63
+ declare global {
64
+ interface Window {
65
+ ethereum?: Eip1193Provider;
66
+ }
67
+ }
68
+ declare function getInjectedProvider(): Eip1193Provider | undefined;
69
+ declare function hasInjectedWallet(): boolean;
70
+ interface ConnectedWallet {
71
+ address: Address$1;
72
+ walletClient: WalletClient;
73
+ chainId: number;
74
+ }
75
+ /** Prompt the wallet to connect, and switch chain if it is on the wrong one. */
76
+ declare function connectWallet(chain: Chain): Promise<ConnectedWallet>;
77
+
78
+ interface MountHandle {
79
+ update(next: Partial<AuctionCardProps>): void;
80
+ unmount(): void;
81
+ }
82
+ declare function mount(target: string | Element, props: AuctionCardProps): MountHandle;
83
+
84
+ export { AuctionCard, type AuctionCardProps, type AuctionData, type ConnectedWallet, type Eip1193Provider, type MountHandle, type UseAuctionResult, connectWallet, getInjectedProvider, hasInjectedWallet, mount, useAuction };
@@ -0,0 +1,84 @@
1
+ import * as react from 'react';
2
+ import { Address, AuctionInfo, AuctionState, TokenMetadata, AuctionStatus, BeaconClient } from '@hammerock/cca-sdk';
3
+ import { Address as Address$1, WalletClient, Chain } from 'viem';
4
+
5
+ interface AuctionCardProps {
6
+ /** Address of the ContinuousClearingAuction to display. */
7
+ auction: Address;
8
+ /** Public RPC the widget reads through. Never put a keyed URL here - the
9
+ * widget runs in the visitor's browser. */
10
+ rpcUrl: string;
11
+ /** Chain id the auction lives on. Must be a supported testnet. */
12
+ chainId: number;
13
+ /** Optional deployed AuctionStateLens. Omit to use the eth_call override. */
14
+ lensAddress?: Address;
15
+ /** How often to re-read live state, in ms. */
16
+ pollIntervalMs?: number;
17
+ /** Hide the bid form and render read-only. */
18
+ readOnly?: boolean;
19
+ }
20
+ declare function AuctionCard(props: AuctionCardProps): react.JSX.Element | null;
21
+
22
+ /**
23
+ * Everything the card renders, read through @hammerock/cca-sdk.
24
+ *
25
+ * The widget runs on somebody else's website, so it reads through whatever
26
+ * public RPC the embedder passes in. It never needs a lens deployment: the SDK
27
+ * runs `AuctionStateLens` through an `eth_call` state override.
28
+ */
29
+ interface AuctionData {
30
+ info: AuctionInfo;
31
+ state: AuctionState;
32
+ token: TokenMetadata;
33
+ currency: TokenMetadata;
34
+ status: AuctionStatus;
35
+ headBlock: bigint;
36
+ blocksRemaining: bigint;
37
+ secondsRemaining: number;
38
+ }
39
+ interface UseAuctionResult {
40
+ data: AuctionData | null;
41
+ error: Error | null;
42
+ loading: boolean;
43
+ client: BeaconClient | null;
44
+ refresh: () => void;
45
+ }
46
+ declare function useAuction(options: {
47
+ auction: Address;
48
+ rpcUrl: string;
49
+ chainId: number;
50
+ lensAddress?: Address;
51
+ pollIntervalMs?: number;
52
+ }): UseAuctionResult;
53
+
54
+ /** The subset of EIP-1193 the widget needs. */
55
+ interface Eip1193Provider {
56
+ request(args: {
57
+ method: string;
58
+ params?: unknown[];
59
+ }): Promise<unknown>;
60
+ on?(event: string, handler: (...args: unknown[]) => void): void;
61
+ removeListener?(event: string, handler: (...args: unknown[]) => void): void;
62
+ }
63
+ declare global {
64
+ interface Window {
65
+ ethereum?: Eip1193Provider;
66
+ }
67
+ }
68
+ declare function getInjectedProvider(): Eip1193Provider | undefined;
69
+ declare function hasInjectedWallet(): boolean;
70
+ interface ConnectedWallet {
71
+ address: Address$1;
72
+ walletClient: WalletClient;
73
+ chainId: number;
74
+ }
75
+ /** Prompt the wallet to connect, and switch chain if it is on the wrong one. */
76
+ declare function connectWallet(chain: Chain): Promise<ConnectedWallet>;
77
+
78
+ interface MountHandle {
79
+ update(next: Partial<AuctionCardProps>): void;
80
+ unmount(): void;
81
+ }
82
+ declare function mount(target: string | Element, props: AuctionCardProps): MountHandle;
83
+
84
+ export { AuctionCard, type AuctionCardProps, type AuctionData, type ConnectedWallet, type Eip1193Provider, type MountHandle, type UseAuctionResult, connectWallet, getInjectedProvider, hasInjectedWallet, mount, useAuction };