Flutter 五端 + 官网 + 用户中心的设计系统治理全景:一次 UI 改动标准路径、目录地图、三层真相源模型、令牌 codegen、四道静态闸「违规谁拦」、像素验收(golden 双主题 + fidelity 待建)、响应式五端、规则速查。原型单源 design/prototype/(tokens/atoms/icons/index.html)、check-ds/check-l1-sync/check_ds_code/codegen-drift 四闸进 CI、golden 全量 34 绿含 CJK。
diff --git a/docs/pay-address-pool-plan.html b/docs/pay-address-pool-plan.html
new file mode 100644
index 0000000..5193cfc
--- /dev/null
+++ b/docs/pay-address-pool-plan.html
@@ -0,0 +1,110 @@
+
+
+
+
+
← 文档索引
+
pangolin-pay 地址池收款模型
+
2026-07-09 · 阅读版 · 执行真相源 docs/superpowers/plans/2026-07-09-pay-address-pool.md · #34/34A 收款模型修订(折中方案)
+
+
+从"每单唯一 HD 地址"改为地址池复用:池大小 = 峰值并行度(初始 10,不够动态派生),地址复用摊薄激活/归集成本;仍多地址,避免并发订单金额撞、对账精确。归集成本从 O(订单数) 降到 O(池大小),激活一次/地址即长期复用。是"单地址(省钱撞单)"与"每单唯一(精确但贵)"的折中。
+
+
+
+核心风险 · 地址复用的迟到付款错配:地址回收后绑给新订单,若前一个用户超时后才付款,钱打到已绑新订单的地址上 → 可能误配。解法(必须):① 匹配按"到账 tx + 金额 + 时间戳(晚于建单)",不按余额、不只按地址;② 每单唯一金额(基准+唯一尾数);③ 匹配不到活跃订单的到账 → 记 orphan_payments 人工对账;④(可选)超时后地址冷却再重绑。
+
+
+
设计(规则 + 安全点)
+
+- 地址池:HD 派生地址(
m/44'/195'/0'/0/i),状态 idle|busy,初始 10。
+- 建单:绑最小编号 idle 地址→busy;无 idle → 派生新地址入池。原子(事务/行锁,防并发抢同址)。
+- 每单唯一金额 ⭐:基准 + 唯一尾数,当前活跃订单间不撞;复用地址上旧单迟到付款不误配新单。
+- 15min 超时 → expired → 地址回 idle(可选冷却)→ 提示重建订单。
+- 付款完成 → paid → 地址回 idle(注意:地址里仍有 USDT 待归集,idle 只表示可重绑)。
+- 匹配:找"到该地址 + 金额命中 + 区块时间晚于建单"的转入 tx。
+- 同用户单订单:同时只能一个活跃订单。
+- 归集:定期扫池内有余额地址→冷钱包(能量租赁 ~$0.1–1/笔);池 ~10,笔数有界;与 busy 解耦。
+
+
+
Phase A — 数据模型
+
+- A.1
addresses(id, addr_index唯一, address, state, activated, created_at),按需派生入池。
+- A.2
pay_orders 加 user_ref / address_id / expect_amount(唯一金额) / matched_tx_id。
+- A.3
orphan_payments(tx_id唯一, address, value, block_ts, handled)。
+- A.4 复用 addr_cursor 派生新址;迁移 + 索引(status/address/user_ref)。
+
+
+
Phase B — 建单
+
+- B.1 CreateOrder(user, sku):校验同用户无活跃单 → 原子选最小 idle 置 busy(无则派生)→ 分配唯一金额 → 写 pending(TTL 15min)。
+- B.2 唯一金额分配(基准+唯一尾数,当前活跃单间不撞)。
+- B.3 GetOrder + releaseAddress 公共方法(paid/expired 复用)。
+
+
+
Phase C — watcher(匹配/释放/孤儿)
+
+- C.1 匹配:pending 单查其地址转入,value 命中唯一金额 且
block_ts>created → paid + 记 tx + 释放地址。
+- C.2 超时:pending 过期 → expired + 释放地址(可选冷却)。
+- C.3 孤儿:匹配不到活跃订单的到账 → 记 orphan_payments(去重)。
+- C.4 幂等(tx_id 去重)+ 崩溃恢复;TronGrid 取 block_timestamp 供时间过滤。
+
+
+
Phase D — 归集
+
+- D.1 扫池内有余额地址 → 冷钱包(能量租赁,先手动 runbook);与订单状态解耦。
+
+
+
Phase E — 测试 + 真链
+
+- E.1 单测:并发不抢同址、复用后迟到付款不误配、唯一金额、超时释放、孤儿、幂等、崩溃恢复、同用户单订单。
+- E.2 真链:两并发订单各绑地址付款;一单超时释放后新单复用同址,旧地址补"旧金额"付款应成孤儿不误配;归集。
+
+
+
不在本轮 / 取舍
+
+- GasFree(#35,免 TRX 但每笔固定 1 USDT,更适合少地址批量,另议)。
+- 能量租赁自动化(先手动);池增长上限(先宽松);发货侧(独角数卡 + /internal/codes/mint)另排。
+
+
+
相关:加密货币交易引擎(已实现钱包/tron/sweep) · #34 收款闭环全景
+
+
+
+
diff --git a/docs/superpowers/plans/2026-07-09-pay-address-pool.md b/docs/superpowers/plans/2026-07-09-pay-address-pool.md
new file mode 100644
index 0000000..5ed10ea
--- /dev/null
+++ b/docs/superpowers/plans/2026-07-09-pay-address-pool.md
@@ -0,0 +1,71 @@
+# pangolin-pay 地址池收款模型(折中方案,取代"每单唯一 HD 地址")
+
+> #34/34A 收款模型修订。**Context**:每单唯一 HD 地址 → 每地址激活(~1 TRX)+ 归集(每笔一次转账)成本随
+> **订单总数线性增长**(#34 暴露的严峻成本)。改为**地址池复用**:池大小 = **峰值并行度**(初始 10,不够动态派生),
+> 地址**复用**摊薄激活/归集;仍是多地址,**避免并发订单金额撞、对账精确**。这是"单地址(省钱但撞单)"与
+> "每单唯一(精确但贵)"的折中。
+>
+> 归集成本从"O(订单数)"降到"O(池大小)";激活成本一次性(每个池地址激活一次即长期复用)。
+>
+> **本 plan = 用户定的规则 + 补齐的安全点**(核心:地址复用的**迟到付款错配**)。已实现的 Phase B(钱包派生)、
+> tron(TronGrid 读到账/建/广播/签名)、cmd/sweep 复用;主要改 store / pay(建单)/ watcher(匹配)。
+
+## 设计(规则 + 安全点)
+
+- **地址池**:HD 派生地址(路径 `m/44'/195'/0'/0/i`,与现有一致),各有状态 `idle | busy`。初始池 10。
+- **建单**:绑**最小编号的 idle** 地址 → 置 `busy`;**无 idle → 派生下一个新地址**(编号递增)入池并绑之。
+- **每单唯一金额** ⭐必需:基准价 + 唯一尾数(如按订单序号映射的微分),保证**当前活跃订单之间金额不撞**,
+ 且复用地址上"旧订单迟到付款"不会误配"新订单"。
+- **15 分钟超时**:超时 → `expired` → 地址回 `idle`(可选**冷却期**再重绑,降低迟到错配)→ 提示用户**重建订单**、用新订单地址付款。
+- **付款完成**:watcher 确认到账 → 订单 `paid` → 地址回 `idle`。**注意**:此时地址里**仍有 USDT**(待归集);
+ `idle` 只表示"可重绑",不代表钱清了。
+- **匹配规则(核心)**:watcher 找**到该地址、金额 == 该单唯一金额(或 ≥,带容差)、且到账区块时间晚于订单创建**
+ 的 TRC20 转入 **tx** → 匹配。**绝不按余额、不只按地址**(地址会累积余额、会复用)。
+- **同用户单订单**:同一用户同时只能有**一个**活跃(pending)订单。
+- **孤儿付款**:到账 tx 匹配不到任何活跃订单(迟到 / 欠额 / 误差)→ 记 `orphan_payments`,人工对账/补发。
+- **归集**:定期扫池内**有余额**的地址 → 冷钱包(**能量租赁** ~$0.1–1/笔);池 ~10 地址,**归集笔数有界**;
+ 归集与 `busy` 无关(随时可扫,不影响待付订单——到账是未来的独立 tx)。
+- **池增长上限**(可选):无空闲就新建,设上限防滥用无限增长(超限则排队/拒单)。
+
+## Phase A — 数据模型改造
+
+- [ ] `addresses` 表:`id / addr_index(唯一) / address / state('idle'|'busy') / activated(bool) / created_at`;初始不预建,按需派生入池。
+- [ ] `pay_orders` 改:加 `user_ref`(同用户单订单约束用)、`address_id`(绑定的池地址)、`expect_amount`(唯一金额,micro-USDT)、`matched_tx_id`;保留 status/created_at/expires_at。
+- [ ] `orphan_payments` 表:`tx_id(唯一) / address / value / block_ts / created_at / handled(bool)`。
+- [ ] 复用现有 `addr_cursor`(HD 派生游标)派生新池地址。迁移脚本 + 索引(status、address、user_ref)。
+
+## Phase B — 建单(pay 服务)
+
+- [ ] `CreateOrder(userRef, sku)`:① 校验**同用户无活跃订单**(有则返回现有/拒);② **原子**选最小编号 `idle` 地址(事务 + 行锁)置 `busy`;③ 无 idle → `NextAddrIndex` 派生新地址(`AddressFromAccountXpub`)入池并绑;④ 分配**唯一金额**;⑤ 写 `pending` 单(TTL 15min)。
+- [ ] **唯一金额分配**:基准金额 + 唯一尾数,保证与**当前所有活跃订单**不撞(可用订单序号 → 尾数微分,micro-USDT 级);记录基准+尾数便于展示。
+- [ ] `GetOrder`;释放地址的公共方法 `releaseAddress(addrID)`(paid/expired 复用)。
+
+## Phase C — watcher 改造(匹配 + 释放 + 孤儿)
+
+- [ ] **匹配**:对每个 `pending` 单,查其绑定地址的 TRC20 转入;筛 `value` 命中唯一金额(==,或 ≥ 带小容差)**且 `block_ts > order.created_at`** → `paid` + 记 `matched_tx_id`;**释放地址 → idle**。
+- [ ] **超时**:`pending` 过期 → `expired` + 释放地址 → idle(可选冷却期后才允许重绑)。
+- [ ] **孤儿**:遍历池地址的到账 tx,凡匹配不到任何活跃订单的转入 → 写 `orphan_payments`(去重 by tx_id)。
+- [ ] **幂等**(tx_id 全局去重,含 orphan)、崩溃恢复(从 DB pending + 池状态重建)。TronGrid 需能取到账时间戳(`block_timestamp`)用于时间过滤。
+
+## Phase D — 归集(复用 cmd/sweep)
+
+- [ ] 扫池内**有余额**地址 → 冷钱包;接**能量租赁**(先手动 runbook,后续自动化);归集与订单状态解耦。
+- [ ] 归集不清空 `busy` 语义;只搬余额。runbook 写清"哪些地址、多久扫一次、能量怎么租"。
+
+## Phase E — 测试 + 真链验证
+
+- [ ] 单测:并发建单**不抢同址**(原子性)、地址**复用后旧订单迟到付款不误配新订单**(唯一金额+时间戳)、唯一金额不撞、超时释放、孤儿记录、幂等、崩溃恢复、同用户单订单约束。
+- [ ] 真链:两并发订单各绑不同地址各自付款到 paid;一单超时释放后新单**复用同址**,再对旧地址补一笔"旧金额"付款 → 应成**孤儿**、不误配新单;归集池地址到冷钱包。
+
+## Verification / 判据
+
+- `go test ./...`(store/pay/watcher 新逻辑全绿,重点覆盖复用错配)。
+- 真链:并发 + 复用 + 迟到付款三场景表现正确;归集笔数 = 有余额的池地址数(有界)。
+- 成本:激活一次/地址、归集 O(池大小);对小额高频订单不再被激活费线性拖累。
+
+## 不在本轮 / 取舍
+
+- GasFree(#35,免 TRX 但每笔固定 1 USDT,更适合少地址批量,另议)。
+- 能量租赁自动化(先手动)。
+- 池增长上限/排队(先不设,或设一个宽上限)。
+- 发货侧(独角数卡 + /internal/codes/mint)另排。