5fd0d3c148
pay-server 自带 /_test 测试页:创建订单→显示收款地址+精确金额(可复制)
+过期倒计时→轮询状态到 paid。同源、无 CORS/CSP 摩擦,不碰营销站安全头;
纯调 POST /order + GET /order/{id},无私钥无密钥。生产收银台后续走独角数卡门面。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
105 lines
6.8 KiB
HTML
105 lines
6.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>pangolin-pay 加密货币交易引擎 实现计划</title>
|
|
<style>
|
|
:root{
|
|
--bg:#0f1117; --panel:#171a22; --panel2:#1d2129; --fg:#e6e8ee; --fg2:#a8afbd;
|
|
--accent:#e0884f; --accent2:#5fb0c9; --ok:#5ec27a; --bad:#e06a6a; --warn:#e0b84f;
|
|
--border:#272c36; --mono:"SF Mono",ui-monospace,Menlo,Consolas,monospace;
|
|
--sans:-apple-system,"PingFang SC","Helvetica Neue",Arial,sans-serif;
|
|
}
|
|
*{box-sizing:border-box}
|
|
body{margin:0;background:var(--bg);color:var(--fg);font-family:var(--sans);line-height:1.7;font-size:15px}
|
|
.wrap{max-width:960px;margin:0 auto;padding:48px 24px 96px}
|
|
h1{font-size:29px;line-height:1.3;margin:0 0 8px;letter-spacing:-.01em}
|
|
.sub{color:var(--fg2);font-size:15px;margin:0 0 32px}
|
|
h2{font-size:20px;margin:40px 0 12px;padding-bottom:8px;border-bottom:1px solid var(--border);color:var(--accent)}
|
|
p{margin:10px 0}
|
|
code{font-family:var(--mono);font-size:.85em;background:var(--panel2);padding:1px 6px;border-radius:5px;color:#f0d9c4}
|
|
pre{background:#0a0c11;border:1px solid var(--border);border-radius:10px;padding:14px 16px;overflow-x:auto;font-family:var(--mono);font-size:12.5px;line-height:1.5;color:#cdd3df}
|
|
.tag{display:inline-block;font-size:12px;font-weight:600;padding:2px 9px;border-radius:999px;vertical-align:middle}
|
|
.tag.info{background:rgba(95,176,201,.16);color:var(--accent2)}
|
|
ul.ck{list-style:none;padding-left:4px}
|
|
ul.ck li{position:relative;padding-left:26px;margin:7px 0}
|
|
ul.ck li::before{content:"☐";position:absolute;left:0;color:var(--fg2)}
|
|
ul{padding-left:22px}
|
|
li{margin:6px 0}
|
|
.lead{background:linear-gradient(180deg,rgba(224,136,79,.10),transparent);border:1px solid var(--border);border-radius:12px;padding:18px 20px;margin:0 0 8px}
|
|
.small{color:var(--fg2);font-size:13px}
|
|
a{color:var(--accent2)}
|
|
.back{display:inline-block;margin-bottom:24px;font-size:13px}
|
|
b{color:#fff}
|
|
.warnbox{background:rgba(224,106,106,.08);border:1px solid rgba(224,106,106,.35);border-radius:12px;padding:14px 18px;margin:14px 0}
|
|
.warnbox b{color:var(--bad)}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="wrap">
|
|
<a class="back" href="index.html">← 文档索引</a>
|
|
<h1>pangolin-pay 加密货币交易引擎</h1>
|
|
<p class="sub">2026-07-09 · <span class="tag info">阅读版</span> · 执行真相源 <code>docs/superpowers/plans/2026-07-09-crypto-tx-engine.md</code> · #34 的第一块(可独立执行 + 真实小额验证)</p>
|
|
|
|
<div class="lead">
|
|
#34 的<b>第一块、可独立执行、能用真实小额 USDT 端到端验证</b>的基础件。<b>只做加密货币"交易"核心</b>——派生地址、侦测到账、归集(sweep)——<b>不含</b>独角数卡对接、不含发码。成果=独立 Go 服务 <code>pangolin-pay</code>,提供"建单→收款地址→侦测到账→标记已付"+ 离线归集工具。跑通后任何门面都能挂上来。
|
|
</div>
|
|
|
|
<div class="warnbox">
|
|
<b>安全铁律:</b>热服务只持 <b>xpub</b>(watch-only 派生)+ TronGrid key + 金库收款地址,<b>绝不持私钥</b>;私钥/助记词冷存,归集在离线端签名。关键常量(核对无误再写死):USDT-TRC20 合约 <code>TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t</code>(6 位小数)· 派生 <code>m/44'/195'/0'/0/i</code> · TronGrid <code>api.trongrid.io</code>。
|
|
</div>
|
|
|
|
<h2>Phase A — 钱包与密钥(全程离线)</h2>
|
|
<ul class="ck">
|
|
<li><b>A.1</b> 离线生成<b>两套</b>助记词(断网,Ian Coleman/bip_utils,TRX/24词/English):钱包 A 运营收款、钱包 B 冷备金库。</li>
|
|
<li><b>A.2</b> 导出<b>钱包 A account xpub</b>(<code>m/44'/195'/0'</code>);取<b>钱包 B 地址0</b> 当归集目标。</li>
|
|
<li><b>A.3</b> 冷存助记词 A/B(分开)+ Bitwarden;只把 xpub_A + sweep_addr_B 放进配置。</li>
|
|
<li><b>A.4</b> <b>交叉核对</b>:Go 派生出的地址 0..4 必须与 Ian Coleman 逐个一致(防收款地址对不上)。</li>
|
|
</ul>
|
|
|
|
<h2>Phase B — 服务骨架 + HD 派生</h2>
|
|
<ul class="ck">
|
|
<li><b>B.1</b> 建 Go 服务 <code>pangolin-pay</code>(独立)。配置:xpub_A / sweep_addr_B / TronGrid key / 确认数 / 超时。自带 SQLite。</li>
|
|
<li><b>B.2</b> HD 派生:go-bip39 + hdkeychain 从 xpub_A watch-only 派生 <code>.../0/i</code> 公钥 → TRON 地址(Keccak 后20字节 + <code>0x41</code> + Base58Check)。<b>单测对齐 Ian Coleman</b>。</li>
|
|
<li><b>B.3</b> 数据模型:<code>pay_orders(order_no, sku, expect_amount, addr_index, address, status, tx_id, confirmations, created_at, expires_at)</code> + <code>addr_cursor(next_index)</code>(地址不复用)。</li>
|
|
</ul>
|
|
|
|
<h2>Phase C — 收款(建单 + 侦测到账)</h2>
|
|
<ul class="ck">
|
|
<li><b>C.1</b> <code>POST /order</code> → cursor++ 派生新地址 → 写单(expect_amount 唯一尾数、expires +15min)→ 返回 <code>{order_no, address, expect_amount, expires_at}</code>。</li>
|
|
<li><b>C.2</b> <code>GET /order/{order_no}</code> → status(pending/paid/expired)。</li>
|
|
<li><b>C.3</b> TronGrid watcher 轮询:<code>/v1/accounts/{addr}/transactions/trc20?only_confirmed=true&contract_address=<USDT></code>,匹配 to+金额(6位小数)+确认 → paid、记 tx_id。</li>
|
|
<li><b>C.4</b> 幂等(同 tx 只认一次)+ 超时 expired(地址不复用)+ 崩溃恢复。</li>
|
|
<li><b>C.5</b> 限流退避 + 重试;mock TronGrid 测试:匹配/确认/超时/幂等/恢复。</li>
|
|
</ul>
|
|
|
|
<h2>Phase D — 归集(sweep,离线签名)</h2>
|
|
<ul class="ck">
|
|
<li><b>D.1</b> watcher(xpub)列出有余额地址清单。</li>
|
|
<li><b>D.2</b> gas:gas 钱包给待归集地址打少量 TRX(或能量租赁)。</li>
|
|
<li><b>D.3</b> 离线机导入<b>钱包 A 助记词</b> → 派生 address_i 私钥 → 构造 TRC20 <code>transfer(sweep_addr_B, balance)</code> → <b>离线签名</b>。</li>
|
|
<li><b>D.4</b> 广播:签好的交易经 TronGrid <code>/wallet/broadcasttransaction</code> 上链(私钥不出门)。</li>
|
|
<li><b>D.5</b> 半自动脚本 + 归集 runbook;阈值/定时触发;热地址不囤大额。</li>
|
|
</ul>
|
|
|
|
<h2>Phase E — 端到端验证(真实小额)</h2>
|
|
<ul class="ck">
|
|
<li><b>E.1</b> 真单:<code>POST /order</code> → 转 1 USDT(TRC20)→ watcher 确认 → status=paid。</li>
|
|
<li><b>E.2</b> 归集:D 流程 → USDT 到钱包 B 冷地址。</li>
|
|
<li><b>E.3</b> 安全核对:热服务无私钥、密钥不入 git、地址不复用。</li>
|
|
</ul>
|
|
|
|
<h2>不在本轮</h2>
|
|
<ul>
|
|
<li>独角数卡门面对接 + epay 支付口(下一块:接门面)。</li>
|
|
<li><code>/internal/codes/mint</code> JIT 发码 + 兑换闭环(发货侧,#34 后续)。</li>
|
|
<li>HD 自动 sweep(先人工)、多币种、watcher 高可用。</li>
|
|
</ul>
|
|
|
|
<p class="small" style="margin-top:32px">相关:<a href="payment-clean-usdt-plan.html">#34 收款闭环全景</a> · <a href="payment-channels-overview.html">渠道选型</a> · 知识:brain <code>notes/dev/crypto-hd-wallet-basics.html</code></p>
|
|
|
|
</div>
|
|
</body>
|
|
</html>
|