⚠️Blast API (blastapi.io) ends Oct 31. Migrate to Dwellir and skip Alchemy's expensive compute units.
Switch Today →
Skip to main content

eth_getBalance

Returns the ZETA token balance of an account at a given block.

When to Use This Method

Use eth_getBalance to:

  • Check ZETA Balance - Query native token balance
  • Monitor Accounts - Track balance changes over time
  • Verify Transactions - Confirm funds before sending
  • Cross-Chain Operations - Check gas funds for omnichain calls
  • Wallet Integration - Display user balances

Parameters

  1. Address (required): 20 bytes - Address to check balance
  2. Block Parameter (optional):
    • latest - Latest block (default)
    • earliest - Genesis block
    • pending - Pending state
    • Block number as hexadecimal
{
"jsonrpc": "2.0",
"method": "eth_getBalance",
"params": [
"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb8",
"latest"
],
"id": 1
}

Returns

QUANTITY - ZETA balance in wei as hexadecimal.

  • Type: Hexadecimal string
  • Unit: Wei (1 ZETA = 10^18 wei)
  • Format: 0x prefixed

Implementation Examples

curl -X POST https://api-xdc-mainnet.n.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getBalance",
"params": [
"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb8",
"latest"
],
"id": 1
}'

Example Response

{
"jsonrpc": "2.0",
"id": 1,
"result": "0x56bc75e2d63100000"
}

Decoding: 0x56bc75e2d63100000 = 100,000,000,000,000,000,000 wei = 100 ZETA

Omnichain Balance Management

xdc enables unique cross-chain balance features:

Multi-Chain Asset Tracking

// Track balances across multiple chains from xdc
class OmnichainBalanceTracker {
constructor(provider) {
this.provider = provider;
this.zrc20Contracts = new Map();
}

async getTotalBalance(address) {
// Get native ZETA balance
const zetaBalance = await this.provider.getBalance(address);

// Get ZRC-20 balances (wrapped assets from other chains)
const balances = {
ZETA: ethers.formatEther(zetaBalance),
'ETH.ETH': await this.getZRC20Balance(address, ZRC20_ETH),
'BSC.BNB': await this.getZRC20Balance(address, ZRC20_BNB),
'BTC.BTC': await this.getZRC20Balance(address, ZRC20_BTC)
};

return balances;
}

async getZRC20Balance(address, zrc20Address) {
const abi = ['function balanceOf(address) view returns (uint256)'];
const contract = new ethers.Contract(zrc20Address, abi, this.provider);
const balance = await contract.balanceOf(address);
return ethers.formatEther(balance);
}
}

Common Use Cases

1. Wallet Balance Display

class WalletBalanceManager {
constructor(provider) {
this.provider = provider;
this.balanceCache = new Map();
}

async getBalance(address, useCache = true) {
const cacheKey = `balance-${address}`;

// Check cache (valid for 10 seconds)
if (useCache && this.balanceCache.has(cacheKey)) {
const cached = this.balanceCache.get(cacheKey);
if (Date.now() - cached.timestamp < 10000) {
return cached.balance;
}
}

// Fetch fresh balance
const balanceWei = await this.provider.getBalance(address);
const balanceZeta = ethers.formatEther(balanceWei);

// Update cache
this.balanceCache.set(cacheKey, {
balance: balanceZeta,
timestamp: Date.now()
});

return balanceZeta;
}

async formatBalance(address) {
const balance = await this.getBalance(address);

if (parseFloat(balance) === 0) {
return '0 ZETA';
} else if (parseFloat(balance) < 0.0001) {
return '< 0.0001 ZETA';
} else if (parseFloat(balance) > 1000000) {
return `${(parseFloat(balance) / 1000000).toFixed(2)}M ZETA`;
} else {
return `${parseFloat(balance).toFixed(4)} ZETA`;
}
}
}

2. Insufficient Balance Detection

async function checkSufficientBalance(address, requiredAmount, gasBuffer = 0.1) {
const balance = await provider.getBalance(address);
const required = ethers.parseEther(requiredAmount.toString());
const buffer = ethers.parseEther(gasBuffer.toString());
const total = required + buffer;

if (balance < total) {
const shortage = ethers.formatEther(total - balance);
throw new Error(
`Insufficient balance. Need ${ethers.formatEther(total)} ZETA, ` +
`have ${ethers.formatEther(balance)} ZETA. ` +
`Short by ${shortage} ZETA`
);
}

return {
sufficient: true,
balance: ethers.formatEther(balance),
required: ethers.formatEther(total),
surplus: ethers.formatEther(balance - total)
};
}

