4.5 KiB
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 statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin 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.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Scaffold
- Create directory tree per proposal layout.
- Write
package.jsonat0.1.0with"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
WalletErrorextendingSuaveplanError; codes:WALLET_CONNECT_FAILED,WALLET_NOT_CONNECTED,WALLET_SIGN_FAILED,WALLET_NETWORK_ERROR. - Define
WalletProviderinterface (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— wrapswindow.ethereumEIP-1193 provider.WalletConnectAdapter— wraps injectedWalletConnectProvider.- Both implement
WalletProviderinterface. - 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()— callsprovider.connect(); throwsWalletError(WALLET_CONNECT_FAILED)on failure. OTelwallet.connectspan.disconnect()— callsprovider.disconnect().switchNetwork(chainId)— callsprovider.switchNetwork(); throwsWalletError(WALLET_NETWORK_ERROR)on failure.sendTransaction(tx)— throwsWalletError(WALLET_NOT_CONNECTED)if not connected. OTelwallet.send_transactionspan.signMessage(msg)— throwsWalletError(WALLET_SIGN_FAILED)on error. OTelwallet.signspan.- Write
use-wallet.test.ts(≤500 lines): connect, disconnect, autoConnect, switchNetwork, sendTransaction, signMessage, all error cases. DI injected mockWalletProvider.{ 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
Transactionitems 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.