Links
Comment on page
👋

Welcome to Flair

Real-time and historical custom data indexing for any evm chain
Flair offers reusable indexing primitives (such as fault-tolerant RPC ingestors, custom processors, re-org aware database integrations) to make it easy to receive, transform, store and access your on-chain data.
High-level Architecture: RPC -> Fault-tolerant ingestors -> Your custom processors -> Any destination (Postgres, MongoDB, etc)

Why Flair?

Compared to other alternatives the main reasons why are:
  • 🚀 Adopting parallel and distributed processing paradigm means high scalability and resiliency for your indexing stack. Instead of constrained sequential processing (e.g Subgraph).
  • 🧩 Focused on primitives, which means on the left you plug-in an RPC and on the right you output the data to any destination database.
  • 🚄 Native real-time stream processing for certain data workload (such as aggregations, rollups) for things like total volume per pool, or total portfolio per user wallet.
  • ☁️ Managed cloud services avoid DevOps and irrelevant engineering costs for dApp developers.
  • 🧑‍💻 Avoid decentralization overhead (consensus, network hops, etc) since we believe to enable best UX for dApps reading data must be as close to the developers as possible. Writing to blockchain is the main aspect to keep decentralized, not reading.

Features

  • ✅ Listen to any EVM chain with just an RPC URL.
    • Free managed RPC URLs for +8 popular chains already included.
    • Works with both websocket and https-only RPCs.
  • ✅ Track and ingest any contract for any event topic.
    • Auto-track new contracts deployed from factory contracts.
  • Custom processor scripts with Javascript runtime (with Typescript support)
    • Make external API or Webhook calls to third-party or your backend.
    • Get current or historical USD value of any ERC20 token amount of any contract address on any chain
    • Use any external NPM library.
  • Stream any stored data to your destination database (Postgres, MognoDB, Kafka, Elasticsearch, Timescale, etc)
  • ✅ Pre-built example template scripts for popular use-cases such as:
    • Storing your custom contract events in SQL database, with aggregations (SUM,AVG,etc)
    • Well-known protocols (Uniswap v2, v3, etc.) or standards (NFT, Vault, etc.)
    • Sending a Discord message to your protocol users on certain conditions.
    • Calculate and notify critical metrics (e.g health factor) for your DeFi protocol
    • ... and more.
    ╳ For generic pre-indexed blockchain data it will be more cost-effective to consider services that sell that data, instead of running an indexer. e.g. Try Dune which has already indexed most of generic blockchain data and can sell them cheaper than cost of indexing

Getting Started

  1. 1.
    Clone the starter boilerplate template and follow the instructions:
git clone https://github.com/flair-sdk/starter-boilerplate.git
# ... follow instructions in README.md
Boilerplate instructions will create a new cluster, generate an API Key, and set up a manifest.yml to index your first contract with sample custom processor scripts.
Learn more about the structure of manifest.yml.
  1. 2.
    Query your custom indexed data:
GraphQL
Node.js (Axios)
cURL
Visit https://graph.flair.dev and run this query:
Replace "fuji-finance" with your own namespace selected in step 1 above.
query {
sql(
# Any arbitrary SQL query with JOIN or aggregations on your entities
query:
"""
SELECT
COUNT(*) as totalCount,
entityType
FROM entities WHERE namespace = 'fuji-finance'
GROUP BY entityType
ORDER BY totalCount DESC LIMIT 100
"""
) {
stats {
elapsedMs
}
rows
}
}
Make sure Axios is installed (npm install axios) and execute this code:
Replace "fuji-finance" with your own namespace selected in step 2 above.
const axios = require('axios');
const query = `
query {
sql(
query:
"""
SELECT
COUNT(*) as totalCount,
entityType
FROM entities WHERE namespace = 'fuji-finance'
GROUP BY entityType
ORDER BY totalCount DESC LIMIT 100
"""
) {
stats {
elapsedMs
}
rows
}
}
`;
const fetchRows = async () => {
const response = await axios.post('https://graph.flair.dev', {
query: query,
}, {
headers: {
'Content-Type': 'application/json',
},
});
return response.data.data.sql.rows;
};
fetchRows().then(console.log);
Send a SQL query to the global graph using curl command:
Replace "fuji-finance" with your own namespace selected in step 2 above.
curl -X POST -H "Content-Type: application/json" -d @- "https://graph.flair.dev" <<-'EOF'
{
"query": "query { sql( query: \"SELECT COUNT(*) as totalCount, entityType FROM entities WHERE namespace = 'fuji-finance' GROUP BY entityType ORDER BY totalCount DESC LIMIT 100\") { stats { elapsedMs } rows } }"
}
EOF
  1. 3.
    Stream the data to your own database.

What next?

Tap into available features and primitives to make the best out of the indexing toolbox:
Learn about some advanced features if you want to expand your work:
Last modified 2mo ago