Conecta wallets, lee contratos y envía transacciones desde el navegador
transfer("0xAbc...", 1000000000000000000n) en los bytes exactos que el EVM entiende. Provider = solo lectura (como consultar un libro). Signer = lectura + escritura (como firmar un contrato notarial). wagmi v2 + RainbowKit añaden la capa React con hooks como useReadContract, useWriteContract, y la UI de conexión de wallets lista para producción.
import { BrowserProvider } from "ethers"; // Solicitar acceso a MetaMask const provider = new BrowserProvider(window.ethereum); // Obtener signer (usuario conectado) const signer = await provider.getSigner(); const address = await signer.getAddress(); const balance = await provider.getBalance(address); const ethBalance = ethers.formatEther(balance); // Detectar red const network = await provider.getNetwork(); console.log(network.chainId); // 1n = Mainnet, 11155111n = Sepolia
import { Contract, JsonRpcProvider } from "ethers"; // ABI mínimo para leer ERC-20 const ERC20_ABI = [ "function name() view returns (string)", "function symbol() view returns (string)", "function decimals() view returns (uint8)", "function totalSupply() view returns (uint256)", "function balanceOf(address) view returns (uint256)", ]; // Provider público (sin wallet) const provider = new JsonRpcProvider( "https://eth-mainnet.g.alchemy.com/v2/KEY" ); const usdc = new Contract(USDC_ADDR, ERC20_ABI, provider); const name = await usdc.name(); // "USD Coin" const supply = await usdc.totalSupply(); const formatted = ethers.formatUnits(supply, 6);
const ERC20_WRITE_ABI = [ "function transfer(address to, uint256 amount) returns (bool)", "function approve(address spender, uint256 amount) returns (bool)", "event Transfer(address indexed from, address indexed to, uint256 value)", ]; const tokenWithSigner = new Contract(TOKEN_ADDR, ERC20_WRITE_ABI, signer); // Paso 1: Estimar gas (opcional, ethers lo hace automático) const gasEst = await tokenWithSigner.transfer.estimateGas( recipientAddr, ethers.parseUnits("100", 18) ); // Paso 2: Enviar tx y esperar confirmación const tx = await tokenWithSigner.transfer( recipientAddr, ethers.parseUnits("100", 18) ); const receipt = await tx.wait(1); // 1 confirmación console.log("Tx hash:", receipt.hash);
// wagmi.config.ts import { createConfig, http } from "wagmi"; import { mainnet, sepolia } from "wagmi/chains"; import { RainbowKitProvider, getDefaultConfig } from "@rainbow-me/rainbowkit"; export const config = getDefaultConfig({ appName: "My DeFi App", projectId: "YOUR_WALLETCONNECT_ID", chains: [mainnet, sepolia], transports: { [mainnet.id]: http(), [sepolia.id]: http() }, }); // BalanceCard.tsx ” hook para leer contrato import { useReadContract, useAccount } from "wagmi"; import { formatUnits } from "viem"; function BalanceCard() { const { address } = useAccount(); const { data } = useReadContract({ address: "0xA0b86...", // USDC abi: ERC20_ABI, functionName: "balanceOf", args: [address], }); return <div>USDC: {formatUnits(data ?? 0n, 6)}</div>; } // WriteButton.tsx ” enviar transacción import { useWriteContract, useWaitForTransactionReceipt } from "wagmi"; function TransferButton() { const { writeContractAsync } = useWriteContract(); const send = async () => { const hash = await writeContractAsync({ address: TOKEN_ADDR, abi: ERC20_ABI, functionName: "transfer", args: [recipient, parseUnits("100", 18)], }); return hash; }; return <button onClick={send}>Transferir</button>; }