·Transfa Team

How to Track Wallet Balances and Transfers on Tempo

Query wallet balances, transfer history, and transaction activity on Tempo using the Transfa Data API instead of raw RPC calls.

tempowalletstransfersdata-api

Tracking wallet activity on most blockchains means parsing raw transaction logs, decoding event data, and maintaining your own indexer. On Tempo, you can skip all of that. The Transfa Data API provides indexed, queryable wallet data (balances, transfers, transactions) through simple REST endpoints backed by ClickHouse.

This guide covers every wallet-related query available in the API, with code examples in cURL, JavaScript, and Python.

Prerequisites

Why not use raw RPC calls

Getting a wallet's token balances on Tempo means calling balanceOf() on every TIP-20 token contract individually. If a wallet holds 20 tokens, that's 20 RPC calls. For transfer history, you need to scan event logs with eth_getLogs, decode the topics, handle pagination across block ranges, and deal with rate limits. And eth_getBalance returns a meaningless number because there's no native token. The actual balances live in TIP-20 token contracts.

The Data API indexes all on-chain state into a queryable database. One API call replaces dozens of RPC calls.

Get all token balances for a wallet

A single call returns every TIP-20 token balance for an address:

curl -X GET "https://api.transfa.com/v1/wallets/0xYOUR_ADDRESS/balances?chain=moderato&expandToken=true" \
  -H "x-api-key: YOUR_API_KEY"

Example response:

{
  "data": [
    {
      "tokenAddress": "0x20c0000000000000000000000000000000000001",
      "balance": "1500000000",
      "token": {
        "name": "AlphaUSD",
        "symbol": "AlphaUSD",
        "decimals": 6
      }
    },
    {
      "tokenAddress": "0x20c0000000000000000000000000000000000000",
      "balance": "250000000",
      "token": {
        "name": "pathUSD",
        "symbol": "pathUSD",
        "decimals": 6
      }
    }
  ]
}

Amounts are uint256 strings with 6 decimals. "1500000000" = 1,500.000000 AlphaUSD. Never parse these as floats. Use BigInt or decimal libraries in your application code.

Query transfer history

Get the transfer history for a wallet, with optional filters for direction, token, and date range:

curl -X GET "https://api.transfa.com/v1/wallets/0xYOUR_ADDRESS/transfers?chain=moderato" \
  -H "x-api-key: YOUR_API_KEY"

Example response:

{
  "data": [
    {
      "from": "0xSENDER",
      "to": "0xYOUR_ADDRESS",
      "tokenAddress": "0x20c0000000000000000000000000000000000001",
      "amount": "500000000",
      "balanceBefore": "1000000000",
      "balanceAfter": "1500000000",
      "blockTimestamp": 1707523200,
      "transactionHash": "0xabc...",
      "direction": "credit"
    }
  ]
}

The balanceBefore and balanceAfter fields are indexed by Transfa. They're not available from raw Transfer event logs. This is useful for reconciliation: you can verify that every transfer's balance change matches expectations without reconstructing state from scratch.

Filter transfers by direction

To get only incoming or outgoing transfers, add a direction query parameter:

# Only incoming transfers
curl -X GET "https://api.transfa.com/v1/wallets/0xYOUR_ADDRESS/transfers?chain=moderato&direction=credit" \
  -H "x-api-key: YOUR_API_KEY"
 
# Only outgoing transfers
curl -X GET "https://api.transfa.com/v1/wallets/0xYOUR_ADDRESS/transfers?chain=moderato&direction=debit" \
  -H "x-api-key: YOUR_API_KEY"

Filter by token

To see transfers for a specific stablecoin only:

curl -X GET "https://api.transfa.com/v1/wallets/0xYOUR_ADDRESS/transfers?chain=moderato&tokenAddress=0x20c0000000000000000000000000000000000001" \
  -H "x-api-key: YOUR_API_KEY"

Get decoded transaction activity

The /transactions endpoint returns transaction-level data with decoded TIP-20 transfer events, including balance snapshots:

curl -X GET "https://api.transfa.com/v1/wallets/0xYOUR_ADDRESS/transactions?chain=moderato" \
  -H "x-api-key: YOUR_API_KEY"
{
  "data": [
    {
      "transactionHash": "0xabc...",
      "blockNumber": 12345678,
      "blockTimestamp": 1707523200,
      "transfers": [
        {
          "from": "0xSENDER",
          "to": "0xYOUR_ADDRESS",
          "tokenAddress": "0x20c0000000000000000000000000000000000001",
          "amount": "500000000",
          "balanceBefore": "1000000000",
          "balanceAfter": "1500000000"
        }
      ]
    }
  ]
}

This is useful when a single transaction contains multiple transfers, like a batch transaction that distributes tokens to several recipients. The /transfers endpoint shows each transfer individually, while /transactions groups them by transaction hash.

Paginate through results

All list endpoints use cursor-based pagination. The response includes a pagination object with a nextCursor field when more results are available:

async function getAllTransfers(address, apiKey) {
  const transfers = [];
  let cursor = null;
 
  while (true) {
    const url = new URL(
      `https://api.transfa.com/v1/wallets/${address}/transfers`
    );
    url.searchParams.set("chain", "moderato");
    if (cursor) url.searchParams.set("afterCursor", cursor);
 
    const response = await fetch(url, {
      headers: { "x-api-key": apiKey },
    });
    const result = await response.json();
 
    transfers.push(...result.data);
 
    if (!result.pagination.hasMore) break;
    cursor = result.pagination.nextCursor;
  }
 
  return transfers;
}

Check allowances granted by a wallet

See all approve() allowances a wallet has granted:

curl -X GET "https://api.transfa.com/v1/wallets/0xYOUR_ADDRESS/allowances?chain=moderato" \
  -H "x-api-key: YOUR_API_KEY"

This is useful for security audits. You can quickly check which addresses have permission to move tokens on behalf of a wallet.

Build a wallet dashboard

Combining these endpoints, you can build a complete wallet view with a few API calls. Here's a minimal example in JavaScript:

const API_KEY = "YOUR_API_KEY";
const ADDRESS = "0xYOUR_ADDRESS";
const BASE = "https://api.transfa.com/v1";
const headers = { "x-api-key": API_KEY };
 
// Fetch balances and recent transfers in parallel
const [balancesRes, transfersRes] = await Promise.all([
  fetch(`${BASE}/wallets/${ADDRESS}/balances?chain=moderato&expandToken=true`, { headers }),
  fetch(`${BASE}/wallets/${ADDRESS}/transfers?chain=moderato`, { headers }),
]);
 
const balances = (await balancesRes.json()).data;
const transfers = (await transfersRes.json()).data;
 
// Display balances
for (const entry of balances) {
  const amount = Number(BigInt(entry.balance)) / 1e6;
  console.log(`${entry.token.symbol}: ${amount.toFixed(6)}`);
}
 
// Display recent transfers
for (const tx of transfers.slice(0, 5)) {
  const amount = Number(BigInt(tx.amount)) / 1e6;
  const direction = tx.direction === "credit" ? "received" : "sent";
  console.log(`${direction} ${amount} ${tx.tokenAddress}`);
}

Two API calls replace what would be dozens of RPC calls on a standard EVM chain, with no indexer required.

What to read next