sup.blockchain
The sup.blockchain package provides read-only access to EVM-compatible blockchain data. It supports Ethereum mainnet and major Layer 2 networks including Base, Optimism, Arbitrum, Polygon, and Zora.
// Get current block numberconst blockNum = sup.blockchain.eth.blockNumber();
// Get ETH balance (vitalik.eth)const balance = sup.blockchain.eth.balance('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045');const formatted = sup.blockchain.eth.format(balance);
// Get token priceconst ethPrice = sup.blockchain.eth.price('ETH');console.log('ETH price:', ethPrice.toString());
// Read from a smart contractconst usdc = sup.blockchain.eth.erc20('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48');const symbol = usdc.symbol(); // "USDC"const decimals = usdc.decimals(); // 6
// Use other chainsconst baseBalance = sup.blockchain.eth.chain('base').balance('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045');Security Notice
All blockchain operations are read-only. There is no transaction signing, private key handling, or write operations. This API is designed for safely querying blockchain data without any risk of funds movement.
Properties
sup.blockchain.eth
SupBlockchainChain
The primary interface for Ethereum mainnet operations. All methods are available directly on this object.
Chain Information
sup.blockchain.eth.blockNumber()
→ string
const blockNum = sup.blockchain.eth.blockNumber();console.log('Current block:', blockNum);Returns the current block number for the chain as a string.
Balances
sup.blockchain.eth.balance()
(address: string, token?: string) → string
// Get native ETH balance (vitalik.eth)const ethBalance = sup.blockchain.eth.balance('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045');console.log('ETH:', sup.blockchain.eth.format(ethBalance));
// Get ERC20 token balanceconst usdcBalance = sup.blockchain.eth.balance( '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48');console.log('USDC:', sup.blockchain.eth.format(usdcBalance, 6));Get wallet balance for native token (ETH) or any ERC20 token. Returns the balance as a string in the smallest unit (wei for ETH, or token’s base unit).
Parameters:
address(string): Wallet address to querytoken(string, optional): ERC20 token contract address. Omit for native token.
Returns: Balance as string in wei/smallest unit
Token Prices
sup.blockchain.eth.price()
(contractOrTicker: string) → SupBigNumber
// Get price by ticker symbolconst ethPrice = sup.blockchain.eth.price('ETH');console.log('ETH price:', ethPrice.toString());
// Get price by contract addressconst usdcPrice = sup.blockchain.eth.price('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48');console.log('USDC price:', usdcPrice.toFixed(6));
// Perform calculations with precisionconst doubled = ethPrice.times(2);const ethAmount = new SupBigNumber('1.5');const totalValue = ethAmount.times(ethPrice);console.log('Value of 1.5 ETH:', totalValue.toFixed(2), 'USD');Get current USD price for a token from DeFiLlama. Returns a SupBigNumber with 18 decimal precision for mathematical operations.
Parameters:
contractOrTicker(string): Either a contract address (starting with0x) or a ticker symbol (likeETH,USDC,BTC)
Returns: SupBigNumber with the USD price
See the SupBigNumber documentation for available operations.
Smart Contract Reads
sup.blockchain.eth.contract()
(address: string, abi: any[], functionName: string, args?: any[]) → any
const balance = sup.blockchain.eth.contract( '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', [ { "constant": true, "inputs": [{"name": "_owner", "type": "address"}], "name": "balanceOf", "outputs": [{"name": "balance", "type": "uint256"}], "type": "function" } ], 'balanceOf', ['0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045']);Read data from any smart contract by providing the ABI and function details.
Parameters:
address(string): Contract addressabi(any[]): Array containing the function ABIfunctionName(string): Name of the function to callargs(any[], optional): Array of arguments to pass to the function
Returns: The function’s return value (type depends on the contract function)
ERC20 Tokens
sup.blockchain.eth.erc20()
(address: string) → SupERC20
const usdc = sup.blockchain.eth.erc20('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48');
// Get token infoconst symbol = usdc.symbol(); // "USDC"const name = usdc.name(); // "USD Coin"const decimals = usdc.decimals(); // 6const supply = usdc.totalSupply(); // Total supply in base units
// Check balancesconst balance = usdc.balanceOf('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045');
// Check allowancesconst allowance = usdc.allowance( '0xOwnerAddress...', '0xSpenderAddress...');Convenience wrapper for ERC20 token operations. Returns an object with methods that automatically use the ERC20 ABI.
Returns: Object with the following methods:
SupERC20 Methods
balanceOf(account: string)→string- Get token balance for an addresstotalSupply()→string- Get total token supplydecimals()→number- Get number of decimalssymbol()→string- Get token symbolname()→string- Get token nameallowance(owner: string, spender: string)→string- Get approved spending amount
sup.blockchain.eth.token()
(address: string) → TokenMetadata
const metadata = sup.blockchain.eth.token('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48');console.log(`${metadata.symbol}: ${metadata.name}`);console.log(`Decimals: ${metadata.decimals}`);console.log(`Total Supply: ${metadata.totalSupply}`);Get comprehensive metadata for an ERC20 token in a single call.
Returns: Object with:
name(string): Token namesymbol(string): Token symboldecimals(number): Number of decimalstotalSupply(string): Total supply in base units
ERC721 NFTs
sup.blockchain.eth.erc721()
(address: string) → SupERC721
const blitmap = sup.blockchain.eth.erc721('0x8d04a8c79cEB0889Bdd12acdF3Fa9D207eD3Ff63');
// Get NFT infoconst name = blitmap.name(); // "Blitmap"const symbol = blitmap.symbol(); // "BLIT"const supply = blitmap.totalSupply(); // "1700"
// Check ownershipconst owner = blitmap.ownerOf(1); // Owner address of token #1const balance = blitmap.balanceOf('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045');
// Get metadataconst uri = blitmap.tokenURI(1); // Metadata URI for token #1
// Check approvalsconst approved = blitmap.getApproved(1); // Address approved for token #1const isApproved = blitmap.isApprovedForAll('0xOwner...', '0xOperator...');Convenience wrapper for ERC721 NFT operations.
Returns: Object with the following methods:
SupERC721 Methods
balanceOf(owner: string)→string- Get NFT count for an addressownerOf(tokenId: number | string)→string- Get owner of a specific tokentokenURI(tokenId: number | string)→string- Get metadata URIname()→string- Get collection namesymbol()→string- Get collection symboltotalSupply()→string- Get total number of tokensgetApproved(tokenId: number | string)→string- Get approved address for tokenisApprovedForAll(owner: string, operator: string)→boolean- Check operator approval
ERC1155 Multi-Tokens
sup.blockchain.eth.erc1155()
(address: string) → SupERC1155
const nft = sup.blockchain.eth.erc1155('0x495f947276749ce646f68ac8c248420045cb7b5e');
// Check balance for specific token IDconst balance = nft.balanceOf('0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb', 1);
// Check multiple balances at onceconst balances = nft.balanceOfBatch( ['0xAddress1...', '0xAddress2...'], [1, 2]);
// Get metadata URIconst uri = nft.uri(1);
// Check approvalsconst isApproved = nft.isApprovedForAll('0xOwner...', '0xOperator...');Convenience wrapper for ERC1155 multi-token operations.
Returns: Object with the following methods:
SupERC1155 Methods
balanceOf(account: string, id: number | string)→string- Get balance for specific token IDbalanceOfBatch(accounts: string[], ids: (number | string)[])→string[]- Get multiple balancesuri(id: number | string)→string- Get metadata URI for token IDisApprovedForAll(owner: string, operator: string)→boolean- Check operator approval
Transactions
sup.blockchain.eth.tx()
(hash: string) → Transaction
const tx = sup.blockchain.eth.tx('0x123...');console.log('From:', tx.from);console.log('To:', tx.to);console.log('Value:', tx.value);console.log('Block:', tx.blockNumber);Get details about a transaction by its hash.
Returns: Transaction object with properties like from, to, value, gas, blockNumber, etc.
Utility Functions
sup.blockchain.eth.format()
(value: string | number, decimals?: number) → number
const balance = sup.blockchain.eth.balance(address);const formatted = sup.blockchain.eth.format(balance, 18);console.log('Balance:', formatted, 'ETH');
// USDC has 6 decimalsconst usdcBalance = sup.blockchain.eth.balance(address, usdcAddress);const usdcFormatted = sup.blockchain.eth.format(usdcBalance, 6);console.log('Balance:', usdcFormatted, 'USDC');Convert from wei/smallest unit to human-readable value.
Parameters:
value(string | number): Value in wei or smallest unitdecimals(number, optional): Token decimals (default: 18 for ETH)
Returns: Formatted value as JavaScript number
Note: Since this returns a JavaScript Number, precision may be lost for very large values. For precise calculations, use SupBigNumber operations instead.
sup.blockchain.eth.parse()
(value: number, decimals?: number) → string
const amount = sup.blockchain.eth.parse(1.5, 18);console.log('1.5 ETH in wei:', amount);
const usdcAmount = sup.blockchain.eth.parse(100, 6);console.log('100 USDC in base units:', usdcAmount);Convert from human-readable value to wei/smallest unit.
Parameters:
value(number): Human-readable valuedecimals(number, optional): Token decimals (default: 18 for ETH)
Returns: Value in wei/smallest unit as string
sup.blockchain.eth.isAddress()
(address: string) → boolean
if (sup.blockchain.eth.isAddress(userInput)) { const balance = sup.blockchain.eth.balance(userInput); // ...} else { return "Invalid Ethereum address";}Validate Ethereum address format (checks for 0x prefix and 40 hex characters).
Parameters:
address(string): Address to validate
Returns: true if valid Ethereum address format, false otherwise
Multi-Chain Support
sup.blockchain.eth.chain()
(chainName: string) → SupBlockchainChain
// Access Base L2const baseBalance = sup.blockchain.eth.chain('base').balance(address);const baseBlock = sup.blockchain.eth.chain('base').blockNumber();
// Access Optimismconst opUsdc = sup.blockchain.eth.chain('optimism').erc20('0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85');const symbol = opUsdc.symbol();
// Access Arbitrumconst arbPrice = sup.blockchain.eth.chain('arbitrum').price('ETH');
// Access Polygonconst polyBalance = sup.blockchain.eth.chain('polygon').balance(address);
// Access Zoraconst zoraBlock = sup.blockchain.eth.chain('zora').blockNumber();Access Layer 2 and other EVM-compatible chains with the same API interface.
Supported chains:
base- Baseoptimism- Optimismarbitrum- Arbitrum Onepolygon- Polygon PoSzora- Zora
Returns: Chain-specific blockchain operations with the same API as sup.blockchain.eth
All methods available on sup.blockchain.eth are also available on the returned chain object:
blockNumber()balance(address, token?)price(contractOrTicker)contract(address, abi, functionName, args?)erc20(address)erc721(address)erc1155(address)token(address)tx(hash)format(value, decimals?)parse(value, decimals?)isAddress(address)
SupBigNumber
The SupBigNumber class is returned by price() and provides precision-safe mathematical operations for financial calculations.
Why SupBigNumber?
JavaScript’s native Number type loses precision with large numbers or many decimal places. For financial data like token prices, this can lead to incorrect calculations. SupBigNumber uses JavaScript’s native bigint for fixed-point arithmetic to maintain exact values within a specified decimal precision (default 18 decimals).
// Problem with native numbers:const price = 0.999663;const amount = 1000000;console.log(price * amount); // 999663.0000000001 ❌
// Solution with SupBigNumber:const price = sup.blockchain.eth.price('USDC');const amount = new SupBigNumber('1000000');console.log(price.times(amount).toString()); // Exact result ✓Constructor
// Create from various sourcesconst bn1 = new SupBigNumber('123.456');const bn2 = new SupBigNumber(123.456);const bn3 = new SupBigNumber('1000000000000000000', 18); // With decimals
// From price API (returns SupBigNumber)const ethPrice = sup.blockchain.eth.price('ETH');Methods
Arithmetic Operations
const a = new SupBigNumber('10.5');const b = new SupBigNumber('2.25');
a.plus(b); // Addition: 12.75a.minus(b); // Subtraction: 8.25a.times(b); // Multiplication: 23.625a.div(b); // Division: 4.666...Conversion & Formatting
const num = new SupBigNumber('123.456789');
num.toString(); // "123.456789"num.toFixed(2); // "123.46"num.toFixed(0); // "123"num.toNumber(); // 123.456789 (JavaScript number)Comparisons
const a = new SupBigNumber('10');const b = new SupBigNumber('20');
a.gt(b); // false (greater than)a.gte(b); // false (greater than or equal)a.lt(b); // true (less than)a.lte(b); // true (less than or equal)a.eq(b); // false (equal)Example: Calculate Portfolio Value
function main() { // Get current prices const ethPrice = sup.blockchain.eth.price('ETH'); const btcPrice = sup.blockchain.eth.price('BTC');
// Define holdings const ethHolding = new SupBigNumber('2.5'); const btcHolding = new SupBigNumber('0.1');
// Calculate values const ethValue = ethPrice.times(ethHolding); const btcValue = btcPrice.times(btcHolding); const totalValue = ethValue.plus(btcValue);
return [ `ETH: ${ethHolding.toString()} × $${ethPrice.toFixed(2)} = $${ethValue.toFixed(2)}`, `BTC: ${btcHolding.toString()} × $${btcPrice.toFixed(2)} = $${btcValue.toFixed(2)}`, `Total: $${totalValue.toFixed(2)}` ];}Complete Examples
Check Multiple Token Balances
function main() { const address = sup.input.text;
if (!sup.blockchain.eth.isAddress(address)) { return "Please provide a valid Ethereum address"; }
// Native ETH const ethBalance = sup.blockchain.eth.balance(address); const ethFormatted = sup.blockchain.eth.format(ethBalance);
// USDC const usdcAddress = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; const usdcBalance = sup.blockchain.eth.balance(address, usdcAddress); const usdcFormatted = sup.blockchain.eth.format(usdcBalance, 6);
// USDT const usdtAddress = '0xdAC17F958D2ee523a2206206994597C13D831ec7'; const usdtBalance = sup.blockchain.eth.balance(address, usdtAddress); const usdtFormatted = sup.blockchain.eth.format(usdtBalance, 6);
return [ `Address: ${address}`, `ETH: ${ethFormatted.toFixed(4)}`, `USDC: ${usdcFormatted.toFixed(2)}`, `USDT: ${usdtFormatted.toFixed(2)}` ];}Track Token Price
function main() { const ticker = sup.input.text || 'ETH';
try { const price = sup.blockchain.eth.price(ticker); const priceNum = price.toNumber();
// Store historical data const history = sup.get('priceHistory') || []; history.push({ ticker, price: price.toString(), timestamp: Date.now() });
// Keep last 10 prices if (history.length > 10) history.shift(); sup.set('priceHistory', history);
// Calculate change if we have previous data let change = ''; if (history.length > 1) { const prev = new SupBigNumber(history[history.length - 2].price); const diff = price.minus(prev); const pct = diff.div(prev).times(100); change = ` (${pct.toFixed(2)}%)`; }
return `${ticker}: $${price.toFixed(priceNum < 10 ? 4 : 2)}${change}`; } catch (error) { return `Could not find price for ${ticker}`; }}Multi-Chain Balance Checker
function main() { const address = sup.input.text;
if (!sup.blockchain.eth.isAddress(address)) { return "Invalid address"; }
const chains = [ { name: 'Ethereum', chain: null }, { name: 'Base', chain: 'base' }, { name: 'Optimism', chain: 'optimism' }, { name: 'Arbitrum', chain: 'arbitrum' }, { name: 'Polygon', chain: 'polygon' } ];
const results = chains.map(({ name, chain }) => { try { const balance = chain ? sup.blockchain.eth.chain(chain).balance(address) : sup.blockchain.eth.balance(address); const formatted = sup.blockchain.eth.format(balance); return `${name}: ${formatted.toFixed(4)} ETH`; } catch (error) { return `${name}: Error`; } });
return ['Balance across chains:', ...results];}NFT Ownership Checker
function main() { const [collection, tokenId] = (sup.input.text || '').split('/');
if (!collection || !tokenId) { return "Usage: <collection-address>/<token-id>"; }
if (!sup.blockchain.eth.isAddress(collection)) { return "Invalid collection address"; }
try { const nft = sup.blockchain.eth.erc721(collection);
const name = nft.name(); const symbol = nft.symbol(); const owner = nft.ownerOf(tokenId); const uri = nft.tokenURI(tokenId);
return [ `Collection: ${name} (${symbol})`, `Token ID: ${tokenId}`, `Owner: ${owner}`, `Metadata: ${uri}` ]; } catch (error) { return `Error: ${error.message}`; }}Notes
- All operations are read-only - no transaction signing or private keys
- Prices are fetched from DeFiLlama’s price API
- Price data is stored with 18 decimal precision
- Use
SupBigNumberfor precise financial calculations format()returns JavaScriptNumberwhich may lose precision for very large values- Contract reads require valid ABI definitions
- Address validation only checks format, not if the address exists on-chain