Web3 Integration Guide
Learn how to integrate Web3 functionality into your Civra applications.
Wallet Connection
Basic Setup
Civra provides built-in wallet connection components:
typescript
import { WalletButton } from '@civra/web3'
export function Header() {
return (
<nav>
<WalletButton />
</nav>
)
}Supported Wallets
- MetaMask
- WalletConnect
- Coinbase Wallet
- Rainbow Wallet
- Trust Wallet
Custom Wallet Integration
typescript
import { useWallet } from '@civra/web3'
export function CustomConnect() {
const { connect, disconnect, address, isConnected } = useWallet()
return (
<div>
{isConnected ? (
<div>
<span>{address}</span>
<button onClick={disconnect}>Disconnect</button>
</div>
) : (
<button onClick={() => connect('metamask')}>
Connect MetaMask
</button>
)}
</div>
)
}Smart Contract Interaction
Reading Contract Data
typescript
import { useContract } from '@civra/web3'
const CONTRACT_ADDRESS = '0x...'
const ABI = [...]
export function TokenBalance() {
const contract = useContract(CONTRACT_ADDRESS, ABI)
const { data: balance } = contract.read.balanceOf(address)
return <div>Balance: {balance}</div>
}Writing to Contracts
typescript
export function MintButton() {
const contract = useContract(CONTRACT_ADDRESS, ABI)
const handleMint = async () => {
try {
const tx = await contract.write.mint({
value: parseEther('0.1')
})
await tx.wait()
console.log('Minted successfully!')
} catch (error) {
console.error('Mint failed:', error)
}
}
return <button onClick={handleMint}>Mint NFT</button>
}Network Management
Detecting Network
typescript
import { useNetwork } from '@civra/web3'
export function NetworkIndicator() {
const { chain } = useNetwork()
return (
<div>
Connected to: {chain?.name}
</div>
)
}Switching Networks
typescript
import { useSwitchNetwork } from '@civra/web3'
export function NetworkSwitcher() {
const { switchNetwork } = useSwitchNetwork()
return (
<div>
<button onClick={() => switchNetwork(1)}>
Switch to Ethereum
</button>
<button onClick={() => switchNetwork(137)}>
Switch to Polygon
</button>
</div>
)
}Transaction Handling
Monitoring Transactions
typescript
import { useWaitForTransaction } from '@civra/web3'
export function TransactionStatus({ hash }) {
const { data, isLoading, isSuccess } = useWaitForTransaction({
hash
})
if (isLoading) return <div>Transaction pending...</div>
if (isSuccess) return <div>Transaction confirmed!</div>
return null
}Transaction Receipts
typescript
const { data: receipt } = useWaitForTransaction({ hash })
console.log('Gas used:', receipt.gasUsed)
console.log('Block number:', receipt.blockNumber)Token Operations
ERC-20 Tokens
typescript
// Check balance
const { data: balance } = useTokenBalance({
token: '0x...',
address: userAddress
})
// Approve spending
const { write: approve } = useTokenApprove({
token: '0x...',
spender: '0x...',
amount: parseEther('100')
})
// Transfer tokens
const { write: transfer } = useTokenTransfer({
token: '0x...',
to: '0x...',
amount: parseEther('10')
})NFTs (ERC-721)
typescript
// Get NFT metadata
const { data: nft } = useNFT({
contract: '0x...',
tokenId: '1'
})
// Transfer NFT
const { write: transfer } = useNFTTransfer({
contract: '0x...',
from: address,
to: '0x...',
tokenId: '1'
})Gas Optimization
Estimating Gas
typescript
const gasEstimate = await contract.estimateGas.mint()
console.log('Estimated gas:', gasEstimate)Setting Gas Price
typescript
const tx = await contract.write.mint({
gasLimit: 100000,
maxFeePerGas: parseGwei('50'),
maxPriorityFeePerGas: parseGwei('2')
})Events and Logs
Listening to Events
typescript
import { useContractEvent } from '@civra/web3'
useContractEvent({
address: CONTRACT_ADDRESS,
abi: ABI,
eventName: 'Transfer',
listener: (from, to, amount) => {
console.log(`Transfer: ${from} → ${to}: ${amount}`)
}
})Querying Past Events
typescript
const { data: events } = useContractRead({
address: CONTRACT_ADDRESS,
abi: ABI,
functionName: 'getPastEvents',
args: ['Transfer', { fromBlock: 0 }]
})IPFS Integration
Uploading to IPFS
typescript
import { uploadToIPFS } from '@civra/ipfs'
const file = await fetch(imageUrl).then(r => r.blob())
const cid = await uploadToIPFS(file)
console.log('IPFS CID:', cid)Fetching from IPFS
typescript
import { getFromIPFS } from '@civra/ipfs'
const data = await getFromIPFS(cid)
const metadata = JSON.parse(data)Security Best Practices
- Never expose private keys - Always use wallet connections
- Validate user input - Sanitize addresses and amounts
- Handle errors gracefully - Show user-friendly error messages
- Use proper types - TypeScript helps prevent errors
- Test on testnets - Always test before mainnet deployment
- Audit contracts - Get professional audits for financial apps
- Implement access controls - Use proper permission systems
- Monitor transactions - Show clear transaction status
Common Patterns
Loading States
typescript
const { data, isLoading, error } = useContractRead(...)
if (isLoading) return <Spinner />
if (error) return <Error message={error.message} />
return <Data value={data} />Error Handling
typescript
try {
await contract.write.mint()
} catch (error) {
if (error.code === 4001) {
// User rejected
} else if (error.code === -32603) {
// Execution reverted
}
}Examples
Check out our template library for complete Web3 application examples.
