A real-time treasury management view is a dashboard that aggregates and visualizes a project's on-chain financial position. Unlike traditional finance, where data is siloed and reported quarterly, blockchain-native treasuries are transparent and update with every transaction. This guide explains how to build a system that tracks assets across multiple chains and protocols, calculates liabilities from token vesting or loans, and presents key metrics like runway and portfolio diversification. The goal is operational clarity for DAOs, protocols, and crypto-native companies.
Launching a Real-Time Treasury Management View
Launching a Real-Time Treasury Management View
A guide to building a live dashboard for monitoring on-chain treasury assets, liabilities, and financial health.
The core technical challenge is data aggregation. A treasury's assets are rarely in one place; they are distributed across EVM-compatible chains (Ethereum, Arbitrum, Optimism), Layer 2 networks, and in various forms like native tokens, ERC-20 tokens, LP positions, and staked assets. Liabilities, such as team token allocations on vesting contracts or debt positions in protocols like Aave, must also be tracked. Building a view requires querying multiple blockchains, decoding contract states, and fetching real-time prices from oracles.
To build this, you will use a stack of Web3 development tools. Start with a data indexer like The Graph or Covalent to query historical balances and transactions. For real-time state, use JSON-RPC providers (Alchemy, Infura) with multicall contracts for batch queries. Price feeds can be sourced from Chainlink oracles or DEX aggregators. This data is then processed in a backend service (using Node.js or Python) which calculates metrics and serves them via an API to a frontend dashboard built with frameworks like React or Next.js.
Key financial metrics to calculate include Total Value Locked (TVL) across all assets, runway (how long the treasury can fund operations at current burn rates), and asset allocation percentages. For example, a treasury with 10,000 ETH, 5 million USDC, and various LP tokens needs each asset's USD value summed. Runway is calculated as (Liquid Assets USD) / (Monthly Operational Expenses). It's critical to distinguish between liquid assets (stablecoins, blue-chip tokens) and illiquid assets (locked vesting tokens, long-tail LP positions) in these calculations.
Security and accuracy are paramount. Always verify contract addresses from official sources like the project's GitHub or Etherscan. Use multi-signature wallet addresses as the source of truth for treasury holdings. Implement data validation checks; for instance, cross-reference price feeds from two independent oracles. The system should also account for gas fees on different chains when calculating net asset value, as moving funds incurs real costs. Regular audits of the data pipeline ensure the dashboard reflects the true, actionable financial state.
This guide provides the architectural blueprint and code snippets to launch your own treasury dashboard. By the end, you will be able to deploy a system that answers critical questions: What is our treasury's total value? How is it allocated? What is our monthly burn rate and runway? With real-time data, teams can make informed, proactive financial decisions instead of relying on outdated snapshots, turning treasury management from a periodic reporting task into a continuous strategic function.
Prerequisites and Tech Stack
The technical foundation required to build a real-time treasury management view using on-chain data.
Building a real-time treasury dashboard requires a specific technical foundation. You'll need proficiency in a modern programming language like JavaScript/TypeScript or Python for data processing and API interaction. A working knowledge of blockchain fundamentals is essential, including concepts like wallets, transactions, smart contracts, and the structure of common blockchains like Ethereum, Solana, or Polygon. Familiarity with REST APIs and GraphQL will be crucial for fetching data from indexers and node providers.
The core of your tech stack will be a reliable data provider. For real-time, historical, and decoded data, you'll use services like Chainscore, The Graph, or Alchemy. These platforms abstract away the complexity of running nodes and provide structured APIs. You will also need a backend framework (e.g., Node.js with Express, Python with FastAPI) to build your API layer and a database (e.g., PostgreSQL, TimescaleDB) to cache and aggregate metrics for performance. For the frontend, a reactive framework like React or Vue.js is ideal for displaying live-updating charts and tables.
Key development tools include Node.js (v18+) or Python (3.10+), npm/yarn/pip for package management, and Git for version control. You will interact with blockchain data using SDKs like ethers.js (v6) for Ethereum or @solana/web3.js for Solana. To streamline development, set up environment variables for your API keys (e.g., CHAINSECORE_API_KEY) and use a .env file. A basic project structure with separate directories for data fetching, business logic, and the frontend will keep your code organized as complexity grows.
System Architecture Overview
This guide details the system architecture for building a live dashboard that aggregates and visualizes on-chain treasury data across multiple protocols and blockchains.
A real-time treasury management view is a data aggregation and visualization system that pulls financial state from multiple on-chain sources. The core architecture typically follows a modular design with three primary layers: a data ingestion layer that queries blockchain nodes and indexers, a processing and storage layer that normalizes and caches this data, and a presentation layer that serves it via an API and frontend dashboard. This separation of concerns ensures scalability, allowing you to add new data sources—like a new DeFi protocol on Arbitrum or a new token standard on Solana—without overhauling the entire application.
The data ingestion layer is responsible for collecting raw on-chain information. This involves using RPC providers (e.g., Alchemy, Infura) for live chain state and leveraging specialized indexers (like The Graph or Goldsky) for complex historical queries. For example, to track a DAO's treasury, you would need to fetch token balances from its wallet addresses, query vesting contract schedules, and pull liquidity pool positions from protocols like Uniswap V3 or Aave. This layer must handle the nuances of different chains, such as EVM-based chains (Ethereum, Polygon) versus non-EVM chains (Solana, Cosmos), each requiring specific client libraries and query methods.
Once collected, data flows to the processing layer. Here, raw transactional data is transformed into financial metrics. This includes calculating the USD value of token holdings using real-time price oracles (Chainlink, Pyth), computing unrealized gains/losses from LP positions, and aggregating totals across all tracked wallets. This processed data is then stored in a time-series database (e.g., TimescaleDB) or a cache (Redis) to enable fast queries for the dashboard. Implementing efficient data models here is critical for performance, especially when dealing with high-frequency updates or large historical datasets spanning thousands of blocks.
The final component is the presentation layer, which consists of a backend API (often built with Node.js, Python FastAPI, or Go) and a frontend interface. The API serves normalized data endpoints, such as /api/v1/treasury/summary or /api/v1/positions/history, which the frontend consumes. The dashboard itself, built with frameworks like React or Vue.js, visualizes this data through charts, tables, and key metric cards. For a complete view, you should display: total portfolio value, asset allocation across chains, protocol exposure, and recent transaction history. The system's real-time capability is typically achieved through WebSocket connections for live price feeds and polling mechanisms for on-chain state updates.
Core Dashboard Components to Build
A real-time treasury dashboard requires live data aggregation, risk visualization, and automated alerting. These are the essential components to build for monitoring on-chain assets and liabilities.
Counterparty Risk Dashboard
Visualize exposure to specific protocols, smart contracts, and centralized entities. This component maps treasury assets to their underlying risk vectors.
- Tracks: TVL in lending protocols (Aave, Compound), custody with CEXs, and deposits in bridge contracts.
- Integrates: Risk scores from platforms like Gauntlet or internal audit reports.
- Alerts: Flag concentrations exceeding a predefined threshold (e.g., >20% of treasury in a single lending pool).
Portfolio Performance & APY Calculator
Calculates the real-time yield and overall return of the treasury's deployed capital across staking, lending, and liquidity provision.
- Aggregates: Staking rewards (e.g., from Lido, Rocket Pool), lending interest (Aave), and LP fees (Uniswap).
- Calculates: Realized and unrealized P&L based on current token prices versus entry points.
- Output: Shows annualized percentage yield (APY) for each position and the total portfolio, helping assess strategy effectiveness.
Step 1: Backend Setup and Contract Interaction
This guide walks through building a Node.js backend to fetch and process real-time treasury data from smart contracts on Ethereum and other EVM chains.
A robust backend is essential for aggregating and serving real-time on-chain data. We'll use Node.js with Ethers.js v6 for its comprehensive Ethereum interaction capabilities. The core tasks involve connecting to a blockchain node via a provider (like Alchemy or Infura), instantiating contract objects using their Application Binary Interface (ABI), and calling specific view functions to retrieve state data such as token balances, total supply, and governance parameters. This setup forms the data ingestion layer for your treasury dashboard.
First, initialize your project and install the required dependencies: npm init -y followed by npm install ethers dotenv. Create a .env file to securely store your provider's RPC URL (e.g., ALCHEMY_MAINNET_URL). In your main script, import Ethers and load environment variables. Establish a connection using new ethers.JsonRpcProvider(process.env.RPC_URL). This provider object is your gateway to reading data from the blockchain without needing a private key.
To interact with a contract, you need its address and ABI. For standard tokens like ERC-20, you can use Ethers's built-in interfaces. For custom treasury or vault contracts, you'll need the specific ABI, often available from the project's GitHub repository or block explorers like Etherscan. Instantiate the contract object: new ethers.Contract(CONTRACT_ADDRESS, CONTRACT_ABI, provider). You can now call any view or pure function on this object, such as contract.balanceOf(address) or contract.totalSupply(), which return Promise objects with the queried data.
Treasury management requires tracking multiple assets across different protocols. You will likely need to query several contracts in parallel. Use Promise.all() to fetch data from multiple sources efficiently. For example, to get the balance of three different ERC-20 tokens held by a treasury address, you would create an array of contract instances and map over them to call balanceOf. Always handle potential RPC errors and null returns gracefully with try/catch blocks to ensure your service remains resilient.
The raw data from the blockchain is often in the form of BigInt for numbers, which needs to be formatted for display. Use Ethers's formatting utilities, like ethers.formatUnits(balance, decimals), to convert token balances from their base unit (e.g., wei) into a human-readable decimal string. Structuring this formatted data into a consistent JSON object is the final step for this backend module, ready to be served via an API endpoint to your frontend application.
Step 2: Fetching and Caching Token Balances
This step focuses on efficiently retrieving and storing the core data for your treasury dashboard: the real-time token balances across all tracked wallets and chains.
The foundation of any treasury dashboard is accurate, up-to-date token balance data. For a multi-chain treasury, this requires querying the blockchain state for each wallet address across multiple networks. Instead of making direct RPC calls on every page load—which is slow and can hit rate limits—you should implement a caching layer. A common pattern is to use a scheduled backend job (e.g., a cron job) that periodically fetches balances via providers like Alchemy, Infura, or the Chainscore API, and stores the aggregated results in a database like PostgreSQL or a key-value store like Redis.
When fetching balances, you must handle both native tokens (like ETH on Ethereum or MATIC on Polygon) and ERC-20 tokens. For native balances, a simple eth_getBalance RPC call suffices. For ERC-20s, you need to call the token contract's balanceOf function for each wallet. Optimizing this process is critical; batch RPC requests using eth_call with multiple contract addresses or using a provider's specialized multicall endpoint can reduce the number of network calls from hundreds to one or two per chain.
Your data schema should capture the essential details for each balance snapshot: the wallet_address, chain_id, token_address (use 0x0 for native gas tokens), token_symbol, balance (as a raw integer), balance_usd (calculated value), and a timestamp. Storing the raw integer balance is important for precision, while the USD value should be calculated using a reliable price feed, such as CoinGecko's or Chainlink's oracles, fetched in the same cron cycle.
The caching strategy's refresh frequency is a trade-off between data freshness and performance. For most treasury views, updating balances every 5-15 minutes is sufficient. However, you may want to trigger an immediate cache invalidation and refresh after a large transaction is detected. This can be done by monitoring wallet addresses for outgoing transactions using webhooks from services like Chainscore Alerts or Tenderly.
Finally, your backend API should expose a simple endpoint, such as GET /api/v1/treasury/balances, that returns the cached, aggregated data. The response should be structured for easy consumption by your frontend charting library, often grouping balances by chain or wallet. This separation of data fetching (backend/cron) from data presentation (frontend) ensures your dashboard loads instantly while displaying near-real-time information.
Step 3: Building the Transaction History Feed
Transform raw blockchain data into a structured, real-time log of treasury activity. This feed is the foundation for all dashboards and alerts.
A transaction history feed is more than a simple list of transfers. For treasury management, it must be a normalized data stream that aggregates activity from multiple chains and protocols into a single, coherent timeline. The core challenge is mapping raw on-chain events—like Transfer, Swap, or Deposit—to human-readable, categorized entries. This requires decoding transaction inputs, interpreting event logs, and enriching data with off-chain metadata such as token symbols and protocol names from sources like the Token Lists repository.
To build this feed, you need to ingest data from blockchain nodes or indexers. For Ethereum and EVM chains, you can subscribe to new blocks via WebSocket using libraries like ethers.js or viem. For each block, filter transactions involving your treasury's wallet addresses. Then, decode the transaction data and parse the event logs using the contract's Application Binary Interface (ABI). For complex DeFi interactions, you may need to trace internal calls using a node's debug_traceTransaction method to see the full flow of funds.
Here is a simplified code snippet using viem to watch for Transfer events from a specific ERC-20 contract to a treasury address:
javascriptimport { createPublicClient, http, parseAbiItem } from 'viem'; import { mainnet } from 'viem/chains'; const client = createPublicClient({ chain: mainnet, transport: http() }); const usdcContract = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'; const treasuryAddress = '0xYourTreasuryAddress'; const transferEvent = parseAbiItem( 'event Transfer(address indexed from, address indexed to, uint256 value)' ); const unwatch = client.watchEvent({ address: usdcContract, event: transferEvent, args: { to: treasuryAddress }, onLogs: (logs) => { logs.forEach(log => { console.log(`USDC Incoming: ${log.args.value} from ${log.args.from}`); }); }, });
This creates a real-time listener for incoming USDC transfers.
After capturing raw events, the critical step is enrichment and normalization. Each entry in your feed should contain standardized fields: timestamp, chain ID, transaction hash, category (e.g., Transfer In, DEX Swap, Yield Earned), involved addresses, token amounts (in both raw and decimal format), USD value at time of transaction, and a link to a block explorer. Calculating USD value requires a historical price oracle; you can query decentralized oracle networks or use indexed data from services like Chainscore's historical price API.
Finally, this enriched feed must be stored in a queryable database (like PostgreSQL or TimescaleDB) and exposed via an API for your frontend dashboard. Implementing pagination, filtering by asset or protocol, and WebSocket subscriptions for live updates are essential for a professional interface. The completed feed turns chaotic, multi-chain data into an auditable, real-time source of truth for all subsequent treasury analysis and reporting.
Step 4: Monitoring Pending Approvals and State
Learn how to track pending transactions and monitor on-chain state to maintain an accurate, real-time view of your treasury's health and security posture.
A real-time treasury dashboard is only as good as its data. Static snapshots of token balances are insufficient for active management. You must monitor two critical dynamic states: pending transaction approvals and the real-time on-chain state of your treasury contracts. Pending approvals represent the most significant security risk, as they are pre-signed permissions that could be exploited before you notice a balance change. Real-time state monitoring ensures your view reflects the latest blockchain data, not cached or delayed information from an indexer.
To track pending approvals, you need to query the blockchain for the allowance granted by your treasury's EOA or smart contract wallet to specific spender addresses (like DEX routers or lending protocols). This is done by calling the allowance(owner, spender) function on ERC-20 token contracts. For example, to check USDC allowances on Ethereum, you would call the function on the USDC contract. You should automate this check across all assets and known external protocols, setting up alerts for any new or increased allowances that weren't explicitly authorized by your governance process.
Monitoring real-time state involves directly polling RPC nodes or using services like Chainscore's real-time data streams to get the latest block information. Key metrics to track include: native token balance (ETH, MATIC, etc.), ERC-20 token balances via balanceOf, and the status of any active positions in DeFi protocols (e.g., debt in Aave, LP shares in Uniswap V3). Implement a fallback mechanism that compares data from multiple RPC providers to avoid relying on a single potentially stale or censored node.
For actionable insights, calculate derived metrics from this raw state data. This includes: total portfolio value (using real-time oracles like Chainlink), approval risk exposure (sum of all allowances per token), and concentration risk (percentage of holdings in a single asset or protocol). Visualize these in your dashboard with clear thresholds; for instance, flag any single token allowance exceeding 5% of the treasury's total value. This transforms raw blockchain data into a risk management tool.
Finally, integrate this monitoring with your alerting system. Use webhooks to send notifications to Slack, Discord, or email when critical events occur: a new approval is set, a large balance change is detected, or a risk metric breaches a defined threshold. The goal is to create a closed-loop system where the dashboard not only displays information but also proactively informs custodians of required actions, enabling true real-time treasury management and threat response.
Key Data Sources and RPC Methods
Comparison of primary methods for fetching real-time treasury data from EVM chains.
| Data Type | Public RPC | Specialized Node Provider | Indexing Service |
|---|---|---|---|
Native Token Balance | |||
ERC-20 Token Holdings | |||
ERC-721/1155 NFTs | |||
Historical Token Transfers | |||
DeFi Position State (e.g., Aave, Compound) | |||
Gas Cost for Query | User pays | Provider plan | API subscription |
Typical Latency | 1-3 sec | < 1 sec | < 500 ms |
Rate Limits | Low (public) | High/Configurable | Very High |
Step 5: Frontend UI and Real-Time Updates
This guide covers building a React-based frontend to visualize treasury data and implementing WebSocket connections for live updates.
A functional frontend transforms raw on-chain data into an actionable dashboard. For a treasury management view, you'll need to display key metrics like total value locked (TVL), asset allocation across chains, recent transactions, and protocol revenue. Using a framework like React with TypeScript provides type safety and a component-based architecture. Essential libraries include wagmi and viem for blockchain interactions, TanStack Query for efficient data fetching and caching, and a charting library like Recharts or Chart.js for visualizations. The UI should be organized into clear sections: a summary header, asset breakdown charts, a transaction history table, and protocol-specific performance indicators.
To achieve real-time updates, you must move beyond simple HTTP requests. While TanStack Query's refetchInterval can poll for changes, it's inefficient for high-frequency data. The optimal solution is to establish a WebSocket connection to a backend service that subscribes to blockchain events. Your React app can connect to this WebSocket server using the native WebSocket API or a library like socket.io-client. Upon connection, the server pushes new data—such as a confirmed deposit, withdrawal, or price change—directly to the client. This allows the dashboard to update instantly without user interaction, providing a true live view of treasury activity.
Implementing the WebSocket integration requires handling connection states and message parsing. In your React component, use a useEffect hook to establish the connection and set up event listeners for onopen, onmessage, and onclose. Incoming messages, typically in JSON format, should be validated and then used to update the application's state, often via a state management solution like Zustand or Redux Toolkit. For example, a message containing a new transaction should append to the existing transaction list in the global store, triggering a re-render of the relevant UI component. Always include reconnection logic to handle dropped connections gracefully.
The final step is optimizing performance and user experience. Use React.memo and useCallback to prevent unnecessary re-renders of complex chart components when new data streams in. Implement skeleton loaders for initial data fetch and visual indicators like toast notifications for significant live events (e.g., "New deposit of 100 ETH confirmed"). For public dashboards, consider adding read-only mode using public RPC endpoints or services like The Graph for historical queries, reserving the live WebSocket feed for authenticated users or premium features. The complete application provides a powerful, real-time window into multi-chain treasury management.
Essential Resources and Tools
These tools and concepts help teams build a real-time treasury management view across wallets, protocols, and chains. Each card focuses on a concrete component you can integrate into an internal dashboard or monitoring pipeline.
Frequently Asked Questions
Common questions and troubleshooting for developers building and integrating real-time treasury dashboards with on-chain data.
A real-time treasury management view is a dashboard that aggregates and visualizes a protocol's or DAO's on-chain financial position. It works by connecting to blockchain nodes and indexers to pull live data on assets, liabilities, and revenue streams across multiple chains and protocols.
Core components include:
- Data Ingestion: Using RPC providers (Alchemy, Infura) and subgraphs (The Graph) to fetch token balances, transaction history, and DeFi positions.
- Portfolio Aggregation: Consolidating holdings from wallets, smart contracts (like Gnosis Safe), and liquidity pools (Uniswap v3, Aave).
- Real-time Updates: Leveraging WebSocket connections or frequent polling to reflect price changes and new transactions instantly.
- Analytics Layer: Calculating metrics like Total Value Locked (TVL), runway, yield earned, and exposure to specific assets or protocols.