Skip to content

Fix/pr278 clean onto master#281

Open
fanhousanbu wants to merge 8 commits intomasterfrom
fix/pr278-clean-onto-master
Open

Fix/pr278 clean onto master#281
fanhousanbu wants to merge 8 commits intomasterfrom
fix/pr278-clean-onto-master

Conversation

@fanhousanbu
Copy link
Copy Markdown
Collaborator

@fanhousanbu fanhousanbu commented Apr 7, 2026

Summary

Clean rebase onto master — supersedes #278 and #279. Excludes SDK work already merged via #237/#250/#251/#272.

4 commits, ~6000 additions:

Commit Content
feat(tasks): add MyTask M6-M8 task market UI TaskContext, task list/create/detail, TaskEscrowV2 ABI, contract config
feat(recovery): add social recovery UI and guardian-sign page /recovery page, guardian-sign update, E2E test docs
feat(tasks): Sprint 1 M9 — ERC-20 balance, EIP-2612 permit, x402 receipts T01 balance display, T02 createTaskWithPermit, T06 receipt scaffolding
feat(tasks): Sprint 1 T05/T06 — x402 payment flow + receipt display lib/x402-client.ts, 402→sign→retry flow, auto linkReceipt, receipt detail UI

Closes

Supersedes #278 and #279 (both can be closed after this merges)

Test plan

