/** * balances.js * * Reads on-chain balances. Requires the user to configure RPC endpoints * (config.json) — we don't bake in a paid provider's API key. Free public * endpoints are set as defaults so it works out of the box, but they are * rate-limited and not meant for production use. */ const { ethers } = require('ethers'); const { Connection, PublicKey, LAMPORTS_PER_SOL } = require('@solana/web3.js'); async function getEthBalance(address, rpcUrl) { const provider = new ethers.JsonRpcProvider(rpcUrl); const wei = await provider.getBalance(address); return ethers.formatEther(wei); // returns a decimal string, e.g. "1.234" } async function getSolBalance(address, rpcUrl) { const connection = new Connection(rpcUrl); const lamports = await connection.getBalance(new PublicKey(address)); return (lamports / LAMPORTS_PER_SOL).toString(); } /** Bitcoin: no JSON-RPC by default without running your own node, so we * use a block explorer's public REST API (Blockstream) instead. */ async function getBtcBalance(address, apiBase = 'https://blockstream.info/api') { const res = await fetch(`${apiBase}/address/${address}`); if (!res.ok) throw new Error(`Blockstream API error: ${res.status}`); const data = await res.json(); const sats = data.chain_stats.funded_txo_sum - data.chain_stats.spent_txo_sum + data.mempool_stats.funded_txo_sum - data.mempool_stats.spent_txo_sum; return (sats / 1e8).toString(); } module.exports = { getEthBalance, getSolBalance, getBtcBalance };