Production polish: i18n shelved, PWA icons, SEO/GEO cleanup, UX fixes
Big-picture changes since 01be8e7:
New routes — /trump /btc /kol /trades /analytics /archive plus four
SEO landing pages (/methodology /glossary /case-studies /contact),
all served under /[locale]. Each has dedicated metadata + JSON-LD.
KOL page (new) — DigestWidget + OnchainWidget + TalkVsTradesWidget,
filter by handle/ticker, click-through to per-post detail with the
original AI-extracted ticker/conviction/quote.
BTC page (new) — tabbed: macro-bottom (AHR999 + 200WMA + Pi Cycle)
and funding-rate reversal, with live sparkline + threshold bands.
Telegram card on Settings — wallet-link code generation, status,
disconnect. Preferences moved into the bot itself (/trump /btc etc.)
so the card stays minimal.
SignalMonitor (new) — ETH/LINK Bollinger breakout monitor in its own
component, shares the singleton WsProvider so no second WS opens.
WS singleton refactor (lib/wsContext) — shared WsProvider + useWsSubscribe
hook. Cleanup now actively closes the socket on unmount; previously the
local `ws` couldn't be reached from cleanup and leaked one connection
per StrictMode remount.
OpenPositions polling no longer pops MetaMask in the background —
splits into load('first') for user-initiated and load('poll') that
uses getCachedViewEnvelope without signing.
i18n shelved — proxy.ts (Next 16 middleware rename) wires next-intl
but only Navbar + layout footer have translations. Rest of UI used
isZh ternary scattered across 28 files. All `const isZh = locale === 'zh'`
flipped to `const isZh = false` so every site renders English; Chinese
branches kept as dead code so revival is one regex away.
LanguageSwitch hidden but file kept. zh-CN hreflang removed from
metadata + sitemap to avoid duplicate-content penalties.
Wallet error handling — lib/walletError.ts: isUserRejection walks EIP-1193
code 4001 + .cause chain; previous string-match for "reject"/"denied"
broke for users running MetaMask in non-English UIs. 12 call sites
migrated across 5 components.
PWA icons — app/icon.tsx + app/apple-icon.tsx render the brand "α" via
Next's ImageResponse so no static PNG asset is required. manifest.ts
references /icon and /apple-icon dynamic routes.
OG image + sitemap + robots — dynamic 1200×630 OG card; robots blocks
both /en/settings and /zh/settings; sitemap only emits /en routes;
JSON-LD covers SoftwareApplication + Organization + 10-Q FAQPage.
Landing page polish — Launch Dashboard button stripped of magnetic
hover + shimmer + lift + glow expansion (multiple users found it busy);
hero scramble alphabet swapped to alphanumeric (was block characters);
"15 KOL feeds" copy updated to 19 in 5 places.
PostCards source icons — new entries for btc_bottom_reversal,
funding_reversal, kol_divergence so they no longer fall through to
the generic "first letter" fallback.
Archive page filter — excludes funding_reversal + kol_divergence
(previously only excluded truth + btc_bottom_reversal so new live
signals leaked into the legacy archive).
Cache + skeleton loading — lib/cache.ts SWR module with per-key TTL,
applied across the major pages so navigation feels instant.
SignConfirmSheet — 4 hardcoded Chinese strings translated to English
(English users were seeing zh-only "需要钱包签名" etc).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,55 +1,87 @@
|
||||
import Link from 'next/link'
|
||||
import { getLocale } from 'next-intl/server'
|
||||
|
||||
export default async function PrivacyPage({ params: { locale } }: { params: { locale: string } }) {
|
||||
const intlLocale = await getLocale()
|
||||
const isZh = false // i18n shelved — Chinese branches kept as dead code for future revival; see messages/zh.json
|
||||
|
||||
const sections = isZh
|
||||
? [
|
||||
{
|
||||
title: '1. 我们收集什么',
|
||||
body: '当你连接钱包时,我们会收集你的钱包地址,用于身份识别、订阅状态判断和机器人配置关联。除非你主动通过联系表单提供,我们不会收集姓名、邮箱等传统个人身份信息。',
|
||||
},
|
||||
{
|
||||
title: '2. Hyperliquid API Key',
|
||||
body: '如果你选择绑定 Hyperliquid API key,该密钥会以加密形式存储。明文不会被写入日志,也不会用于除 Hyperliquid 官方交易接口以外的用途。',
|
||||
},
|
||||
{
|
||||
title: '3. 数据如何使用',
|
||||
body: '钱包地址、订阅状态和交易配置只会用于执行你授权的机器人逻辑、展示个人交易表现,以及提供平台功能。我们不会出售、出租或用于广告投放。',
|
||||
},
|
||||
{
|
||||
title: '4. 分析与统计',
|
||||
body: '我们使用极简统计来理解页面访问、错误率和整体使用趋势。这些统计不会绑定你的真实身份,也不会用于跨站广告追踪。',
|
||||
},
|
||||
{
|
||||
title: '5. 数据保留',
|
||||
body: '只要你的账户仍在使用,相关订阅与配置数据会被保留。你可以联系我们请求删除。交易历史最多保留 24 个月,用于对账、争议处理和产品分析。',
|
||||
},
|
||||
{
|
||||
title: '6. 联系方式',
|
||||
body: '如果你有与隐私相关的问题,请使用联系页面与我们沟通。',
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
title: '1. Information We Collect',
|
||||
body: 'When you connect a wallet, we collect the wallet address required to identify your account, check subscription status, and link bot settings. We do not collect names, email addresses, or similar personal identifiers unless you voluntarily provide them through the contact form.',
|
||||
},
|
||||
{
|
||||
title: '2. Hyperliquid API Keys',
|
||||
body: 'If you connect a Hyperliquid API key, the key is stored in encrypted form. Plaintext keys are not written to logs and are only used for calls to official Hyperliquid trading endpoints.',
|
||||
},
|
||||
{
|
||||
title: '3. How We Use Data',
|
||||
body: 'Wallet addresses, subscription status, and trading settings are used only to run the bot logic you authorize, show your personal trading analytics, and operate product features. We do not sell, rent, or repurpose this data for advertising.',
|
||||
},
|
||||
{
|
||||
title: '4. Analytics',
|
||||
body: 'We use minimal analytics to understand page usage, error rates, and aggregate product patterns. These analytics are not tied to your real-world identity and are not used for cross-site advertising.',
|
||||
},
|
||||
{
|
||||
title: '5. Data Retention',
|
||||
body: 'Subscription and configuration data is retained while your account remains active. You may request deletion by contacting us. Trade-history records are retained for up to 24 months for reconciliation, dispute handling, and product analysis.',
|
||||
},
|
||||
{
|
||||
title: '6. Contact',
|
||||
body: 'If you have a privacy-related question, please use the contact page.',
|
||||
},
|
||||
]
|
||||
|
||||
export default function PrivacyPage({ params: { locale } }: { params: { locale: string } }) {
|
||||
return (
|
||||
<div className="page" style={{ maxWidth: 720 }}>
|
||||
<div className="page-head">
|
||||
<div>
|
||||
<h1 className="page-title">Privacy Policy</h1>
|
||||
<p className="page-sub">Last updated: April 2026</p>
|
||||
<h1 className="page-title">{isZh ? '隐私政策' : 'Privacy Policy'}</h1>
|
||||
<p className="page-sub">{isZh ? '最后更新:2026 年 4 月' : 'Last updated: April 2026'}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="card" style={{ padding: 32, lineHeight: 1.7, fontSize: 14, color: 'var(--ink-2)' }}>
|
||||
<h2 style={{ fontSize: 16, fontWeight: 600, color: 'var(--ink)', marginBottom: 8 }}>1. Information We Collect</h2>
|
||||
<p style={{ marginBottom: 20 }}>
|
||||
We collect your Ethereum wallet address when you connect your wallet. This address is used solely to
|
||||
authenticate your session and manage your subscription. We do not collect your name, email address, or
|
||||
any other personally identifiable information unless you voluntarily provide it via the contact form.
|
||||
</p>
|
||||
|
||||
<h2 style={{ fontSize: 16, fontWeight: 600, color: 'var(--ink)', marginBottom: 8 }}>2. Hyperliquid API Keys</h2>
|
||||
<p style={{ marginBottom: 20 }}>
|
||||
If you choose to connect a Hyperliquid API key, it is encrypted at rest using industry-standard symmetric
|
||||
encryption (Fernet/AES-128-CBC). The plaintext key is never logged, cached, or transmitted except to
|
||||
Hyperliquid's official API endpoints to execute trades on your behalf.
|
||||
</p>
|
||||
|
||||
<h2 style={{ fontSize: 16, fontWeight: 600, color: 'var(--ink)', marginBottom: 8 }}>3. How We Use Your Data</h2>
|
||||
<p style={{ marginBottom: 20 }}>
|
||||
Your wallet address and trading configuration are used exclusively to operate the automated trading bot
|
||||
on your behalf. We do not sell, rent, or share your data with third parties, except as required to
|
||||
process trades (Hyperliquid API) or comply with applicable law.
|
||||
</p>
|
||||
|
||||
<h2 style={{ fontSize: 16, fontWeight: 600, color: 'var(--ink)', marginBottom: 8 }}>4. Cookies & Analytics</h2>
|
||||
<p style={{ marginBottom: 20 }}>
|
||||
We use minimal analytics to understand aggregate usage patterns (page views, error rates). No
|
||||
personal identifiers are associated with analytics events. We do not use advertising cookies or
|
||||
cross-site tracking.
|
||||
</p>
|
||||
|
||||
<h2 style={{ fontSize: 16, fontWeight: 600, color: 'var(--ink)', marginBottom: 8 }}>5. Data Retention</h2>
|
||||
<p style={{ marginBottom: 20 }}>
|
||||
Subscription data is retained for as long as your account is active. You may request deletion of your
|
||||
data at any time by contacting us. Trade history is retained for up to 24 months for dispute resolution
|
||||
purposes.
|
||||
</p>
|
||||
|
||||
<h2 style={{ fontSize: 16, fontWeight: 600, color: 'var(--ink)', marginBottom: 8 }}>6. Contact</h2>
|
||||
<p>
|
||||
For privacy-related inquiries, please use our <Link href={`/${locale}/contact`} style={{ color: 'var(--amber)' }}>contact form</Link>.
|
||||
</p>
|
||||
{sections.map((section, index) => (
|
||||
<div key={section.title} style={{ marginBottom: index === sections.length - 1 ? 0 : 20 }}>
|
||||
<h2 style={{ fontSize: 16, fontWeight: 600, color: 'var(--ink)', marginBottom: 8 }}>{section.title}</h2>
|
||||
<p style={{ marginBottom: 0 }}>
|
||||
{section.title.endsWith('Contact') || section.title.endsWith('联系方式')
|
||||
? <>
|
||||
{section.body}{' '}
|
||||
<Link href={`/${locale}/contact`} style={{ color: 'var(--amber)' }}>{isZh ? '联系页面' : 'contact page'}</Link>.
|
||||
</>
|
||||
: section.body}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user