import { useEffect, useMemo, useRef, useState } from 'react' import { Copy, Eye, EyeOff, RefreshCw, Shield, Wallet, Sparkles } from 'lucide-react' import { QRCodeSVG } from 'qrcode.react' import { toast } from 'sonner' import { DeepVoidBackground } from '../components/common/DeepVoidBackground' import { useLanguage } from '../contexts/LanguageContext' import { api } from '../lib/api' import type { BeginnerOnboardingResponse } from '../types' import { setBeginnerWalletAddress } from '../lib/onboarding' export function BeginnerOnboardingPage() { const { language } = useLanguage() const [data, setData] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState('') const [showPrivateKey, setShowPrivateKey] = useState(false) const [refreshingBalance, setRefreshingBalance] = useState(false) const hasRequestedRef = useRef(false) const isZh = language === 'zh' const loadOnboarding = async (showLoading: boolean) => { if (showLoading) { setLoading(true) } else { setRefreshingBalance(true) } setError('') try { const result = await api.prepareBeginnerOnboarding() setData(result) setBeginnerWalletAddress(result.address) } catch (err) { setError( err instanceof Error ? err.message : isZh ? '新手钱包准备失败' : 'Failed to prepare beginner wallet' ) } finally { if (showLoading) { setLoading(false) } else { setRefreshingBalance(false) } } } useEffect(() => { if (hasRequestedRef.current) { return } hasRequestedRef.current = true void loadOnboarding(true) }, []) const hints = useMemo( () => isZh ? [ '这是你的专属 Base 钱包,只用于后续调用大模型。', '请保存私钥。丢失后无法恢复。', '只往这个地址充值 Base 链 USDC,不要充到别的链。', ] : [ 'This dedicated Base wallet is only used to pay for model calls.', 'Save the private key now. It cannot be recovered later.', 'Deposit USDC on Base only. Do not send funds from another chain.', ], [isZh] ) const copyText = async (value: string, label: string) => { try { await navigator.clipboard.writeText(value) toast.success(isZh ? `${label}已复制` : `${label} copied`) } catch { toast.error(isZh ? '复制失败' : 'Copy failed') } } const handleContinue = () => { window.history.pushState({}, '', '/traders') window.dispatchEvent(new PopStateEvent('popstate')) } return (
{isZh ? '新手保护' : 'Beginner Guard'}

{isZh ? '钱包已经帮你准备好了' : 'Your wallet is ready'}

{isZh ? '我们已经为你生成了一个专属钱包,并默认接入 Claw402 + DeepSeek。你现在只需要保存私钥,然后往这个地址充值 Base 链 USDC,后面调用大模型时会自动从这里扣费。' : 'We generated a dedicated wallet for you and preconfigured Claw402 + DeepSeek. Save the private key, then deposit Base USDC to this address so future model calls can be paid automatically.'}

{hints.map((hint) => (
{hint}
))}
{isZh ? '为什么要充值?' : 'Why fund this wallet?'}

{isZh ? '这里只负责大模型调用费用,不会自动替你充值交易所。先充少量 USDC 就够了,通常 $5-$10 可以用很久。' : 'This wallet only covers LLM usage costs. It does not fund your exchange automatically. A small amount of USDC is enough to get started, usually $5-$10.'}

{error ? (
{error}
) : null}
{loading ? (
{isZh ? '正在准备你的 Base 钱包...' : 'Preparing your Base wallet...'}
) : data ? (
{isZh ? '默认模型' : 'Default Model'}
Claw402 + DeepSeek
{isZh ? '按次付费,无需 API Key' : 'Pay per call, no API key needed'}
{isZh ? '充值地址(Base 链 USDC)' : 'Deposit Address (Base USDC)'}
{data.address}
{isZh ? '当前余额' : 'Current Balance'}
{data.balance_usdc} USDC
{isZh ? 'Base 链钱包余额' : 'Base wallet balance'}
{isZh ? '钱包私钥' : 'Wallet Private Key'}
{isZh ? '请先备份,再进入下一步。' : 'Back this up before you continue.'}
{showPrivateKey ? data.private_key : '0x' + '•'.repeat(64)}
{data.env_saved ? isZh ? `已同步保存到环境文件:${data.env_path || '.env'}` : `Also saved to env: ${data.env_path || '.env'}` : isZh ? '当前运行环境没有成功写回 .env,但产品已完成默认配置。' : 'The app is configured, but this runtime could not write back to .env.'}
{data.env_warning ?
{data.env_warning}
: null}
) : null}
) }