# pangolin-pay 自托管 USDT(TRC20) 收款服务。给每个订单派生一个**唯一收款地址**(watch-only,从账户 xpub 派生,**不持私钥**),轮询 TronGrid 侦测到账、确认后标记订单已付。归集(把钱扫到冷 钱包)是**独立的离线步骤**,本服务不碰私钥。 > 属 #34「独角数卡 + USDT 收款闭环」的加密货币交易引擎(计划见 > `docs/superpowers/plans/2026-07-09-crypto-tx-engine.md`)。概念见 brain > `notes/dev/crypto-hd-wallet-basics.html`。 ## 安全模型(必读) - 本服务(热、联网)**只持 account xpub**——能派生收款地址、能查到账,**拿不到任何私钥**。被脱库也转不走钱。 - 私钥/助记词**冷存**;要动钱(归集)时才在**离线端**用私钥签名(见 seed.go,OFFLINE ONLY)。 - 密钥(xpub / TronGrid key)走 Bitwarden,不入 git、不写死。 ## Phase A —— 离线准备钱包(你在断网机器上做) 1. 断网,用 Ian Coleman `bip39-standalone.html`(或 `bip_utils`)生成**两套** 24 词助记词: 钱包 A(运营收款)、钱包 B(冷备金库)。Coin=TRX、English。 2. 取**钱包 A 的 Account Extended Public Key**(`m/44'/195'/0'` 的 xpub)→ 就是本服务的 `PAY_ACCOUNT_XPUB`。 3. 取**钱包 B 的地址0**(`T...`)→ 归集目标(Phase D 用)。 4. **交叉核对(关键)**:本仓自带的金标准向量(测试助记词 `abandon…about`)必须与 Ian Coleman 一致 —— 跑 `go test ./internal/wallet -run TestKnownVector -v`,再在 Ian Coleman 里用同一测试 助记词、Coin=TRX 对照前 3 个地址。一致 = 派生实现可信;不一致 = 有 bug,别上线。 5. 助记词 A/B 分开冷存 + Bitwarden。**只把 xpub_A 交给本服务。** ## 运行 ```bash export PAY_ACCOUNT_XPUB="xpub..." # 钱包 A 的 account xpub(必填) export TRONGRID_API_KEY="..." # TronGrid key(建议) export PAY_DB="pay.db" # SQLite 路径(默认 pay.db) export PAY_ADDR=":8090" # 监听(默认 :8090) export PAY_POLL_SECONDS="20" # 轮询间隔秒(默认 20) # USDT_CONTRACT / TRONGRID_BASE 默认主网 go run ./cmd/paywatch ``` ## API ``` POST /order {"sku":"pro-year","amount":5000000} # amount = micro-USDT(1e-6) → 201 {"order_no","address","expect_amount","status":"pending","expires_at"} GET /order/{orderNo} → 200 {..., "status":"pending|paid|expired","tx_id"} GET /healthz → 200 ok ``` 门面(独角数卡)下单时调 `POST /order` 拿收款地址;支付页轮询 `GET /order/{id}` 直到 `paid`。 ## Phase D —— 归集(离线,后续) `internal/wallet/seed.go` 提供离线派生私钥的原语(`PrivKeyHexFromMnemonic`)。完整的 sweep (构造 TRC20 transfer → 离线签名 → 广播)+ gas 处理 + runbook 在后续切片实现。 ## 测试 ```bash go test ./... ``` - `wallet`:派生一致性(xpub 路径 == 私钥路径)+ 金标准向量(需 A.4 核对)。 - `store`/`pay`/`watcher`/`httpapi`:建单/派生地址/侦测到账/幂等/超时/HTTP。