Hey is a decentralized and permissionless social media app built with Lens Protocol 🌿

refactor: integrate useHandleWrongNetwork hook in Trade component for network validation

yoginth.com e8d1b9db 9639fee0

verified
+74 -106
+74 -106
apps/web/src/components/Account/CreatorCoin/Trade.tsx
··· 19 19 import { base } from "viem/chains"; 20 20 import { useAccount, useWalletClient } from "wagmi"; 21 21 import { Button, Image, Input, Tabs, Tooltip } from "@/components/Shared/UI"; 22 + import useHandleWrongNetwork from "@/hooks/useHandleWrongNetwork"; 22 23 23 24 interface TradeModalProps { 24 25 coin: NonNullable<GetCoinResponse["zora20Token"]>; ··· 34 35 () => createPublicClient({ chain: base, transport: http() }), 35 36 [] 36 37 ); 38 + const handleWrongNetwork = useHandleWrongNetwork({ chainId: base.id }); 37 39 38 40 const [mode, setMode] = useState<Mode>("buy"); 39 - const [amount, setAmount] = useState(""); // input in human units 41 + const [amount, setAmount] = useState(""); 40 42 const [loading, setLoading] = useState(false); 41 43 const [ethBalance, setEthBalance] = useState<bigint>(0n); 42 44 const [tokenBalance, setTokenBalance] = useState<bigint>(0n); ··· 94 96 slippage: 0.01 95 97 }; 96 98 } 99 + 97 100 return { 98 101 amountIn: parseUnits(amount, tokenDecimals), 99 102 buy: { type: "eth" }, ··· 103 106 }; 104 107 }; 105 108 106 - const ensureBaseNetwork = async () => { 107 - try { 108 - const eth: any = (window as any).ethereum; 109 - if (!eth?.request) return; 110 - await eth.request({ 111 - method: "wallet_switchEthereumChain", 112 - params: [{ chainId: "0x2105" }] 113 - }); 114 - } catch (error: any) { 115 - // Chain not added 116 - if (error?.code === 4902) { 117 - const eth: any = (window as any).ethereum; 118 - try { 119 - await eth.request({ 120 - method: "wallet_addEthereumChain", 121 - params: [ 122 - { 123 - blockExplorerUrls: ["https://basescan.org"], 124 - chainId: "0x2105", 125 - chainName: "Base", 126 - nativeCurrency: { decimals: 18, name: "Ether", symbol: "ETH" }, 127 - rpcUrls: ["https://mainnet.base.org"] 128 - } 129 - ] 130 - }); 131 - } catch {} 132 - } 133 - } 134 - }; 135 - 136 109 const handleSubmit = async () => { 137 - if (!walletClient) { 110 + console.log(walletClient); 111 + if (!walletClient || !publicClient || !address) { 138 112 return toast.error("Connect a wallet to trade"); 139 113 } 114 + 140 115 const params = makeParams(); 141 116 if (!params) return; 142 117 try { 143 118 setLoading(true); 144 - await ensureBaseNetwork(); 119 + await handleWrongNetwork(); 145 120 const receipt = await tradeCoin({ 146 121 account: walletClient.account, 147 122 publicClient, ··· 159 134 } 160 135 }; 161 136 162 - // Update estimate when inputs change 163 137 useEffect(() => { 164 138 let cancelled = false; 165 139 const run = async () => { ··· 209 183 210 184 return ( 211 185 <div className="p-5"> 212 - {address ? ( 213 - <> 214 - {/* Buy/Sell tabs */} 215 - <Tabs 216 - active={mode} 217 - className="mb-4" 218 - layoutId="trade-mode" 219 - setActive={(t) => setMode(t as Mode)} 220 - tabs={[ 221 - { name: "Buy", type: "buy" }, 222 - { name: "Sell", type: "sell" } 223 - ]} 224 - /> 225 - 226 - <div className="relative mb-2"> 227 - <Input 228 - className="w-full rounded-md border border-gray-300 bg-transparent py-2 pr-3 text-base outline-none focus:border-gray-400 dark:border-gray-700 dark:focus:border-gray-600" 229 - inputMode="decimal" 230 - label="Amount" 231 - onChange={(e) => setAmount(e.target.value)} 232 - placeholder={mode === "buy" ? "0.01" : "0"} 233 - prefix={ 234 - mode === "buy" ? ( 235 - "ETH" 236 - ) : ( 237 - <Tooltip content={`$${symbol}`}> 238 - <Image 239 - alt={coin.name} 240 - className="size-5 rounded-full" 241 - height={20} 242 - src={coin.mediaContent?.previewImage?.small} 243 - width={20} 244 - /> 245 - </Tooltip> 246 - ) 247 - } 248 - value={amount} 249 - /> 250 - </div> 251 - <div className="mb-3 flex items-center justify-between text-gray-500 text-xs dark:text-gray-400"> 252 - <div> 253 - Estimated amount:{" "} 254 - {estimatedOut 255 - ? mode === "buy" 256 - ? `${Number( 257 - formatUnits(BigInt(estimatedOut), tokenDecimals) 258 - ).toFixed(6)} ${symbol}` 259 - : `${Number(formatEther(BigInt(estimatedOut))).toFixed(6)} ETH` 260 - : "-"} 261 - </div> 262 - <div>{balanceLabel}</div> 263 - </div> 186 + <Tabs 187 + active={mode} 188 + className="mb-4" 189 + layoutId="trade-mode" 190 + setActive={(t) => setMode(t as Mode)} 191 + tabs={[ 192 + { name: "Buy", type: "buy" }, 193 + { name: "Sell", type: "sell" } 194 + ]} 195 + /> 264 196 265 - <div className="mb-3 grid grid-cols-4 gap-2"> 266 - {[25, 50, 75].map((p) => ( 267 - <Button key={p} onClick={() => setPercentAmount(p)} outline> 268 - {p}% 269 - </Button> 270 - ))} 271 - <Button onClick={() => setPercentAmount(100)} outline> 272 - Max 273 - </Button> 274 - </div> 197 + <div className="relative mb-2"> 198 + <Input 199 + inputMode="decimal" 200 + label="Amount" 201 + onChange={(e) => setAmount(e.target.value)} 202 + placeholder={mode === "buy" ? "0.01" : "0"} 203 + prefix={ 204 + mode === "buy" ? ( 205 + "ETH" 206 + ) : ( 207 + <Tooltip content={`$${symbol}`}> 208 + <Image 209 + alt={coin.name} 210 + className="size-5 rounded-full" 211 + height={20} 212 + src={coin.mediaContent?.previewImage?.small} 213 + width={20} 214 + /> 215 + </Tooltip> 216 + ) 217 + } 218 + value={amount} 219 + /> 220 + </div> 221 + <div className="mb-3 flex items-center justify-between text-gray-500 text-xs dark:text-gray-400"> 222 + <div> 223 + Estimated amount:{" "} 224 + {estimatedOut 225 + ? mode === "buy" 226 + ? `${Number( 227 + formatUnits(BigInt(estimatedOut), tokenDecimals) 228 + ).toFixed(6)}` 229 + : `${Number(formatEther(BigInt(estimatedOut))).toFixed(6)} ETH` 230 + : "-"} 231 + </div> 232 + <div>{balanceLabel}</div> 233 + </div> 275 234 276 - <Button 277 - className="mt-4 w-full" 278 - disabled={!amount || !address} 279 - loading={loading} 280 - onClick={handleSubmit} 281 - size="lg" 282 - > 283 - {mode === "buy" ? "Buy" : "Sell"} 235 + <div className="mb-3 grid grid-cols-4 gap-2"> 236 + {[25, 50, 75].map((p) => ( 237 + <Button key={p} onClick={() => setPercentAmount(p)} outline> 238 + {p}% 284 239 </Button> 285 - </> 286 - ) : null} 240 + ))} 241 + <Button onClick={() => setPercentAmount(100)} outline> 242 + Max 243 + </Button> 244 + </div> 245 + 246 + <Button 247 + className="mt-4 w-full" 248 + disabled={!amount || !address} 249 + loading={loading} 250 + onClick={handleSubmit} 251 + size="lg" 252 + > 253 + {mode === "buy" ? "Buy" : "Sell"} 254 + </Button> 287 255 </div> 288 256 ); 289 257 };