M6-M8 Task market:

  • Configure MetaMask with Anvil (chainId 31337, RPC http://127.0.0.1:8545)
  • Account A: /tasks → Post Task → Approve USDC → Create
  • Account B: Claim Task → Submit Work
  • Account A: Approve & Pay Out

Sprint 1 x402:

  • Set NEXT_PUBLIC_X402_API_URL=http://localhost:3401 in .env.local
  • Start API server: cd MyTask/packages/api-server && pnpm start
  • Create task → MetaMask: x402 sign → permit sign → tx → receipt linked
  • Task detail shows receipt ID, payer, timestamp
  • Remove NEXT_PUBLIC_X402_API_URL → task still creates (graceful degradation)

Social recovery:

  • /recovery page: propose + execute social recovery flow

@fanhousanbu fanhousanbu requested a review from jhfnetboy as a code owner April 7, 2026 07:31
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copy link
Copy Markdown
Member

@jhfnetboy jhfnetboy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

代码审查 — PR #281 Fix/pr278 clean onto master

审查范围:Task Market UI (M6-M9)、Social Recovery、x402 payment flow、MetaMask guardian signing


🔴 严重问题(必须修复)

1. myAddress 角色判断不一致(功能性 Bug)

tasks/page.tsxTaskCard 使用智能账户地址判断归属:

const myAddress = data.account?.address?.toLowerCase(); // YAA 智能账户

tasks/[taskId]/page.tsx 用 EOA 地址判断角色:

const myAddress = (eoaAddress || (data.account?.address ?? "")).toLowerCase();

合约存储的是 EOA 地址,所以任务列表页面 "(you)" 标签会始终不显示,或在 EOA = 智能账户时误显示。需统一用 EOA。


2. guardian-signacceptanceHash 校验被删除(安全问题)

原 passkey 路径有 if (!acceptanceHash) 守卫,这次重构时被删掉了。MetaMask 路径也没有这个守卫。isValidParams 仅控制按钮渲染,不阻止函数内部执行。URL 参数缺失时用户会对空 hash 签名,这是一个安全漏洞。


🟡 中等问题(建议本 PR 内修复)

3. EIP-2612 permit domain version 写死为 "2"

tasks/create/page.tsxversion: "2" 是硬编码,但 task-config.ts 已暴露 REWARD_TOKEN_VERSION 环境变量。USDC 在不同网络 version 不同,应使用配置值。

4. getPublicClient() 重复定义

task-config.ts 中已导出 getPublicClient(),但 TaskContext.tsx 又定义了同名本地函数且从未导入 task-config 版本。请删除本地版本,统一使用导出版本。

5. 任务加载只扫描最近 50,000 个区块

const fromBlock = latestBlock > 50000n ? latestBlock - 50000n : 0n;

Sepolia ~12s/块,50,000 块约 7 天。更早的任务对用户不可见,且无分页。建议改用 subgraph 或后端索引。

6. TaskCreated 事件 topic 魔术字符串

topics: ["0xc703eeeb92d845b735c767a95c30a380646ad4c4824a3a100253d4bec0294e9e"],

ABI 任何变动都会静默失效,应用 viem 的 encodeEventTopics 从 ABI 推导。

7. 手动关联 receipt 时同一值传入两个参数

await linkReceipt(task!.taskId, receiptInput.trim(), receiptInput.trim(), walletClient);
//                               ^ receiptId          ^ receiptUri  (同一值)

receiptId 是 bytes32 标识符,receiptUri 是 URI 字符串,两者应该不同。


⚪ 轻微问题(可后续跟进)

8. TaskContext 所有 catch 块静默吞错 — 空 catch 导致链上错误完全不可调试,建议至少 console.error

9. recovery/page.tsx 使用 confirm() — 阻塞浏览器 API,移动端 WebView 可能禁用,应换成 UI 内确认组件。

10. pendingRecovery: any 类型 — 应根据后端响应定义接口类型。

11. Recovery 多 guardian UX 假设同一浏览器 — Guardian 1 发起和 Guardian 2 支持都在同一 session,现实中是两个不同的人,缺少分享通知机制。


总结

级别 数量
🔴 严重(必须修复) 2
🟡 中等(建议修复) 5
⚪ 轻微(可后续跟进) 4

请至少修复两个严重问题(EOA/智能账户角色判断不一致 + acceptanceHash 空签名漏洞)再 merge。

Integrate MyTask task market into YAA frontend under /tasks route.

- Add TaskContext with contract read/write (createTask, acceptTask,
  submitWork, approveWork, finalizeTask, cancelTask)
- Add task list page with All/Open/Mine/Claimed filter tabs and search
- Add create task form with ERC-20 approve + createTask two-step flow
- Add task detail page with role-based action buttons (Community/Taskor)
- Add TaskEscrowV2 ABI and contract config (viem, env-driven chain)
- Add task-types.ts (TaskStatus enum, ParsedTask), date-utils.ts
- Inject TaskProvider in app layout; add Tasks nav (desktop + mobile)
- Upgrade tsconfig target to ES2020 (BigInt literal support)
- Add /recovery page for on-chain social recovery flow (propose + execute)
- Update guardian-sign page for QR-based guardian signature
- Add social recovery E2E test docs and HTML test pages
…ipts

T01: 积分余额展示
- TaskContext 新增 taskTokenBalance / loadTaskTokenBalance
- Dashboard 新增 Task Reward Balance 卡片,实时读取 ERC-20 余额

T02: createTaskWithPermit
- TASK_ESCROW_ABI 补充 createTaskWithPermit / ERC20 nonces / name / permit
- 创建任务时优先走 EIP-2612 permit(单 tx 无需 approve)
- permit 失败自动降级为 approve + createTask

T06: linkReceipt 前端
- ABI 补充 linkReceipt / getTaskReceipts
- TaskContext 新增 getTaskReceipts / linkReceipt
- 任务详情页新增 x402 Receipts 区域:显示已绑定收据,参与方可手动 link
T05 — X402Client integration (lib/x402-client.ts):
- postTaskWithX402: POST /tasks → 402 → sign EIP-3009 → retry → receiptId
- fetchReceiptDetails: GET /receipts/:id for richer display
- Graceful degradation when NEXT_PUBLIC_X402_API_URL not set

T06 — Receipt display & auto-link:
- create/page.tsx: x402 sign → createTaskWithPermit → auto linkReceipt (3-step)
- [taskId]/page.tsx: show payer + timestamp per receipt, fetched from API
- task-config.ts: add X402_API_URL, REWARD_TOKEN_NAME/VERSION, isX402Configured()
- Run prettier on all 11 frontend files (task pages, contexts, lib)
- Remove unused imports: IsPositive, IsNumberString, EnvConfigService, AnalyzeTransactionDto
- Rename catch (error) → catch (_error) in user-nft and user-token services
  where the error variable was not used (per @typescript-eslint/no-unused-vars)
- Reformat guardian-setup.dto.ts with prettier after import cleanup
- Remove unused `data` destructure from useDashboard() call
- Remove unused DEFAULT_REWARD_TOKEN_SYMBOL and getStoredAuth imports
- tasks/page.tsx: use signerAddress (EOA) instead of smart account address
  for "(you)" label; contracts store EOA so the label was never shown
- guardian-sign/page.tsx: add acceptanceHash guard at the top of both
  handleSignWithPasskey and handleSignWithMetaMask to prevent signing
  an empty hash when URL params are missing
@fanhousanbu fanhousanbu force-pushed the fix/pr278-clean-onto-master branch from c8b3876 to c00a793 Compare April 7, 2026 09:23
Copy link
Copy Markdown
Member

@jhfnetboy jhfnetboy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review — 严重问题已修复 ✅,中等问题待处理

感谢快速响应。两个严重问题已正确修复:

  • EOA 角色判断tasks/page.tsx 改用 data.account?.signerAddress — 正确,Account 类型中该字段存在。
  • acceptanceHash 空签名漏洞:在 handleSignWithPasskeyhandleSignWithMetaMask 顶部都加了守卫 — 正确。

以下 5 个中等问题仍未处理,请跟进:


[未修复] permit domain version 仍写死为 "2"

tasks/create/page.tsx:172

version: "2",   // ← 仍然硬编码

REWARD_TOKEN_VERSION 已经 import 进来(第 16 行)并在 x402 path 里用了(第 131 行),但 EIP-2612 permit 的 domain 里忘了替换。改一行即可:

version: REWARD_TOKEN_VERSION,

[未修复] getPublicClient() 在 TaskContext.tsx 中重复定义

TaskContext.tsx:110 有一个本地 getPublicClient(),与 task-config.ts 导出的同名函数完全相同。删掉本地版本,改为:

import { getPublicClient } from "@/lib/contracts/task-config";

[未修复] 任务加载只扫描最近 50,000 个区块

TaskContext.tsx:153

const fromBlock = latestBlock > 50000n ? latestBlock - 50000n : 0n;

Sepolia ~12s/块,50,000 块约 7 天,更早的任务用户不可见。短期可以调大到 200000n,长期建议改用 subgraph 或后端索引。


[未修复] TaskCreated 事件 topic 魔术字符串

TaskContext.tsx:159

topics: ["0xc703eeeb92d845b735c767a95c30a380646ad4c4824a3a100253d4bec0294e9e"],

建议改为:

import { keccak256, toHex, toBytes } from "viem";
// 或直接用 viem 的 parseAbiItem + encodeEventTopics
const topic = keccak256(toBytes("TaskCreated(bytes32,address,address,uint256)"));

这样 ABI 改动时不会静默失效。


[未修复] 手动关联 receipt 同一值传两个参数

tasks/[taskId]/page.tsx:418-421

await linkReceipt(
  task!.taskId,
  receiptInput.trim(),  // receiptId (bytes32)
  receiptInput.trim(),  // receiptUri (URI string) ← 同一值
  walletClient
);

如果用户粘贴的是 receipt URI(字符串),linkReceipt 内部会对它 keccak256 再传给合约;如果粘贴的是已有的 bytes32 id,则 URI 字段应该是别的值。建议将输入框拆为两个字段,或在 UI 上明确说明只接受哪种格式,并在 receiptUri 字段填入有意义的值。


总结

问题 状态
EOA 角色判断 ✅ 已修复
acceptanceHash 空签名 ✅ 已修复
permit version 写死 ❌ 未修复
getPublicClient 重复 ❌ 未修复
50k 块扫描上限 ❌ 未修复
topic 魔术字符串 ❌ 未修复
linkReceipt 双参数 ❌ 未修复

前两个(permit version + getPublicClient 重复)是 1 行的改动,建议顺手修掉再 merge。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants