docs(prd): clarify task #7 keying — cart-with-multi-seller, per-Payment derivation
User flagged: a buyer's cart can span multiple sellers, so 'per-(buyer, seller)' isn't really 1:1. The right framing is per-Payment: Amanat already creates N Payment records for an N-seller cart (one per sellerOfferId), and each gets its own derived destination + RN intent + buyer-side approve+pay tx pair. PRD now explicitly: - Recommends per-Payment keying (which collapses to per-(buyer, sellerOfferId) via the existing uniq_pending_request_network_by_buyer_session index) - Documents the multi-seller cart UX (N approve+pay pairs in sequence, with clear progress indicator, mid-cart abandonment is fine) - Notes RN's ERC20FeeProxy is single-destination by design (no atomic split in v1; future Amanat splitter contract is out of scope) - Updates open questions to monotonic derivation counter, immediate sweep, single-use addresses (no rotation), and cold-payment recovery - Scope explicitly mentions cart-aware buyer UX as part of task #7 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
"master": {
|
||||
"tasks": [
|
||||
{
|
||||
"id": 1,
|
||||
"id": "1",
|
||||
"title": "Stabilize Mermaid diagram rendering across documentation vault",
|
||||
"description": "Correct Mermaid syntax/rendering issues across the documentation vault and validate all Mermaid blocks.",
|
||||
"details": "Source PRD: .taskmaster/docs/prd-mermaid-diagram-rendering-stabilization.md. Scope covered 57 Mermaid blocks and 11 failing blocks. The source PRD records that all targeted files now pass mmdc parse validation and the full vault sweep passes.",
|
||||
@@ -47,7 +47,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"id": "2",
|
||||
"title": "Implement platform audit remediation plan",
|
||||
"description": "Address the code-backed security and consistency issues identified in the 2026-05-24 platform audit remediation PRD.",
|
||||
"details": "Source PRD: .taskmaster/docs/prd-platform-audit-remediation-plan-2026-05-24.md. Target backend hardening first, then documentation/runtime alignment. Delivery order suggested by PRD: security/auth, rate limiting, passkeys, Web3 verification, socket hardening, dispute hold controls, docs/API alignment.",
|
||||
@@ -154,7 +154,7 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"id": "3",
|
||||
"title": "Migrate payment architecture toward Request Network and internal funds management",
|
||||
"description": "Plan and implement provider-neutral payment flows, Request Network pay-in support, funds ledger, webhook reconciliation, release/refund orchestration, UI migration, and SHKeeper decommissioning.",
|
||||
"details": "Source PRD: .taskmaster/docs/prd-request-network-migration-and-funds-management.md. The PRD recommends phased migration behind a provider adapter, Secure Payment Pages first, platform-controlled escrow/payee destination, and a first-class internal funds ledger before release/refund enforcement.\n\nPost-completion update: Task 3 now includes a CI-safe focused verification command for the provider-neutral payment migration plus optional Trezor safekeeping. Trezor safekeeping is optional by default via TREZOR_SAFEKEEPING_REQUIRED=false and only gates release/refund confirmation when explicitly enabled. Vault references: 04 - Flows/Trezor Safekeeping Flow.md, 03 - API Reference/Trezor API.md, and 08 - Operations/Payment and Trezor Verification Report.md.",
|
||||
@@ -341,7 +341,7 @@
|
||||
"updatedAt": "2026-05-24T07:04:01.906Z"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"id": "4",
|
||||
"title": "Define backend security and refactor strategy from latest audit",
|
||||
"description": "Convert the backend stack security/refactor assessment into concrete architecture decisions, documentation deliverables, and developer handoff criteria.",
|
||||
"details": "Source audit: .taskmaster/docs/audit-backend-stack-security-and-refactor-assessment-2026-05-24.md. This task is advisory/architecture-focused and should run in parallel with immediate hardening. It should produce the decision artifacts needed before any backend-core rewrite or provider migration is started.",
|
||||
@@ -483,7 +483,7 @@
|
||||
"updatedAt": "2026-05-24T07:23:44.643Z"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"id": "5",
|
||||
"title": "Deliver Telegram-native app, bot, and wallet experience",
|
||||
"description": "Create a Telegram bot plus Mini App surface so users can complete Amanat buyer, seller, escrow, chat, dispute, payment, release/refund, and support workflows from inside Telegram.",
|
||||
"details": "Source PRD: .taskmaster/docs/prd-telegram-native-app-bot-wallet.md. Keep this as a separate delivery track from security remediation and Request Network migration. Identity, bot navigation, Mini App shell, and notifications can start behind flags; wallet/payment crediting and release/refund actions must use canonical backend authorization, provider adapter, funds ledger, escrow state machine, idempotency, and dispute holds.",
|
||||
@@ -647,7 +647,7 @@
|
||||
"updatedAt": "2026-05-24T13:46:14.458Z"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"id": "6",
|
||||
"title": "Request Network in-house checkout (Rabby-supporting)",
|
||||
"description": "Replace the redirect to pay.request.network with an Amanat-rendered checkout page that submits the same on-chain calls as RN's hosted UI, so RN's webhook fires unchanged but buyers stay on amn.gg and Rabby works.",
|
||||
"details": "See PRD: nick-doc/.taskmaster/docs/prd-request-network-in-house-checkout.md (summary at nick-doc/PRD - Request Network In-House Checkout.md). Status: draft, pending review with second developer. Approach: replicate the two on-chain calls (approve + RN_FEE_PROXY.transferFromWithReferenceAndFee) using wagmi v2 with existing injected()/metaMask() connectors (Rabby works via EIP-6963). Hard-known: proxy 0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9, selector 0xc219a14d, paymentRef = last8Bytes(keccak256(requestId+salt+dest)), feeAmount=0, feeAddress=0x...dEaD. Backend: extend POST /payment/request-network/intents response with inHouseCheckout object (destination, tokenAddress, decimals, chainId, proxyAddress, paymentReference, feeAmount, feeAddress, amountWei). Frontend: new page /checkout/request-network/:paymentId with state machine reusing manual-payment.tsx layout chrome, hosted-page link kept as escape hatch. Implementation gated on a $0.50 cold probe on dev BSC to confirm RN's webhook fires for an externally-built tx. Out of scope: per-seller multi-chain config (§2), ephemeral wallets (§3), full RN removal (§4), gasless. Open questions in PRD §10.",
|
||||
@@ -671,18 +671,19 @@
|
||||
"updatedAt": "2026-05-28T07:34:40.368Z"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"id": "7",
|
||||
"title": "Per-(buyer, sellerOffer) ephemeral RN destination wallets",
|
||||
"description": "Replace the single shared Amanat destination wallet with a per-(buyerId, sellerOfferId) HD-derived address sent to Request Network on intent creation, plus sweep-on-approval and an admin UI.",
|
||||
"details": "See PRD - Wallet, Multichain, Confirmations, AML, Trezor.md §1. Files: new backend/src/services/payment/wallets/derivedDestinations.ts (getDestinationFor(buyerId, sellerOfferId) → {address, derivationPath, chainId}); Payment schema add metadata.derivedDestination; requestNetworkPayInService.ts override destinationId before POST /v2/secure-payments (we confirmed RN accepts different destinations per intent); new sweep cron + admin manual-trigger endpoint gated on Transaction Safety Provider; admin UI at /dashboard/admin/derived-destinations with address, balance, last sweep tx (BscScan link), ownership status. Open questions to settle first: HD vs disposable EOAs vs smart-forwarder (recommended HD); sweep cadence (recommended immediate); granularity (recommended per-(buyer, seller), not per-payment); re-use vs rotate after sweep. KMS-rooted seed; backend never holds raw private keys; signing via KMS API (Task #11 Trezor flow is the longer-term replacement). Acceptance: two payments from one buyer to two sellers land on two different addresses; RN webhook fires for both; sweep is idempotent; master seed never leaves KMS.",
|
||||
"testStrategy": "",
|
||||
"status": "pending",
|
||||
"status": "in-progress",
|
||||
"dependencies": [],
|
||||
"priority": "high",
|
||||
"subtasks": []
|
||||
"subtasks": [],
|
||||
"updatedAt": "2026-05-28T11:51:34.115Z"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"id": "8",
|
||||
"title": "Multichain RN proxy registry + USDC/USDT support",
|
||||
"description": "Probe and persist RN ERC20FeeProxy addresses on BSC/Arb/ETH/Polygon/Base, add USDC + USDT token entries with correct decimals per chain, and surface an admin networks page. Include the USDT-mainnet approve(0) reset quirk in the frontend approve step.",
|
||||
"details": "See PRD - Wallet, Multichain, Confirmations, AML, Trezor.md §2. Tasks: new backend/scripts/probe-rn-chains.ts that walks each chain in supported-chains.json and verifies the canonical 0x0DfbEe143b42B41eFC5A6F87bFD1fFC78c2f0aC9 proxy is the real RN proxy via a known view fn (CREATE2 is deterministic, but verify); promote backend/src/services/payment/requestNetwork/tokens.ts to load from JSON + admin override; add USDT entries on all 5 chains (BSC USDT 18-dec quirk, mainnet/Arb/Polygon/Base USDT 6-dec); buildInHouseCheckoutBlock returns reason='unsupported_chain:<id>' for unknowns; new admin route GET /api/admin/rn/networks + frontend page /dashboard/admin/networks rendering the registry with per-row 'probe again'. Frontend approve flow: if buyer is on Ethereum mainnet AND token is USDT AND current allowance > 0, do approve(spender, 0) first then approve(spender, amount). Acceptance: probe succeeds on at least BSC/Arb/Polygon/ETH/Base; one paid probe on BSC USDT end-to-end; mainnet USDT approve(0) reset works; admin page reflects registry. Dependencies: none — runs in parallel with #9. This is task #8 in the PRD.",
|
||||
@@ -693,7 +694,7 @@
|
||||
"subtasks": []
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"id": "9",
|
||||
"title": "Per-chain confirmation thresholds + admin UI",
|
||||
"description": "Make TransactionSafetyProvider's confirmation threshold tunable at runtime per chain via admin UI, with an awaiting-confirmation payments view that shows live confirmations vs threshold.",
|
||||
"details": "See PRD - Wallet, Multichain, Confirmations, AML, Trezor.md §3. Today TRANSACTION_SAFETY_MIN_CONFIRMATIONS is a global env var, default 12, baked in until redeploy. Move to runtime config: new Setting docs keyed 'confirmation_threshold:<chainId>' or extend existing model; cache reads in transactionSafetyProvider.ts for 30s; GET/PATCH /api/admin/settings/confirmation-thresholds (auth: admin); new admin page /dashboard/admin/confirmation-thresholds (table: chain, current, recommended default, edit-in-place with confirm dialog, audit log of changes); new admin page /dashboard/admin/payments/awaiting-confirmation (payments where escrowState !== 'funded' AND metadata.transactionSafety.lastCheck.status === 'pending'; for each show tx hash linked to explorer, current confirmations via 12s poll on BSC, threshold, ETA). Acceptance: admin lowers BSC threshold from 12 to 3 on dev, next webhook honors new value within 30s; awaiting-confirmation table updates live; audit log records every change. Non-goals: per-asset, per-seller thresholds. Dependencies: none. This is task #9 in the PRD.",
|
||||
@@ -704,7 +705,7 @@
|
||||
"subtasks": []
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"id": "10",
|
||||
"title": "Optional AML screening on incoming payments (seller-paid)",
|
||||
"description": "Turn the existing aml_screening placeholder in TransactionSafetyProvider into a real Chainalysis (or equivalent) Address Screening call that the seller opts into per-offer and pays the per-check cost for.",
|
||||
"details": "See PRD - Wallet, Multichain, Confirmations, AML, Trezor.md §4. Default provider recommendation: Chainalysis Address Screening (cheapest, simplest). Files: new backend/src/services/payment/safety/amlProvider.ts interface + chainalysisProvider.ts impl behind env TRANSACTION_SAFETY_AML_PROVIDER=chainalysis with API_KEY in KMS; transactionSafetyProvider's evaluateAmlPlaceholder() becomes real, persists raw provider response on Payment.metadata.amlResult; Offer schema add requireAmlCheck + amlBlockOnFailure booleans; offer-edit UI toggle 'Require AML on incoming payments ($X per payment, paid by you)'; admin global config UI for provider selection + API key rotation + per-chain enabled flag; cost accounting: deduct per-check cost from seller's escrow on completion as a separate ledger line item, surfaced on payment-details. Open questions before code: pick provider (Chainalysis vs TRM vs Elliptic — need 1-page comparison of cost/latency/coverage); failure mode (fail-closed only when seller opted in AND amlBlockOnFailure=true, else warn/log); cost batching cadence. Acceptance: seller toggles AML on an offer; incoming payment triggers a real Chainalysis call; sanctions verdict blocks the safety gate; clean verdict passes; seller's settled amount reduced by check cost; admin can rotate API key without redeploy; provider-down + amlBlockOnFailure=true keeps payment pending with provider_unavailable reason. Dependencies: none. This is task #10 in the PRD.",
|
||||
@@ -715,7 +716,7 @@
|
||||
"subtasks": []
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"id": "11",
|
||||
"title": "Trezor signing for admin actions (release/refund/sweep)",
|
||||
"description": "Replace the hot-key admin signing flow with a WebUSB-based Trezor flow so the backend never holds a private key. All admin-side txes are built backend, signed via Trezor in the browser, broadcast from the browser.",
|
||||
"details": "See PRD - Wallet, Multichain, Confirmations, AML, Trezor.md §5. Lib: @trezor/connect-web (WebUSB; Chromium-only — Firefox users need Trezor Bridge native helper). Files: new frontend/src/web3/trezor/trezorConnector.ts wrapping @trezor/connect-web; existing admin actions (release/refund/sweep when #7 lands) get a 'Sign with Trezor' button that flows: POST /api/admin/actions/build-tx → returns unsigned tx bytes → send to Trezor → sign → wagmi sendTransaction broadcasts → POST /api/admin/actions/confirm-tx with hash; admin settings page to register Trezor address(es) (backend rejects signatures from unauthorized devices); audit log on every Trezor-signed action; break-glass hot-key path requires explicit admin toggle, expires after 1h, fires Telegram alarm. Open questions: m-of-n multi-admin signing — default single-signer for v1; Trezor One vs Model T — lib abstracts; fallback when Trezor unavailable — break-glass with alarm. Acceptance: admin registers Trezor address; release flow uses Trezor end-to-end; backend rejects signatures from unregistered devices; audit log captures admin user + Trezor addr + tx hash + before/after escrow state; break-glass works and alarms. Non-goals: mobile Trezor flow, buyer-side Trezor (buyer uses wagmi injected). Dependencies: task #7 (ephemeral wallets) for the sweep step — but task #11 can ship the release/refund flows first. This is task #11 in the PRD.",
|
||||
@@ -728,15 +729,12 @@
|
||||
],
|
||||
"metadata": {
|
||||
"version": "1.0.0",
|
||||
"lastModified": "2026-05-28T07:34:40.369Z",
|
||||
"taskCount": 6,
|
||||
"lastModified": "2026-05-28T11:51:34.115Z",
|
||||
"taskCount": 11,
|
||||
"completedCount": 5,
|
||||
"tags": [
|
||||
"master"
|
||||
],
|
||||
"created": "2026-05-28T11:47:32.273Z",
|
||||
"description": "Tasks for master context",
|
||||
"updated": "2026-05-28T11:48:22.144Z"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user