Documentation Index
Fetch the complete documentation index at: https://docs.teqoin.io/llms.txt
Use this file to discover all available pages before exploring further.
Build a dapp
This tutorial walks through a small React app that connects to TeQoin, reads a contract value, and sends a transaction.
What you will build
You will build a React app that:
- Connects to a wallet
- Checks that the user is on TeQoin
- Reads
number() from a deployed Counter
- Sends
increment()
Step 1: Create the app
npm create vite@latest teqoin-counter -- --template react
cd teqoin-counter
npm install
npm install ethers
Step 2: Add contract details
Create src/config.js:
export const TEQOIN_CHAIN_ID = 420377;
export const TEQOIN_CHAIN_HEX = '0x66A19';
export const TEQOIN_RPC_URL = 'https://rpc.teqoin.io';
export const COUNTER_ADDRESS = '0xYourContractAddress';
export const COUNTER_ABI = [
'function number() view returns (uint256)',
'function increment()',
];
Step 3: Build the app
Replace src/App.jsx:
import { useState } from 'react';
import { ethers } from 'ethers';
import {
COUNTER_ABI,
COUNTER_ADDRESS,
TEQOIN_CHAIN_HEX,
} from './config';
export default function App() {
const [account, setAccount] = useState('');
const [number, setNumber] = useState('');
const [status, setStatus] = useState('Disconnected');
async function ensureTeQoin() {
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: TEQOIN_CHAIN_HEX }],
});
}
async function connectWallet() {
if (!window.ethereum) {
setStatus('Install a wallet first.');
return;
}
const [selected] = await window.ethereum.request({
method: 'eth_requestAccounts',
});
await ensureTeQoin();
setAccount(selected);
setStatus('Wallet connected');
}
async function readCounter() {
const provider = new ethers.BrowserProvider(window.ethereum);
const contract = new ethers.Contract(COUNTER_ADDRESS, COUNTER_ABI, provider);
const value = await contract.number();
setNumber(value.toString());
}
async function incrementCounter() {
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const contract = new ethers.Contract(COUNTER_ADDRESS, COUNTER_ABI, signer);
const tx = await contract.increment();
setStatus(`Pending: ${tx.hash}`);
await tx.wait();
setStatus('Transaction confirmed');
await readCounter();
}
return (
<main style={{ maxWidth: 720, margin: '40px auto', fontFamily: 'sans-serif' }}>
<h1>TeQoin Counter</h1>
<p>{status}</p>
<p>Account: {account || 'Not connected'}</p>
<p>Current number: {number || '-'}</p>
<button onClick={connectWallet}>Connect wallet</button>
<button onClick={readCounter} style={{ marginLeft: 12 }}>
Read
</button>
<button onClick={incrementCounter} style={{ marginLeft: 12 }}>
Increment
</button>
</main>
);
}
Step 4: Start the app
Open the local URL from Vite, connect your wallet, and test the read and write buttons.
Common fixes
Wallet switch fails
If wallet_switchEthereumChain fails because TeQoin is not added yet, first follow /tutorials/integrate-wallet.
Contract calls revert
Check:
- The contract address is correct
- The ABI matches the deployed contract
- Your wallet is on chain
420377
Next steps
- Add loading and error states
- Store the contract address in an environment variable
- Add event listening with
provider.on()
- Move to Wagmi or Viem if you want a larger React app