Enrich blockchain data with external APIs and IPFS in your Squid SDK indexer.
Squid processors are standard Node.js processes, enabling you to fetch data from external APIs or IPFS gateways right in the batch handler. This allows you to enrich blockchain data with off-chain information.
For squids deployed to SQD Cloud, use API calls in combination with
API keys set via secrets for secure access.
You can enrich indexed transactions with historical price data using external APIs like CoinGecko:
main.ts
import axios from "axios";import moment from "moment";import {augmentBlock} from "@subsquid/evm-objects";run(dataSource, new TypeormDatabase(), async (ctx) => { const burns: Burn[] = []; for (let block of ctx.blocks.map(augmentBlock)) { for (let txn of block.transactions) { burns.push( new Burn({ id: txn.id, block: block.header.number, address: txn.from, value: txn.value, txHash: txn.hash, price: await getETHPriceByDate(block.header.timestamp), }) ); } } await ctx.store.save(burns);});async function getETHPriceByDate(timestamp: number): Promise<number> { const formatted = moment(new Date(timestamp).toISOString()).format( "DD-MM-YYYY" ); const res = await axios.get( `https://api.coingecko.com/api/v3/coins/ethereum/history?date=${formatted}&localization=false` ); return res.data.market_data.current_price.usd;}
Use caching mechanisms to avoid hitting rate limits and improve performance
when fetching external data.
The example above awaits an external call for every transaction, which can dominate sync time. Fetch each distinct input (e.g. one price per day) once and reuse it, and keep database writes batched as described in the batch processing guide.
run(dataSource, new TypeormDatabase(), async (ctx) => { for (let block of ctx.blocks) { for (let log of block.logs) { // Decode an NFT event to get the metadata URI const { tokenId, tokenURI } = decodeNFTEvent(log); const cid = extractCID(tokenURI); // Fetch metadata from IPFS const metadata = await fetchMetadata(cid); if (metadata) { // Store the entity with its off-chain metadata await ctx.store.save( new Token({ id: tokenId, uri: tokenURI, name: metadata.name, image: metadata.image, attributes: metadata.attributes, }) ); } } }});