# /cook:frontend - React Frontend Generation

**Agent:** `frontend`

Generate React frontend with wallet integration for Movement blockchain.

**IMPORTANT**: Delegate to `frontend` agent.

## References
- [TypeScript SDK](https://docs.movementnetwork.xyz/devs/interactonchain/tsSdk)
- [Wallet Adapter](https://docs.movementnetwork.xyz/devs/interactonchain/wallet-adapter/connect_wallet)
- [useWallet Hook](https://docs.movementnetwork.xyz/devs/interactonchain/wallet-adapter/useWallet/ConnectWallet)
- [Sign & Submit](https://docs.movementnetwork.xyz/devs/interactonchain/wallet-adapter/useWallet/signAndSubmitTx)

## Movement Network Configuration

**Chain IDs:**
- Mainnet: `126`
- Testnet: `250`

**RPC Endpoints:**
- Mainnet: `https://mainnet.movementnetwork.xyz/v1`
- Testnet: `https://full.testnet.movementinfra.xyz/v1`

**Explorer:**
- `https://explorer.movementnetwork.xyz/txn/{txHash}?network={mainnet|testnet}`

## Workflow

### Step 1: Analyze Requirements
From the plan or contracts, identify:
- UI components needed
- User interactions
- Contract functions to call (entry functions vs view functions)
- Data display needs

### Step 2: Generate package.json
```json
{
  "name": "{project_name}-frontend",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "test": "vitest"
  },
  "dependencies": {
    "@aptos-labs/ts-sdk": "^1.33.1",
    "@aptos-labs/wallet-adapter-react": "^3.7.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.0",
    "@types/react-dom": "^18.2.0",
    "@vitejs/plugin-react": "^4.2.0",
    "typescript": "^5.3.0",
    "vite": "^5.0.0",
    "vitest": "^1.0.0"
  }
}
```

### Step 3: Generate Environment Configuration
`frontend/.env`:
```bash
VITE_MODULE_ADDRESS=<YOUR_CONTRACT_ADDRESS>
VITE_NETWORK=testnet
VITE_NODE_URL=https://full.testnet.movementinfra.xyz/v1
```

### Step 4: Generate Wallet Provider
`frontend/src/contexts/WalletProvider.tsx`:
```tsx
import { AptosWalletAdapterProvider } from "@aptos-labs/wallet-adapter-react";
import { AptosConfig, Network } from "@aptos-labs/ts-sdk";
import { PropsWithChildren } from "react";

export function WalletProvider({ children }: PropsWithChildren) {
  // Movement Network configuration
  const config = new AptosConfig({
    network: Network.CUSTOM,
    fullnode: import.meta.env.VITE_NODE_URL || 'https://full.testnet.movementinfra.xyz/v1',
  });

  return (
    <AptosWalletAdapterProvider
      plugins={[]}
      autoConnect={true}
      dappConfig={config}
      onError={(error) => {
        console.error("Wallet error:", error);
      }}
    >
      {children}
    </AptosWalletAdapterProvider>
  );
}
```

### Step 5: Generate Custom Hooks
`frontend/src/hooks/useContract.ts`:
```tsx
import { useWallet } from "@aptos-labs/wallet-adapter-react";
import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk";

const MODULE_ADDRESS = import.meta.env.VITE_MODULE_ADDRESS;
const MODULE_NAME = "{module_name}";

// Create Aptos client for Movement Network
const aptosConfig = new AptosConfig({
  network: Network.CUSTOM,
  fullnode: import.meta.env.VITE_NODE_URL || "https://full.testnet.movementinfra.xyz/v1",
});
const aptos = new Aptos(aptosConfig);

export function useContract() {
  const { signAndSubmitTransaction, account, connected } = useWallet();

  // Call entry function (modifies state, requires signing)
  const callFunction = async (functionName: string, args: any[]) => {
    if (!connected || !account) throw new Error("Wallet not connected");

    const response = await signAndSubmitTransaction({
      data: {
        function: `${MODULE_ADDRESS}::${MODULE_NAME}::${functionName}`,
        functionArguments: args,
      },
    });

    // Wait for transaction confirmation
    const result = await aptos.waitForTransaction({
      transactionHash: response.hash
    });

    return result;
  };

  // Call view function (read-only, no signing required)
  const viewFunction = async (functionName: string, args: any[]) => {
    return await aptos.view({
      payload: {
        function: `${MODULE_ADDRESS}::${MODULE_NAME}::${functionName}`,
        functionArguments: args,
      },
    });
  };

  return { callFunction, viewFunction, account, connected, aptos };
}
```

### Step 6: Generate Wallet Connect Component
`frontend/src/components/WalletConnect.tsx`:
```tsx
import { useWallet } from "@aptos-labs/wallet-adapter-react";

export function WalletConnect() {
  const {
    connect,
    disconnect,
    account,
    connected,
    wallets,
    isLoading
  } = useWallet();

  if (isLoading) {
    return <button disabled>Loading...</button>;
  }

  if (connected && account) {
    return (
      <div className="wallet-connected">
        <span className="address">
          {account.address.slice(0, 6)}...{account.address.slice(-4)}
        </span>
        <button onClick={disconnect}>Disconnect</button>
      </div>
    );
  }

  return (
    <div className="wallet-select">
      {wallets?.filter(w => w.readyState === 'Installed').map((wallet) => (
        <button
          key={wallet.name}
          onClick={() => connect(wallet.name)}
        >
          Connect {wallet.name}
        </button>
      ))}
      {wallets?.filter(w => w.readyState === 'Installed').length === 0 && (
        <p>No wallets detected. Please install a Movement-compatible wallet.</p>
      )}
    </div>
  );
}
```

### Step 7: Generate Main App
`frontend/src/App.tsx`:
```tsx
import { WalletProvider } from "./contexts/WalletProvider";
import { WalletConnect } from "./components/WalletConnect";

export default function App() {
  return (
    <WalletProvider>
      <div className="app">
        <header>
          <h1>{Project Name}</h1>
          <WalletConnect />
        </header>
        <main>
          {/* Main content - add your components here */}
        </main>
      </div>
    </WalletProvider>
  );
}
```

### Step 8: Generate Vite Config
`frontend/vite.config.ts`:
```ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  define: {
    'process.env': {},
  },
});
```

### Step 9: Generate TypeScript Config
`frontend/tsconfig.json`:
```json
{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "skipLibCheck": true,
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src"]
}
```

## Common Patterns

### Reading Contract State
```tsx
const { viewFunction } = useContract();

// Read a value from contract
const fetchData = async () => {
  const [result] = await viewFunction("get_value", []);
  setValue(Number(result));
};
```

### Writing to Contract
```tsx
const { callFunction, connected } = useContract();

const handleSubmit = async () => {
  if (!connected) return;

  try {
    const result = await callFunction("set_value", [newValue]);
    console.log("Transaction successful:", result.hash);
  } catch (error) {
    console.error("Transaction failed:", error);
  }
};
```

### Transaction Status
```tsx
const [txStatus, setTxStatus] = useState<'idle' | 'pending' | 'success' | 'error'>('idle');

const handleTransaction = async () => {
  setTxStatus('pending');
  try {
    await callFunction("some_function", []);
    setTxStatus('success');
  } catch {
    setTxStatus('error');
  }
};
```

## Output Summary
```markdown
# 🎨 Frontend Generated

## Files Created
- src/App.tsx
- src/contexts/WalletProvider.tsx
- src/hooks/useContract.ts
- src/components/WalletConnect.tsx
- src/components/{additional components}
- vite.config.ts
- tsconfig.json
- .env

## Next Steps
1. Run `npm install` to install dependencies
2. Update `.env` with your contract address
3. Run `npm run dev` to start development server
4. Install a Movement-compatible wallet (Razor, Nightly, etc.)
5. Connect wallet and test interactions
```
