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
- A Transfa API key (sign up at app.transfa.com)
- A Tempo wallet address to query (use one of the funded testnet addresses from How to Get Started Building on Tempo)
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
- How to Get Started Building on Tempo: set up your environment and send your first transfer
- How to Create a TIP-20 Token on Tempo: deploy and configure your own stablecoin
- Transfa Data API reference: full endpoint documentation with request/response schemas