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";processor.run(new TypeormDatabase(), async (ctx) => { const prices: TokenPrice[] = []; for (let block of ctx.blocks) { // Fetch the historical price once per block and attach it to // whatever entities you derive from the block's data. const price = await getTokenPriceByDate(block.header.timestamp); prices.push( new TokenPrice({ id: `${block.header.height}`, block: block.header.height, price, }) ); } await ctx.store.save(prices);});async function getTokenPriceByDate(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 block, 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.
processor.run(new TypeormDatabase(), async (ctx) => { for (let block of ctx.blocks) { // Pull metadata URIs out of this block's decoded items, // then enrich each one: for (let { tokenId, tokenURI, cid } of extractMetadataRefs(block)) { // 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, }) ); } } }});