3. Balance Change Monitor

class BalanceMonitor {
constructor(provider) {
this.provider = provider;
this.subscriptions = new Map();
}

async watchBalance(address, callback, interval = 5000) {
let lastBalance = await this.provider.getBalance(address);

const checkBalance = setInterval(async () => {
const currentBalance = await this.provider.getBalance(address);

if (!currentBalance.eq(lastBalance)) {
const change = currentBalance.sub(lastBalance);
const changeZeta = ethers.formatEther(change);

callback({
address,
previousBalance: ethers.formatEther(lastBalance),
currentBalance: ethers.formatEther(currentBalance),
change: changeZeta,
direction: change.gt(0) ? 'increase' : 'decrease',
timestamp: Date.now()
});

lastBalance = currentBalance;
}
}, interval);

this.subscriptions.set(address, checkBalance);
return () => this.stopWatching(address);
}

stopWatching(address) {
const subscription = this.subscriptions.get(address);
if (subscription) {
clearInterval(subscription);
this.subscriptions.delete(address);
}
}
}

4. Cross-Chain Gas Calculator

async function calculateCrossChainGas(destinationChainId, operation) {
const address = await signer.getAddress();
const balance = await provider.getBalance(address);

// Calculate required ZETA for cross-chain operation
const gasPrice = await provider.getGasPrice();
const estimatedGas = BigInt(200000); // Base cross-chain gas
const protocolFee = ethers.parseEther('0.01'); // xdc protocol fee

// Destination chain gas (paid in ZETA)
const destGasPrice = await getDestinationGasPrice(destinationChainId);
const destGas = BigInt(100000);
const destGasInZeta = convertToZeta(destGasPrice * destGas, destinationChainId);

const totalRequired = (gasPrice * estimatedGas) + protocolFee + destGasInZeta;

if (balance < totalRequired) {
throw new Error(
`Insufficient ZETA for cross-chain operation. ` +
`Need ${ethers.formatEther(totalRequired)} ZETA`
);
}

return {
sufficient: true,
balance: ethers.formatEther(balance),
required: ethers.formatEther(totalRequired),
breakdown: {
xdcGas: ethers.formatEther(gasPrice * estimatedGas),
protocolFee: ethers.formatEther(protocolFee),
destinationGas: ethers.formatEther(destGasInZeta)
}
};
}

5. Historical Balance Analysis

async function analyzeBalanceHistory(address, blocks = 100) {
const currentBlock = await provider.getBlockNumber();
const history = [];

for (let i = 0; i <= blocks; i += 10) {
const blockNumber = currentBlock - (blocks - i);
const balance = await provider.getBalance(address, blockNumber);
const block = await provider.getBlock(blockNumber);

history.push({
block: blockNumber,
timestamp: block.timestamp,
balance: ethers.formatEther(balance)
});
}

// Calculate statistics
const balances = history.map(h => parseFloat(h.balance));
const stats = {
current: balances[balances.length - 1],
highest: Math.max(...balances),
lowest: Math.min(...balances),
average: balances.reduce((a, b) => a + b, 0) / balances.length,
volatility: calculateVolatility(balances)
};

return { history, stats };
}

Balance Precision

Wei Conversion

const units = {
wei: '1',
kwei: '1000',
mwei: '1000000',
gwei: '1000000000',
szabo: '1000000000000',
finney: '1000000000000000',
ether: '1000000000000000000'
};

// Convert between units
function convertBalance(value, fromUnit, toUnit) {
const weiValue = BigInt(value) * BigInt(units[fromUnit]);
return weiValue / BigInt(units[toUnit]);
}

Best Practices

  1. Always handle BigInt for wei values
  2. Cache balance queries to reduce RPC calls
  3. Use appropriate decimal precision for display
  4. Check balance before transactions
  5. Monitor balance changes for security

Error Codes

CodeMessageDescription
-32600Invalid RequestInvalid JSON
-32602Invalid paramsInvalid method parameters
-32603Internal errorInternal JSON-RPC error
-32000Invalid inputInvalid address format