docs: sync from backend 7688f57 — sweep gas strategy: PermitPull + GasTopUp signers

This commit is contained in:
Siavash Sameni
2026-05-29 10:13:44 +04:00
parent 8623762b85
commit eeb8066b87
4 changed files with 202 additions and 1 deletions

View File

@@ -1,6 +1,6 @@
# PRD: Wallet, Multichain, Confirmations, AML, Trezor
> Status: **Living — last edit 2026-05-28 (after Task #7 core shipped in backend/frontend 2.6.42)**
> Status: **Living — last edit 2026-05-29 (live sweep probe passed; gas strategy decided; sweep gas PRD created)**
> Author: nick + claude
> Owner: backend (payments) + frontend (admin UI + checkout)
> Related: `PRD - Request Network In-House Checkout.md`, `01 - Architecture/Request Network Integration Constraints.md`, `08 - Operations/Handoff - Request Network In-House Checkout - 2026-05-28.md`
@@ -42,6 +42,16 @@ These were open questions in the original draft; the shipped implementation lock
| Derivation index allocation | Monotonic counter in a `counters` Mongo collection (`{_id: 'derived_destination_index', seq: <int>}`) updated atomically via `findByIdAndUpdate { $inc: { seq: 1 } }`. No re-derivation, no race window. |
| Sweep strategy | **Cron-based** by default (`DERIVED_DESTINATION_SWEEP_INTERVAL_MS=300000`, i.e. 5 min) **plus manual admin trigger**. Both go through the same `sweepService` and the same Transaction Safety Provider checks. Auto-start on backend boot is not wired yet — admins start the cron via `POST /api/payment/derived-destinations/cron/start`. |
| Signing | **`DERIVED_DESTINATION_SWEEP_SIGNER=build-only`** in prod — the backend builds the sweep tx but doesn't sign it (Trezor flow in Task #11 will). For local dev, `DERIVED_DESTINATION_SWEEP_SIGNER=hot-key` plus `DERIVED_DESTINATION_XPRIV` lets the backend sign — DO NOT USE IN PROD. |
| Gas strategy | **BSC only: gas top-up before sweep** (master wallet sends BNB, then derived address calls `transfer`). All other chains: **EIP-2612 permit-pull** — derived address signs off-chain, master wallet calls `permit()` + `transferFrom()`, derived address never needs native gas. Audit confirmed: BSC USDT/USDC have no permit; ETH/ARB/Polygon/Base USDC+USDT all have EIP-2612. See `PRD - Sweep Gas Strategy - Permit Pull vs Gas Top-Up.md`. |
### Live probe results (2026-05-29)
First real sweep executed on dev:
- Address: `0xF83bDD716724442693a2005dBeD06ad67089f830` (derivation index 1, `m/44'/60'/0'/0/1`)
- Funded with: 0.1 USDC (BSC) + 0.001 BNB (for gas, manually seeded)
- Sweep tx: `0x80cdb9ca104d624bc9783215618f82d5d758c6b2714b1ef13b999d51173b219d`
- Result: ✅ 0.1 USDC transferred to master `0xa3049825c0785095EEd5E7976E0E539466c84044`
- Bug found and fixed: `HotKeySweepSigner` was calling `derivePath("m/44'/60'/0'/0/1")` on a node already at depth 3 — must strip base prefix and pass only relative path `"0/1"`. Fixed in commit `1594f32`.
### Still open
1. **Multi-seller cart UX** — not built. Today's frontend assumes 1 Payment per checkout page. The PRD copy from the original draft still applies: