{"title":"APP","subtitle":"","coverImg":"","contentType":"text/markdown","content":"# SPACE 链上挂单簿(space-orderbook)\n\n## 这个应用是干什么的\n\n这是一个跑在 Bot Browser 里的静态 MetaApp,用来看一张**真实存在链上的挂单板**,并且用当前登录的 MetaID 身份往链上发布挂单、撤单、吃单意向。\n\n它只做三件事:\n\n1. 从公开的 MetaWeb 索引(`https://manapi.metaid.io`)读取 `/protocols/space-market/` 下的四类 pin:`order`(挂单)、`order-cancel`(撤单)、`take`(吃单意向)、`fill`(成交记录),把它们渲染成盘口、成交表和价格图。\n2. 用 `metaid.pin.write` 代当前身份发布上述 pin。\n3. 诚实标注数据状态:链上读取失败时回退到构建时写入的内置快照,并在页头显著标注「链上读取失败 · 快照时间」;成交样本不足 3 笔时不画趋势线、不插值。\n\n## 它不是什么(重要)\n\n- 它**不是交易所**,不撮合、不托管、不代收代付、不碰私钥,也不请求任何钱包 API。\n- 挂单只是公开意向;真正成交需要卖方用私钥生成定向单(MRC-721 部分交易),买方再用自己的钱包广播。这个过程不发生在页面里。\n- 不涉及人民币,只使用 SPACE(MVC 原生币)与 MRC-721 资产。\n\n## 结构地图\n\n- `index.html` —— 唯一的入口文件,内联全部 CSS 与 JS,无外部依赖、无构建步骤。\n- 页面从上到下:页头(数据源徽标 + 当前身份)、统计条、盘口双栏、成交与价格图、发布挂单表单、边界与说明。\n- 关键函数(都在 `index.html` 底部的 IIFE 里):\n - `loadPath(path)` / `loadAll()`:并发读取四类 pin,失败时回退 `SNAPSHOT`。\n - `statusOf(order)`:由 fill / cancel / expiresAt 推导订单状态(在售 / 已撤 / 已成交 / 已过期)。撤单只认「撤单 pin 的 `by` 等于订单 `makerGlobalMetaId`」的那一条,防止别人替你撤单。\n - `renderBook()` / `renderStats()` / `renderChart()` / `renderFills()`:纯函数式渲染,全部走 `innerHTML` 前做 HTML 转义。\n - `postOrder()` / `postTake()` / `postCancel()`:组装 JSON 并调用 `metaid.pin.write`。\n\n## 参数与数据契约\n\n协议路径:\n\n- `/protocols/space-market/order`:`{v,orderId,side:\"sell\"|\"buy\",itemPinId,collection,itemName,priceSats,priceSpace,makerGlobalMetaId,makerAddress,expiresAt,note}`\n- `/protocols/space-market/order-cancel`:`{v,orderId,orderPinId,reason,by,at}`\n- `/protocols/space-market/take`:`{v,orderId,orderPinId,takerGlobalMetaId,takerAddress,at}`\n- `/protocols/space-market/fill`:`{v,orderId,txid,itemPinId,collection,itemName,priceSats,priceSpace,buyerAddress,sellerAddress,at,before,after}`\n\n读取端点:\n\n- 列表:`https://manapi.metaid.io/api/pin/path/list?path=<路径>&size=50`(返回 `data.list[].id / contentSummary / timestamp / globalMetaId`)\n- 单条:`https://manapi.metaid.io/api/pin/`\n\n本地存储:`localStorage['space_market_addr']` 保存用户填写的 MVC 收款地址(只在本机,不上传)。\n\n## 二次开发注意事项\n\n- 包内资源必须用相对路径;本应用目前只有 `index.html` 一个文件。\n- 修改后要同步更新 `APP.md`,并重新生成 `index.html` 里的 `SNAPSHOT` 常量(它是构建时的真实回执快照,用于链读失败兜底)。\n- 价格图的红线:**不许用挂单价冒充成交价,不许插值,不许在 N<3 时画趋势线**。这条口径写进了操作说明并上链,改动前请先读 `pin://268a7491aeeeb5d3bf48d6cd843640b6762bc8a0410b1497a6c949b79034d486i0`。\n- 订单状态推导集中在 `statusOf()`;如果协议新增状态,改这一处即可。\n- 撤单权限校验不要删:只有订单创建者本人发布的 cancel pin 才算数。\n","encryption":"0","createTime":1794214895422,"tags":[],"attachments":[]}