Celo - Build Mobile-First Financial Applications
Chain RPC
With Dwellir, you get access to our global Chain network which always routes your API requests to the nearest available location, ensuring low latency and the fastest speeds.
Why Build on Celo?
Celo is a mobile-first, EVM-compatible blockchain platform designed to make decentralized financial tools accessible to anyone with a mobile phone. As a carbon-negative blockchain, Celo leads the way in sustainable Web3 development.
📱 Mobile-First Architecture
- Ultralight client - Sync and verify on low-end smartphones
- Phone number mapping - Send crypto using just phone numbers
- Gas fee abstraction - Pay fees with any Celo native asset
- Offline transactions - Support for areas with limited connectivity
🌍 Financial Inclusion
- Stable value currencies - Native stablecoins (cUSD, cEUR, cREAL)
- Low transaction costs - Transactions under $0.01
- Fast finality - 5-second block times with instant finality
- Multi-currency gas - Pay transaction fees in stable tokens
🌱 Sustainability Leadership
- Carbon negative - First carbon-negative blockchain
- Regenerative finance - Built-in climate action programs
- Natural capital backing - Reserve includes tokenized rainforest
- Climate collective - Supporting ecosystem climate initiatives
Quick Start with Celo
Connect to Celo in seconds with Dwellir's high-performance endpoints:
🔗 RPC Endpoints
https://api-celo-mainnet-archive.n.dwellir.com/YOUR_API_KEY
Quick Connect:
curl -X POST https://api-celo-mainnet-archive.n.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'
Installation & Setup
- Ethers.js v6
- Web3.js
- Viem
- ContractKit
import { JsonRpcProvider } from 'ethers';
// Connect to Celo mainnet
const provider = new JsonRpcProvider(
'https://api-celo-mainnet-archive.n.dwellir.com/YOUR_API_KEY'
);
// Get the latest block
const block = await provider.getBlock('latest');
console.log('Latest block:', block.number);
// Query cUSD balance
const cUSD = '0x765DE816845861e75A25fCA122bb6898B8B1282a';
const balance = await provider.getBalance('0x...', cUSD);
console.log('cUSD Balance:', balance.toString());
const Web3 = require('web3');
// Connect to Celo mainnet
const web3 = new Web3(
'https://api-celo-mainnet-archive.n.dwellir.com/YOUR_API_KEY'
);
// Get chain ID to verify connection
const chainId = await web3.eth.getChainId();
console.log('Connected to Celo:', chainId === 42220n);
// Get gas price in CELO
const gasPrice = await web3.eth.getGasPrice();
console.log('Current gas price:', gasPrice);
import { createPublicClient, http } from 'viem';
import { celo } from 'viem/chains';
// Create Celo client
const client = createPublicClient({
chain: celo,
transport: http('https://api-celo-mainnet-archive.n.dwellir.com/YOUR_API_KEY'),
});
// Read stable token balance
const cUSDAddress = '0x765DE816845861e75A25fCA122bb6898B8B1282a';
const balance = await client.readContract({
address: cUSDAddress,
abi: erc20Abi,
functionName: 'balanceOf',
args: ['0x...'],
});
import { newKit } from '@celo/contractkit';
// Connect using ContractKit (Celo's SDK)
const kit = newKit('https://api-celo-mainnet-archive.n.dwellir.com/YOUR_API_KEY');
// Get stable token contracts
const cUSD = await kit.contracts.getStableToken();
const cEUR = await kit.contracts.getStableToken('cEUR');
// Get account balance in multiple currencies
const address = '0x...';
const [celoBalance, cUsdBalance] = await Promise.all([
kit.getTotalBalance(address),
cUSD.balanceOf(address)
]);
console.log('CELO:', celoBalance.CELO.toString());
console.log('cUSD:', cUsdBalance.toString());
Network Information
Chain ID
42220
MainnetBlock Time
5 seconds
With instant finalityGas Token
CELO
Multi-asset feesConsensus
PBFT
Proof of StakeJSON-RPC API Reference
Celo supports the full Ethereum JSON-RPC API plus additional Celo-specific methods for mobile and stable currency features.
Available JSON-RPC Methods
📊 Reading Blockchain Data
Query blocks, transactions, and account states
📤 Sending Transactions
Submit and manage transactions
📝 Smart Contract Interaction
Call and interact with smart contracts
🔧 Node & Network Info
Query node status and network information
🎯 Base L2 Specific
Methods specific to Base Layer 2
Ready to integrate Base into your dApp?
Get Your Free API Key →Celo-Specific Features
🪙 Native Stable Currencies
Work with Celo's algorithmic stablecoins:
// Stable token addresses on Celo Mainnet
const STABLE_TOKENS = {
cUSD: '0x765DE816845861e75A25fCA122bb6898B8B1282a',
cEUR: '0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73',
cREAL: '0xe8537a3d056DA446677B9E9d6c5dB704EaAb4787'
};
// Transfer cUSD
async function transferCUSD(to, amount) {
const cUSD = new ethers.Contract(
STABLE_TOKENS.cUSD,
['function transfer(address to, uint256 amount) returns (bool)'],
signer
);
const tx = await cUSD.transfer(to, ethers.parseUnits(amount, 18));
await tx.wait();
return tx.hash;
}
📞 Phone Number Verification
Integrate Celo's identity protocol:
// Verify phone number ownership (using Celo SDK)
import { OdisUtils } from '@celo/identity';
async function verifyPhoneNumber(phoneNumber, address) {
// Get attestation service
const attestations = await kit.contracts.getAttestations();
// Request attestations
const tx = await attestations.request(
phoneNumber,
3, // Number of attestations
address
);
await tx.waitReceipt();
// Complete verification process
const attestationCode = await getAttestationCode(); // SMS verification
await attestations.complete(phoneNumber, address, attestationCode);
}
💰 Fee Currency Selection
Pay gas fees with stable tokens:
// Configure transaction to pay fees in cUSD
async function sendWithStableFees(to, value) {
const tx = {
to,
value: ethers.parseEther(value),
feeCurrency: STABLE_TOKENS.cUSD, // Pay fees in cUSD
gasLimit: 21000,
gasPrice: await provider.getGasPrice()
};
const signedTx = await signer.signTransaction(tx);
const receipt = await provider.sendTransaction(signedTx);
return receipt;
}
Common Integration Patterns
🔄 Multi-Currency Wallets
Build wallets supporting multiple Celo assets:
class CeloWallet {
constructor(provider, address) {
this.provider = provider;
this.address = address;
}
async getBalances() {
const balances = {};
// Get CELO balance
balances.CELO = await this.provider.getBalance(this.address);
// Get stable token balances
for (const [symbol, address] of Object.entries(STABLE_TOKENS)) {
const contract = new ethers.Contract(
address,
['function balanceOf(address) view returns (uint256)'],
this.provider
);
balances[symbol] = await contract.balanceOf(this.address);
}
return balances;
}
async getUSDValue() {
const balances = await this.getBalances();
let totalUSD = 0;
// cUSD is pegged 1:1
totalUSD += Number(ethers.formatUnits(balances.cUSD, 18));
// Get CELO price from oracle
const celoPrice = await this.getCELOPrice();
totalUSD += Number(ethers.formatUnits(balances.CELO, 18)) * celoPrice;
return totalUSD;
}
}
🌐 Mobile Light Client
Optimize for mobile devices:
// Ultralight client configuration
class MobileCeloClient {
constructor(rpcUrl) {
this.provider = new JsonRpcProvider(rpcUrl, {
// Optimize for mobile
timeout: 30000,
throttleLimit: 1,
throttleSlotInterval: 1000
});
// Cache frequently accessed data
this.cache = new Map();
}
async getBlockHeader(blockNumber) {
const key = `block_${blockNumber}`;
if (this.cache.has(key)) {
return this.cache.get(key);
}
// Fetch only essential fields for mobile
const block = await this.provider.send('eth_getBlockByNumber', [
ethers.toQuantity(blockNumber),
false // Don't include transactions
]);
const header = {
number: block.number,
hash: block.hash,
timestamp: block.timestamp,
gasUsed: block.gasUsed
};
this.cache.set(key, header);
return header;
}
}
🔐 Validator Operations
Interact with Celo's proof-of-stake system:
// Stake CELO with validators
async function stakeCELO(validatorAddress, amount) {
const election = await kit.contracts.getElection();
const lockedGold = await kit.contracts.getLockedGold();
// Lock CELO first
await lockedGold.lock().sendAndWaitForReceipt({
value: amount
});
// Vote for validator
await election.vote(validatorAddress, amount)
.sendAndWaitForReceipt();
console.log(`Staked ${amount} CELO with validator ${validatorAddress}`);
}
// Get validator rewards
async function getRewards(address) {
const election = await kit.contracts.getElection();
const rewards = await election.getVoterRewards(address);
return rewards;
}
Performance Optimization
1. Batch Operations
Minimize RPC calls with multicall:
import { Multicall } from '@celo/contractkit';
async function batchTokenBalances(addresses) {
const multicall = new Multicall(kit);
const calls = addresses.flatMap(addr =>
Object.entries(STABLE_TOKENS).map(([symbol, token]) => ({
target: token,
callData: encodeBalanceOf(addr),
symbol,
address: addr
}))
);
const results = await multicall.aggregate(calls);
return parseResults(results);
}
2. Archive Node Access
Leverage Dwellir's archive nodes for historical data:
// Query historical stable token prices
async function getHistoricalPrice(blockNumber) {
const oracle = new ethers.Contract(
ORACLE_ADDRESS,
['function getExchangeRate(address) view returns (uint256, uint256)'],
provider
);
// Use archive node to query past state
const [numerator, denominator] = await oracle.getExchangeRate(
STABLE_TOKENS.cUSD,
{ blockTag: blockNumber }
);
return numerator / denominator;
}
3. Event Indexing
Efficiently sync events with filters:
async function syncTransfers(fromBlock, toBlock) {
const filter = {
address: STABLE_TOKENS.cUSD,
topics: [ethers.id('Transfer(address,address,uint256)')],
fromBlock,
toBlock
};
// Process in chunks to avoid timeouts
const chunkSize = 1000;
const events = [];
for (let i = fromBlock; i <= toBlock; i += chunkSize) {
const chunk = await provider.getLogs({
...filter,
fromBlock: i,
toBlock: Math.min(i + chunkSize - 1, toBlock)
});
events.push(...chunk);
}
return events;
}
Developer Resources
Getting Started Guides
🚀 Quick Start Tutorial
Build your first Celo dApp in 10 minutes:
- Setup Development Environment
# Install Celo CLI
npm install -g @celo/celocli
# Create new project
npx create-react-app my-celo-dapp
cd my-celo-dapp
# Install Celo dependencies
npm install @celo/contractkit ethers
- Connect to Celo
// src/celo.js
import { newKit } from '@celo/contractkit';
export const kit = newKit(
'https://api-celo-mainnet-archive.n.dwellir.com/YOUR_API_KEY'
);
- Build UI Components
// src/App.js
import { useState, useEffect } from 'react';
import { kit } from './celo';
function App() {
const [account, setAccount] = useState('');
const [balance, setBalance] = useState('0');
useEffect(() => {
connectWallet();
}, []);
async function connectWallet() {
// Connect to Celo wallet
const accounts = await kit.web3.eth.getAccounts();
setAccount(accounts[0]);
// Get balance
const bal = await kit.getTotalBalance(accounts[0]);
setBalance(bal.CELO.toString());
}
return (
<div>
<h1>My Celo dApp</h1>
<p>Account: {account}</p>
<p>Balance: {balance} CELO</p>
</div>
);
}
📱 Mobile Integration Guide
Optimize your dApp for mobile users:
// Mobile-optimized provider configuration
const mobileConfig = {
// Reduce timeout for mobile networks
timeout: 20000,
// Enable compression
headers: {
'Accept-Encoding': 'gzip, deflate'
},
// Retry logic for unstable connections
retry: {
retries: 3,
minTimeout: 1000,
maxTimeout: 5000
}
};
// Detect mobile and adjust accordingly
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
const provider = new JsonRpcProvider(
'https://api-celo-mainnet-archive.n.dwellir.com/YOUR_API_KEY',
isMobile ? mobileConfig : {}
);
Troubleshooting
Common Issues and Solutions
Issue | Description | Solution |
---|---|---|
"Insufficient fee currency balance" | Not enough of selected fee currency | Ensure account has sufficient cUSD/cEUR or switch to CELO for fees |
"Invalid feeCurrency address" | Fee currency not supported | Use only approved stable tokens: cUSD, cEUR, cREAL |
"Phone number already verified" | Number linked to another address | Use Celo's re-verification process or contact support |
"Validator not registered" | Trying to vote for invalid validator | Check validator status with election.getValidatorGroups() |
Testing on Alfajores Testnet
Get started with Celo's testnet:
// Connect to Alfajores testnet
const testnetProvider = new JsonRpcProvider(
'https://api-celo-alfajores.n.dwellir.com/YOUR_API_KEY'
);
// Alfajores faucet
// Visit: https://faucet.celo.org
// Testnet stable tokens
const ALFAJORES_TOKENS = {
cUSD: '0x874069Fa1Eb16D44d622F2e0Ca25eeA172369bC1',
cEUR: '0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F'
};
Migration Guide
From Ethereum to Celo
Migrating Ethereum dApps to Celo is straightforward:
// Before (Ethereum)
const provider = new JsonRpcProvider('https://eth-rpc.example.com');
const tx = {
to: recipient,
value: amount,
gasPrice: await provider.getGasPrice()
};
// After (Celo)
const provider = new JsonRpcProvider(
'https://api-celo-mainnet-archive.n.dwellir.com/YOUR_API_KEY'
);
const tx = {
to: recipient,
value: amount,
gasPrice: await provider.getGasPrice(),
feeCurrency: STABLE_TOKENS.cUSD // Optional: pay fees in cUSD
};
// ✅ EVM compatible - contracts work without changes
// ✅ Same Web3 libraries and tools
// ⚠️ Different chain ID (42220)
// ⚠️ Additional features: stable tokens, phone verification
// ✨ New capability: multi-currency gas payments
Ecosystem & Tools
DeFi on Celo
- Ubeswap - Leading DEX on Celo
- Moola Market - Lending and borrowing
- Mento - Decentralized stable asset protocol
- Valora - Mobile-first Celo wallet
Developer Tools
- Celo Composer - Full-stack starter kit
- Remix IDE - Deploy contracts to Celo
- Celo Explorer - Block explorer
- ContractKit - Celo SDK
Community Resources
Need Help?
- 📧 Email: support@dwellir.com
- 💬 Discord: Join our developer community
- 📚 Celo Docs: docs.celo.org
- 🎯 Dashboard: dashboard.dwellir.com
Build the future of regenerative finance on Celo with Dwellir's reliable RPC infrastructure. Get your free API key →