Beginner15 min read
Edit on GitHub

Build a Balance Checker

Query UTxOs and calculate the total ADA balance for any Cardano address

In this tutorial, you'll build a balance checker that queries the Cardano blockchain and calculates the total ADA balance for any address.

What You'll Build

A function that:

  1. Connects to the Nacho API via WebSocket
  2. Queries UTxOs for a given address
  3. Sums up the ADA values to get the total balance
  4. Handles native tokens in the UTxOs

Prerequisites

  • Node.js 18+ installed
  • A Nacho API key (get one here)
  • Basic TypeScript/JavaScript knowledge

Step 1: Set Up Your Project

Create a new project and install dependencies:

mkdir balance-checker && cd balance-checker
npm init -y
npm install ws

Create a .env file with your API key:

NACHO_API_KEY=napi_your_key_here

Step 2: Connect to the API

The Nacho API uses WebSocket connections with the Ogmios JSON-RPC protocol. Here's how to connect:

import WebSocket from 'ws'

const API_KEY = process.env.NACHO_API_KEY
const WS_URL = 'wss://api.nacho.builders/v1/ogmios'

function connect(): Promise<WebSocket> {
return new Promise((resolve, reject) => {
  const ws = new WebSocket(WS_URL, {
    headers: { 'apikey': API_KEY }
  })

  ws.on('open', () => {
    console.log('Connected to Nacho API')
    resolve(ws)
  })

  ws.on('error', reject)
})
}

Step 3: Query UTxOs

Now let's query the UTxOs for an address:

interface Utxo {
transaction: { id: string }
index: number
value: {
  ada: { lovelace: number }
  [policyId: string]: any
}
}

async function queryUtxos(ws: WebSocket, address: string): Promise<Utxo[]> {
return new Promise((resolve, reject) => {
  const request = {
    jsonrpc: '2.0',
    method: 'queryLedgerState/utxo',
    params: { addresses: [address] },
    id: 'query-utxos'
  }

  ws.send(JSON.stringify(request))

  ws.once('message', (data) => {
    const response = JSON.parse(data.toString())
    if (response.error) {
      reject(new Error(response.error.message))
    } else {
      resolve(response.result)
    }
  })
})
}

Step 4: Calculate the Balance

Sum up the ADA from all UTxOs:

function calculateBalance(utxos: Utxo[]): { ada: number; lovelace: bigint } {
let totalLovelace = BigInt(0)

for (const utxo of utxos) {
  totalLovelace += BigInt(utxo.value.ada.lovelace)
}

return {
  lovelace: totalLovelace,
  ada: Number(totalLovelace) / 1_000_000
}
}

Step 5: Put It All Together

Here's the complete balance checker:

import WebSocket from 'ws'

const API_KEY = process.env.NACHO_API_KEY!
const WS_URL = 'wss://api.nacho.builders/v1/ogmios'

async function getBalance(address: string): Promise<number> {
const ws = await connect()

try {
  const utxos = await queryUtxos(ws, address)
  const balance = calculateBalance(utxos)

  console.log(`Address: ${address}`)
  console.log(`UTxOs: ${utxos.length}`)
  console.log(`Balance: ${balance.ada.toFixed(6)} ADA`)

  return balance.ada
} finally {
  ws.close()
}
}

// Example usage
const address = 'addr1qy2kp7ux2qx7g9h6m8rv4dpuqwfcv2t4a8h5yfjhgpvqc8...'
getBalance(address)

Handling Native Tokens

UTxOs can also contain native tokens. Here's how to extract them:

interface TokenBalance {
  policyId: string
  assetName: string
  quantity: bigint
}

function extractTokens(utxos: Utxo[]): TokenBalance[] {
  const tokens: Map<string, TokenBalance> = new Map()

  for (const utxo of utxos) {
    for (const [policyId, assets] of Object.entries(utxo.value)) {
      if (policyId === 'ada') continue

      for (const [assetName, quantity] of Object.entries(assets)) {
        const key = `${policyId}.${assetName}`
        const existing = tokens.get(key)

        if (existing) {
          existing.quantity += BigInt(quantity)
        } else {
          tokens.set(key, { policyId, assetName, quantity: BigInt(quantity) })
        }
      }
    }
  }

  return Array.from(tokens.values())
}

Common Issues

Empty Response

If you get an empty UTxO array, the address might:

  • Have no funds
  • Be an invalid address format
  • Be on the wrong network (mainnet vs preprod)

Connection Timeout

If the WebSocket connection times out:

  • Check your API key is valid
  • Ensure you're using the correct endpoint
  • Check your network connection

Next Steps

Now that you can check balances, learn how to send transactions:

Next: Build a Transaction Sender

Was this page helpful?