# 幣股整體優化 · 交接規格 · 美編 · style 01 曜黑琉璃 範圍:使用者端 DApp(swap-app)的 `/coin-stock/`,不含後台。Logo(`icons/`)和返回鍵(`back-button-spec.md`)照已做好的規格。 可點原型:https://eason-stock-icons.pages.dev/proto/ (手機 390、電腦 ≥900 自動切換;每個狀態可用 `?s=` 直接開,清單見 §6)。原型裡所有數字都是**示範資料**。 ## 1. 盤點結果(原始碼只讀) | 項目 | 原始碼 | 現況 | |---|---|---| | 頁面 | `app-pages/CoinStockPage.tsx`(222 行) | 三個 view:`main`(理財)、`stocks`(`?v=stocks`)、`stock`(`?s=地址`) | | 理財資料 | `lib/coinStock/useVault.ts`、`vaultAbi.ts`、`demo.ts` | CoinStockVault:`stats`、`tiers`、`positionsOf`、`getPositions`、`queuedOf`、`maturities`;動作 `deposit(tierId, amount)`(自動帶 USDT 授權)、`withdraw(id, amount)`(目前固定傳 0)、`claim(ids[])`。沒有部署合約時進「示範模式」 | | 股票資料 | `lib/coinStock/stocks.ts`、`public/coin-stock/stocks-56.json` | 1,931 檔(Ondo 457、xStocks 1,474),欄位 `i s u n a d c h`;`c` 是國家碼(GB、HK…),**沒有股票/ETF 類型、沒有中文名**。價格、池子、K 線來自 GeckoTerminal(每次 30 檔、每分鐘約 30 次) | | 股票元件 | `components/coinstock/Stocks.tsx`、`KLine.tsx`、`lib/coinStock/kyber.ts` | 列表(搜尋+發行商 chip+顯示更多)、詳情(價格、1D/7D/30D K 線、4 格資料)、兌換 sheet(KyberSwap 報價,`STOCK_SWAP_ON` 環境變數開關,目前關,只有主網) | | 排隊 | 合約 `queue`、`queueHead`、`queueLength`、`queuedOf`、事件 `RedemptionQueued`/`RedemptionPaid`;`Withdrawn` 事件有 `paidNow`、`queued` | 前端只顯示一行「排隊中待支付 {v} USDT」 | | 紀錄 | 只有事件 `Deposited`、`Withdrawn`、`RewardClaimed`、`RedemptionPaid` | 前端沒有紀錄頁 | | 文字 | `i18n/locales/coinStock/*.json`(8 種語言) | 見 §5 文案對照 | ## 2. 問題清單 1. **打開看到的不是股票。**「幣股」首頁其實是 USDT 定存(收益發 EDOT),股票行情藏在第二層「股票」按鈕後面。幣安是一打開「市場」就是行情列表。 2. **最大的數字不是使用者的。** 首頁最大字是平台「總存入本金 1,284,500 USDT」,接著三個平台儲備指標;使用者自己的錢在第三屏。Apple 錢包/幣安理財都先放「我的」。 3. **一頁太長。** 首頁 2,440px、七個區塊(總覽、股票入口、檔次、持倉、儲備透明度、到期長條圖、多簽地址),主要動作在第三屏。 4. **列表看不到漲跌。** 圖示是灰色縮寫方塊;價格和漲跌擠在同一欄的小字;沒有排序、沒有美股/ETF 分類、沒有休市/開盤;列高不一。幣安:每列約 64px,右邊價格、最右邊彩色漲跌塊,表頭可排序。 5. **返回鍵在右邊**,而且共用 header 的 ‹ 被 CSS 藏起來,兩套返回(已另出 `back-button-spec.md`)。 6. **詳情頁主要動作在最底。** 只有一顆「兌換」,要捲過整張卡片;被底部導覽蓋住;不分買入/賣出。幣安、Robinhood:底部固定「買入/賣出」兩顆。 7. **存入沒有確認步驟。** 按「存入」直接跳兩次錢包簽名(授權+存入),沒先說會簽兩次;金額 0 時顯示「0.00 USDT ≈ 0.00 EDOT」;四條條款小字。 8. **持倉按鈕看不懂為什麼不能按。** 每筆兩顆一樣灰的大按鈕,沒寫幾號解鎖;本金和收益兩個同大方框,主次不分;沒有存入/提領紀錄。 9. **排隊說不清楚。** 提領前不知道這次多少馬上到帳、多少要排隊、前面還有多少。 10. **缺狀態。** 理財讀取失敗沒畫面(`useVault` 有 `readError` 但沒用);載入只是一張「讀取中…」;未開放、額度已滿只寫「未開放」;未部署按鈕寫「示範模式」。 11. **用後台語言。**「檔次」「剩餘額度」「流動性覆蓋率」「EDOT 換算價」「收款多簽錢包」→ 使用者要的是「方案」「解鎖日」「每天賺多少」。 12. **排版不一致。** 卡片套卡片;左右邊距 14/16/20 混用;數字沒用等寬字對齊;價格和漲跌沒靠右;區塊間距 12~28 不一;元件自己一套(`cs-back`、`cs-chips`、`cs-tiers`),跟兌換頁的 seg 不同。 ## 3. 新結構 ``` 幣股(更多 › 幣股) ├─ 行情(預設) 市場狀態 · 漲幅榜/跌幅榜 · 全部股票列表(排序) │ └─ 股票詳情 價格 · 走勢 1 天/7 天/30 天 · 24 小時資料 · 關於這檔代幣 │ └─ 買入/賣出面板 → 確認 → 錢包簽名(1 授權 · 2 確認)→ 成功 └─ 理財 我的理財摘要(本金 · 待領收益 · 排隊中) ├─ 存入 選方案(期限 · 月化區間 · 解鎖日)→ 金額 → 確認 → 簽名 → 成功 → 查看持倉 ├─ 我的持倉 每筆:倒數 · 解鎖日 · 領取收益 · 提領 → 提領面板(馬上到帳/排隊) └─ 紀錄 存入 · 提領 · 領取收益 · 排隊到帳 (儲備透明度 → 一個入口列,點進去才看平台數字) ``` `/coin-stock/` 預設開「行情」;`?tab=earn` 開理財;`?tab=earn&p=pos`、`&p=hist` 開持倉、紀錄;`?s=地址` 開詳情(不變)。 ## 4. 排版規則(全部畫面) | 項目 | 規則 | |---|---| | 格線 | 手機左右 20px;電腦內容欄最寬 1040px、左右 40px;詳情與理財在電腦版是兩欄(`1fr 360px`/`1fr 1fr`,間距 24) | | 間距 | 8 的倍數:4(標題與返回列)、8(同組元素)、12(篩選列內)、16(卡片內、卡片之間)、24(區塊之間)、40(空狀態上下) | | 字級 | 頁標 30/700;區塊標題 17/600;列表代號 16/600;內文 15;次要 13 #A1A1A6;註解 12 #6E6E73;大金額 40/700(電腦 56) | | 數字 | 全部 `font-variant-numeric: tabular-nums`;價格、漲跌、金額一律靠右 | | 列表列 | 高 64px;圖示 40;欄寬 手機 `1fr 104px 80px`,電腦 `1.6fr 1fr 1fr 1fr 96px`;分隔線 0.5px rgba(255,255,255,.08);不包卡片(像幣安一樣貼齊格線) | | 漲跌塊 | 寬 80、高 32、圓角 8、字 14/700;漲 #30D158 字 + rgba(48,209,88,.14) 底;跌 #FF453A + rgba(255,69,58,.14);持平灰 | | 卡片 | 圓角 24、內距 20、只一層,不再卡片套卡片 | | 主按鈕 | 高 52(面板內)/48(底部固定),圓角 999;橘色只給主要動作;買入綠、賣出紅 | | 底部固定列 | 詳情的買入/賣出、理財的存入:固定在底部導覽上方 12px,上緣漸層遮罩 | ## 5. 每個畫面與狀態 ### 5.1 行情(預設) - 返回列(返回 更多)→ 標題「幣股」+右側搜尋圓鈕(36px)。 - 分段「行情|理財」(高 44,選中白底黑字,跟 App 其他 seg 同款)。 - 篩選:全部/美股/ETF+「發行商 ▾」(Ondo、xStocks)。 - 市場狀態列(高 44):● 灰「美股休市 · 週一 21:30 開盤(台北時間)」;開盤時綠點+光暈「美股開盤中 · 04:00 收盤」。 - 漲幅榜/跌幅榜一列:橘色切換膠囊+4 個小膠囊(圖示 20、代號、漲跌),可橫向捲動;電腦顯示 6 個。 - 表頭:名稱 · 成交額/最新價/漲跌幅,點了切換排序(預設成交額由高到低),箭頭亮起的就是目前排序。 - 每列:圖示(真實 Logo 或備用徽章)、代號+發行商標籤、中文名;右邊價格+小字「額 $41.3萬」;最右漲跌塊。 - 載入:8 列骨架。失敗:「無法載入行情」+重新載入。搜尋沒結果:「找不到『ZZZZ』」+提示。單檔沒報價:價格「—」、漲跌塊灰「無報價」。流動性低:代號旁黃色小字「流動性低」。暫停交易:灰階+「暫停交易」。 ### 5.2 股票詳情 - 返回(回列表)→ 標題代號。 - 卡片:圖示 48+中文名+發行商標籤;副標「NVDAon · 美股」;大價格 40+漲跌塊;市場狀態一行。 - 區間「1 天/7 天/30 天」+右側「K 線」切換(預設折線,漲綠跌紅漸層;K 線沿用 KLine.tsx)。 - 4 格:24 小時最高、最低、成交額、DEX 流動性。 - 「關於這檔代幣」卡:發行商、對應股票、合約地址(↗)、追蹤憑證說明。 - 底部固定:買入(綠)/賣出(紅)。測試網或未開放:一顆灰鈕「切換到 BSC 主網後可交易」+藍色說明「測試網沒有代幣化股票…」。沒流動性:灰鈕「目前沒有可交易的流動性」。 ### 5.3 買入/賣出面板 - 分段 買入/賣出 → 支付(餘額、25%/50%/75%/最大)→ 預計收到(報價幾秒前更新)→ 成交均價(與市價差)、網路費、滑價 1% ▾ → 「下一步」。 - 確認:支付、收到、均價、與市價差、最少收到、網路費 → 兩步「1 授權 USDT · 2 確認買入」→ 按下後「請在錢包中確認…」(轉圈)→ 成功:✓「買入成功」+均價+BscScan 連結。 - 錯誤:餘額不足(輸入框紅框+「USDT 餘額不足」);沒路徑「目前沒有可用的兌換路徑」;偏差太大(沿用 DEV_BLOCK)「成交價與市價差太多,已停用」;使用者拒簽:關掉提示,回到確認。 ### 5.4 理財 - 摘要卡(已連接):我的理財本金(大字)、待領收益(橘)、排隊中待到帳。未連接:一列「連接錢包查看你的理財/不連接也能先看方案和利率」+連接鈕。 - 內分頁:存入|我的持倉 N|紀錄(小膠囊)。 - 選擇方案:4 列單選(活期/30/60/90 天),每列:期限、解鎖日(例「2027/01/23 解鎖」)、剩餘額度(有上限才顯示)、右邊月化區間大字綠(例「5–8%」「12%+」,下方小字「月化」)。下面 3 行:最低存入、月化利率:確認頁顯示實際月化,存入時鎖定、提領規則(「定期到期後可提領 · 活期隨時可提領」)。 - 其他:「儲備透明度 ›」(覆蓋率)、「存入與提領紀錄 ›」。 - 底部固定:「存入 USDT」。 - 狀態:未連接→鈕「連接錢包」;錯誤網路→頂部橘色列「錢包目前在 BSC 主網,幣股理財在 BSC 測試網[切換]」+鈕「切換到 BSC 測試網」;未部署→黃色說明「理財尚未上線…以下是示範資料」+灰鈕「尚未上線」;方案未開放→該列 45% 透明+「暫不開放」;額度已滿→「本期額度已滿」;讀取失敗→卡片「無法讀取理財資料」+重試。 ### 5.5 存入面板 - 方案膠囊(可直接換,顯示區間,例「90 天 · 月化 12%+」)→ 金額(錢包餘額、25%/50%/75%/最大)→ 解鎖日、每日收益約、到期預估收益(活期為「每 30 天預估收益」,USDT ≈ EDOT)→「下一步」。 - 金額未填:鈕「輸入金額」;低於最低:「最低存入 10 USDT」;超過額度:「超過剩餘額度」;餘額不足:紅框+說明「最多可存入 320.00 USDT」+灰鈕「USDT 餘額不足」。 - 確認:金額、方案(顯示實際月化並鎖定,例「90 天 · 月化 12%(鎖定)」)、解鎖日、每日收益約、到期預估收益(照實際月化精算;區間沒有上限的方案寫「至少 360.00 USDT」)、收益以 EDOT 發放 → 說明「定期到期後才可提領本金(活期隨時可提領)。存入的 USDT 會轉入專案多簽錢包保管。」→ 兩步「1 授權 USDT · 2 確認存入」(已授權足夠就只顯示一步)→ 簽名中 → 成功(✓、金額、解鎖日、每日收益、[完成][查看持倉])。 ### 5.6 我的持倉 - 頂部:排隊中(有的話,藍色說明,見 5.7)→「待領收益(3 筆)1,680.00 EDOT[全部領取]」。 - 每筆卡:期限+標籤(存入時鎖定的實際月化,例「月化 12%」/已到期 綠)+#編號;左「本金」大字、右「累計收益」橘;進度條+「存入 2026/09/15 · 剩 49 天 23:59 · 2026/12/14 解鎖」;按鈕 領取收益(次要)+提領本金(已到期是橘色主鈕)。未到期的定期:只顯示倒數+一行灰字「到期後可提領」,不放提前解鎖鈕、不顯示違約金說明(見 §12)。活期不變:隨時「提領」。 - 已提領完的持倉移到「紀錄」。空:「還沒有持倉/選一個方案存入 USDT」+去存入。未連接:連接錢包。 ### 5.7 提領面板與排隊 - 金額(可提領上限)→ 一張拆分卡:● 綠「馬上到帳 1,500.00 USDT」、● 橘「排隊後自動到帳 500.00 USDT」+白話說明:「合約裡目前可用的 USDT 不夠一次付完。剩下的 500 USDT 會依提領順序排隊,補足後自動轉進你的錢包,不用再操作。排在你前面的共 3,400 USDT。」→「確認提領」。 - 全部能馬上付時,拆分卡只顯示一行「馬上到帳」。 - 排隊中的持倉頁頂部藍色說明「500.00 USDT 排隊中,會自動到帳。…前面還有 2 筆,共 3,400 USDT。」;到帳後紀錄出現「排隊到帳」。 ### 5.8 紀錄 - 每列:圓形圖示(↓ 存入/↑ 提領、領取、排隊到帳)、類型+方案標籤、時間;右邊金額(入帳綠、出帳白)+「BscScan ↗」。底部註「只顯示這個錢包在幣股理財的紀錄」。空:「還沒有紀錄」。 ## 6. 原型狀態網址(`/proto/?s=`) `list` `list-loading` `list-error` `list-empty` · `detail` `detail-off` · `trade` `trade-sell` `trade-review` `trade-pending` `trade-done` · `earn` `earn-c` `earn-wrong` `earn-demo` · `deposit` `deposit-low` `deposit-review` `deposit-pending` `deposit-done` · `pos` `pos-empty` `pos-queue` `withdraw` · `hist` · `conn` · 資產頁 `pf` `pf-stock` `pf-earn` `pf-loading` `pf-empty` `pf-conn` ## 7. 元件(沿用 App 現有) | 元件 | 用 App 現有的 | 新增或調整 | |---|---|---| | 頂部列、跑馬燈、底部導覽、Sheet、Toast、連接錢包視窗 | 原樣 | — | | 返回列 | `BackButton`(back-button-spec.md) | — | | 分段 | 兌換頁 `.seg` | 行情|理財、買入|賣出 | | 篩選膠囊 | `.chips` | 取代 `cs-chips` | | 股票列 `StockRow` | — | 新,64px 三欄(§4) | | 漲跌塊 `ChangePill` | — | 新,80×32 | | 市場狀態 `MarketStatus` | — | 新 | | 漲跌榜 `MoversStrip` | — | 新 | | 方案列 `TierRow` | — | 取代 `cs-tier` 方格 | | 持倉卡 `PositionCard`、提領拆分卡 `PayoutSplit`、步驟條 `TxSteps`、成功頁 `TxDone` | — | 新 | | 圖示 | `StockIcon`(plate "baked") | — | ## 8. 文案對照(舊 → 新) 檔次→方案;選擇檔次→選擇方案;到期日→解鎖日;到期後可提領→進度條寫「{日期} 解鎖」、按鈕位置寫「到期後可提領」;剩餘額度 {v}→剩餘額度 {v}(只在有上限時);額度已滿→本期額度已滿;未開放→暫不開放;示範模式(按鈕)→尚未上線;存入(按鈕)→下一步/確認存入;提領本金(未到期)→灰字「到期後可提領」(不放按鈕);排隊中待支付…→「{v} USDT 排隊中,會自動到帳。」;股票(入口)→分頁「行情」;兌換(詳情)→買入/賣出;1D/7D/30D(詳情)→1 天/7 天/30 天;總存入本金(首頁大字)→移到「儲備透明度」。年化→月化(所有使用者畫面,數字照後台輸入的月化顯示,見 §11)。8 種語言照這個意思翻。 ## 9. 每個畫面需要的資料 | 畫面 | 資料 | 現在有嗎 | |---|---|---| | 行情列表 | 代號、中文名、發行商、類型(股票/ETF)、價格、24h 漲跌、24h 成交額、流動性 | 價格/漲跌/成交額有(GeckoTerminal,但一次 30 檔);**中文名、類型沒有** | | 排序、漲跌榜 | 全部 1,931 檔的漲跌與成交額 | **沒有**(要後端快取) | | 市場狀態 | 美股開收盤時間、假日 | **沒有** | | 詳情 | 價格、K 線、24h 高低(可由 K 線算)、流動性、發行商、合約 | 有 | | 買賣 | Kyber 報價、餘額、授權額度 | 有(主網、開關關著) | | 理財摘要 | 我的本金合計、待領收益、排隊金額 | 有(positions、liveEdot、queuedOf) | | 方案 | duration、實際月化 `aprBps`(每 30 天 bps)、前台顯示區間 min/max(見 §11)、enabled、cap、totalActive、minDeposit(early 開關:暫定關閉,見 §12) | 有 | | 提領拆分 | 這次馬上能付多少、排隊多少、前面還有多少 | **部分**(liquidity、queuedTotal 有;前面還有多少要掃 queue) | | 紀錄 | 存入、提領、領取、排隊到帳事件 | **沒有讀取**(只有事件) | ## 10. 要問技術的問題 1. 股票/ETF 分類:`stocks-56.json` 只有國家碼 `c`,能從 Ondo/xStocks 清單加一個 `type`(stock/etf)欄位嗎? 2. 中文名:要一張代號→中文名對照表(至少熱門 50 檔),放在清單建置腳本裡可以嗎?沒有的就顯示英文名。 3. 休市/開盤:用前端寫美股交易時段+假日表,還是後端提供?(夏令時間:台北 21:30–04:00,冬令 22:30–05:00) 4. 排序與漲跌榜要全部 1,931 檔的資料;GeckoTerminal 每次 30 檔、每分鐘約 30 次。可以做一個後端(例如 Worker+KV)每 1–2 分鐘抓一次全部報價嗎?不行的話就只排序熱門 100 檔。 5. 買賣:`STOCK_SWAP_ON` 什麼時候開?面板改成「下一步 → 確認」兩段、授權跟兌換分兩步顯示,邏輯上 OK 嗎? 6. 紀錄:合約沒有查詢紀錄的函式,只有事件。用 `getLogs`(範圍多大?)還是要 indexer/後端? 7. 排隊順位:「前面還有多少」需要掃 `queue(queueHead…)`。可以加一個 view(例如 `queueAheadOf(index)`)或後端算嗎? 8. 提領預覽:提領前怎麼精準算「馬上到帳」金額?是 `min(amount, liquidity − 已排隊)` 嗎?`retainBps` 會影響嗎? 9. `withdraw(id, amount)` 目前傳 0(全部)。支援部分提領嗎?活期和到期定期都可以嗎? 10. 理財讀取失敗時(`readError`),要不要自動重試幾次再顯示錯誤? 11. 錯誤網路:幣股理財上線後在哪條鏈(測試網 97 還是主網 56)?行情、買賣只在主網。 12. ~~利率單位~~ **已結案**:合約沿用 `aprBps` 這個名稱,意思改為「每 30 天的 bps」;`PERIOD = 30 days`;`MAX_RATE_BPS = 2000`(月化 20%)。見 §11。 ## 11. 利率:月化(實際月化+前台顯示區間) - **每個方案兩個設定(後台)**: 1. **實際月化(%)**:一個數字,算收益用,存進合約 `aprBps`(每 30 天的 bps,例 12% = 1200)。 2. **前台顯示區間**:最低 %(必填)+最高 %(可空)。最高空白時顯示「X%+」。 - **上限**:實際月化最高 20%,合約(`MAX_RATE_BPS = 2000`)和後台輸入框都要擋。合約每 30 天計息(`PERIOD = 30 days`)。 - 示範設定: | 方案 | 實際月化 | 前台顯示 | |---|---|---| | 活期 | 5% | 月化 5–8% | | 30 天 | 8% | 月化 8–10% | | 60 天 | 10% | 月化 10–12% | | 90 天 | 12% | 月化 12%+ | - **哪裡顯示什麼**: - 方案列表、存入面板的方案膠囊:顯示區間(「月化 5–8%」「月化 12%+」)。 - 存入確認頁、成功頁:顯示實際月化(「月化 12%(鎖定)」)和照它算的精確預估。 - 我的持倉、資產頁幣股存款列:顯示存入時鎖定的實際月化。 - **預估收益**(一個月 = 30 天):每日 = 金額 × 實際月化 ÷ 30;定期到期 = 每日 × 30/60/90;活期顯示「每 30 天預估收益」= 金額 × 實際月化。區間沒有上限的方案(90 天)預估寫「至少 X」。 - 存 1,000 USDT:活期 每日 1.67/每 30 天 50.00;30 天 每日 2.67/到期 80.00;60 天 每日 3.33/到期 200.00;90 天 每日 4.00/到期 至少 360.00(USDT;EDOT 以示範換算價 ×2:100.00/160.00/400.00/720.00)。 - **持倉示範**(今天 2026/10/25):90 天 5,000 USDT @12%(09/15 存入、12/14 解鎖、已 40 天)累計 800.00 USDT ≈ 1,600.00 EDOT;30 天 2,000 USDT @8%(已到期;10/20 已領 288.00 EDOT)待領 32.00 EDOT;活期 1,200 USDT @5%(10/14 存 1,500、10/18 提領 300)待領 48.00 EDOT;合計待領 1,680.00 EDOT。 ## 12. 提前解鎖:暫定不開放 - Eason 決定:幣股定期**暫定不能提前解鎖**。 - 前台全部拿掉:持倉卡沒有提前解鎖鈕、沒有違約金/罰金說明;提領面板只處理已到期定期和活期;存入條款寫「定期到期後可提領 · 活期隨時可提領」;紀錄沒有「提前解鎖」類型。 - 未到期的定期持倉只顯示倒數(「剩 49 天 23:59 · 2026/12/14 解鎖」)和「到期後可提領」。活期不變,隨時可提領。 - **給技術**:合約的提前解鎖開關保留,但預設關閉。之後如果要打開,需要先補一套設計(按鈕位置、違約金說明、確認頁、紀錄類型),再上線。