Files
suaveplan/openspec/changes/enterprise-react-crypto/tasks.md
2026-05-27 23:29:53 +01:00

4.5 KiB

Tasks: enterprise-react-crypto

Change ID: enterprise-react-crypto Package: @suaveplan/react-crypto Target path: react/auth/react-crypto Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/crypto, @suaveplan/crypto-browser, @suaveplan/react-translate


0. Pre-flight (non-negotiable)

  • 0.1 Confirm clean working tree (git status reports nothing) and no in-flight worktrees with uncommitted work (git worktree list then git status in each)
  • 0.2 If any worktrees exist under .claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
  • 0.3 Confirm the package set in MANIFEST.md matches find packages -maxdepth 3 -name package.json count. Drift here means a prior change archived without regenerating the manifest.

1. Scaffold

  • Create directory tree per proposal layout.
  • Write package.json at 0.1.0 with "sideEffects": false, exports map.
  • Dependencies: @suaveplan/error workspace:^, @suaveplan/crypto workspace:^, @suaveplan/crypto-browser workspace:^, @suaveplan/react-translate workspace:^, zod catalog:forms, @opentelemetry/api catalog:observability, tslib catalog:build.
  • Write tsconfig.json, vitest.config.ts, scripts.

2. Error codes and types

  • Define WalletError extending SuaveplanError; codes: WALLET_CONNECT_FAILED, WALLET_NOT_CONNECTED, WALLET_SIGN_FAILED, WALLET_NETWORK_ERROR.
  • Define WalletProvider interface (injectable): connect(), disconnect(), getAddress(), getBalance(), getNetwork(), switchNetwork(chainId), sendTransaction(tx), signMessage(msg).
  • Define Network, TokenBalance, Transaction, TransactionDirection, TransactionStatus, WalletInfo, WalletStatus.
  • Write Zod schemas for Network, Transaction.

3. WalletProvider adapters

  • MetaMaskAdapter — wraps window.ethereum EIP-1193 provider.
  • WalletConnectAdapter — wraps injected WalletConnectProvider.
  • Both implement WalletProvider interface.
  • Write tests using DI (inject mock window.ethereum) + md.

4. EVM utils

  • explorerUrl(network, txHash), formatAddress(addr, length?), formatBalance(wei, decimals?), isValidEvmAddress(addr): boolean, networkDisplayName(chainId): string.
  • Write evm-utils.test.ts (all functions, edge cases) + md.

5. Hook — useWallet

  • Accepts provider: WalletProvider + autoConnect?: boolean.
  • State: address, balance, network, status: WalletStatus, transactions.
  • connect() — calls provider.connect(); throws WalletError(WALLET_CONNECT_FAILED) on failure. OTel wallet.connect span.
  • disconnect() — calls provider.disconnect().
  • switchNetwork(chainId) — calls provider.switchNetwork(); throws WalletError(WALLET_NETWORK_ERROR) on failure.
  • sendTransaction(tx) — throws WalletError(WALLET_NOT_CONNECTED) if not connected. OTel wallet.send_transaction span.
  • signMessage(msg) — throws WalletError(WALLET_SIGN_FAILED) on error. OTel wallet.sign span.
  • Write use-wallet.test.ts (≤500 lines): connect, disconnect, autoConnect, switchNetwork, sendTransaction, signMessage, all error cases. DI injected mock WalletProvider. { timeout: 10000 }.
  • Write use-wallet.stories.tsx: connected, disconnected, loading, wrong-network, playground.
  • Write use-wallet.md.

6. Components

WalletConnect

  • Connect/disconnect button; shows address when connected.
  • Write test, stories, md.

AddressDisplay

  • Shortened address with copy-to-clipboard. Write test, stories, md.

BalanceDisplay

  • Token balance with symbol. Write test, stories, md.

TransactionList

  • Paginated list of Transaction items with status badges, explorer links. Write test, stories, md.

7. E2E

  • e2e/wallet.spec.ts — Playwright with injected mock provider:
    • Click "Connect" → address displayed.
    • Call signMessage('hello') → mock returns signature, displayed.

8. Verify and publish

  • bunx turbo lint typecheck test --filter=@suaveplan/react-crypto — green.
  • bunx turbo test:coverage --filter=@suaveplan/react-crypto — 100%.
  • bun scripts/publish.ts --package @suaveplan/react-crypto.
  • Archive change folder.