'use client' /** * SignConfirmSheet — elegant pre-signing confirmation UI. * * Usage (imperative, no context needed): * * import { confirmSign } from '@/components/wallet/SignConfirmSheet' * * const ok = await confirmSign({ * label: 'Enable Auto-Trade', * description: 'Bot will open live trades on Hyperliquid when signals fire.', * danger: true, * }) * if (!ok) return // user cancelled * const env = await signRequest(...) // only NOW triggers MetaMask */ import { createRoot } from 'react-dom/client' export interface SignConfirmOptions { /** Short action title, e.g. "Enable Auto-Trade" */ label: string /** One-sentence explanation shown to the user */ description: string /** If true, renders a red/warning accent — for irreversible / live-money actions */ danger?: boolean } /** Renders a confirmation sheet and resolves true (confirm) or false (cancel). */ export function confirmSign(opts: SignConfirmOptions): Promise { return new Promise((resolve) => { const container = document.createElement('div') document.body.appendChild(container) const root = createRoot(container) function cleanup(result: boolean) { root.unmount() container.remove() resolve(result) } root.render( cleanup(true)} onCancel={() => cleanup(false)} />) }) } /* ─── Internal sheet component ─────────────────────────────────────────────── */ function Sheet({ label, description, danger, onConfirm, onCancel, }: SignConfirmOptions & { onConfirm: () => void; onCancel: () => void }) { const accent = danger ? '#ef4444' : '#f5a524' const accentSoft = danger ? 'rgba(239,68,68,0.1)' : 'rgba(245,165,36,0.1)' // Dismiss on backdrop click function handleBackdrop(e: React.MouseEvent) { if (e.target === e.currentTarget) onCancel() } // Dismiss on Escape function handleKey(e: React.KeyboardEvent) { if (e.key === 'Escape') onCancel() } return (
{/* 拖拽条 */}
{/* 图标 + 标题 */}
🔏
Wallet signature required
{label}
{/* 说明文字 */}
{description}
{/* 说明条 */}
Signing is used only to verify your identity. It will NOT authorize any on-chain transfer and will NOT cost any gas. The MetaMask popup will appear after you click Confirm.
{/* 按钮组 */}
) }