Bancor Subgraph
Introducing the Bancor subgraph. This public infrastructure allows developers to query details about the Bancor network activity quickly and easily.
The subgraph is in development - expect changes to make common data pulls easier and bug fixes.
- Go directly to the Bancor Subgraph
- Review development notes below
- Grab implementation examples below for Python and React
- Send questions and feedback to hello@blocklytics.org
About Bancor
Bancor is a decentralized cross-chain liquidity protocol. Bancor enables peer-to-contract swaps between cryptocurrency assets.
About The Graph
The Graph uses specialized, open source nodes to index and serve data with GraphQL endpoints. You can run these nodes locally or use public endpoints.
About GraphQL
GraphQL is an open source data query language. Its advantage to REST APIs is the ability for developers to specify a complex data structure and have results returned that exactly fit that structure.
Development Status
Last updated February 3, 2020
The Bancor Subgraph is in active development with new deployments based on feedback and issues.
Usage notes
- Converter { tokenBalances } includes smart tokens with total supply as indicated as a converter balance. Filter these out using Converter { smartToken { id } }
- SmartToken includes some normal ERC-20 tokens.
- Not all tokens are ERC-20 compliant. Token details may be missing, including decimals. Implement error handling when converting balances and displaying name or symbols.
Known issues
Submit via hello@blocklytics.org
- There are inaccurate tokenBalances for a specific set of older converters. Filter these out using this query as a basis.
- There are inaccurate userTokenBalances for some specific conditions. Avoid relying on this for now.
Using the Bancor Subgraph
Example usage from:
- Web UI
- Python
- React
Web UI
The Graph website offers a tool to query the subgraph. This is suitable for exploring data and planning your own queries.
- Open subgraph
- Use the example queries in the drop down menu (top left)
- Enter your query (left pane)
- Press the run button (top right) to fetch results (right pane)
Python
Suggested library: https://pypi.org/project/graphqlclient/
Sample query to get converters and their current balances:
from graphqlclient import GraphQLClient
import json
# Use this for the current version
ENDPOINT = "https://api.thegraph.com/subgraphs/name/blocklytics/bancor"
client = GraphQLClient(ENDPOINT)
QUERY = """
{
converters(first:50, skip:0) {
id
smartToken {
id
symbol
decimals
}
tokenBalances {
token {
id
symbol
decimals
}
balance
}
}
}
"""
result = json.loads(client.execute(QUERY))
converters = result['data']['converters']
for converter in converters:
# Skip empty converters
if len(converter['tokenBalances']) == 0:
continue
converter_address = converter['id']
smart_token_address = converter['smartToken']['id']
smart_token_symbol = converter['smartToken']['symbol']
smart_token_decimals = converter['smartToken']['decimals']
print("Converter: {0}\nSmart token: {1}\n".format(
converter_address,
smart_token_symbol
))
for tokenBalance in converter['tokenBalances']:
balance = tokenBalance['balance']
token = tokenBalance['token']['id']
symbol = tokenBalance['token']['symbol']
decimals = tokenBalance['token']['decimals']
balance_converted = float(balance) / 10 ** float(decimals)
print("{2:,.0f} {1} ({0})".format(
token, symbol, balance_converted
))
print("------\n")
React
Suggested library: https://www.apollographql.com/docs/react/get-started/
import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import ApolloClient, { gql } from 'apollo-boost';
// Use this for the current version
const ENDPOINT = "https://api.thegraph.com/subgraphs/name/blocklytics/bancor"
const client = new ApolloClient({
uri: ENDPOINT,
});
const QUERY = gql`
{
converters(
first: 10, skip: 0,
orderBy:bntBalance,
orderDirection:desc,
where:{ bntBalance_not:null }) {
id
smartToken {
id
name
decimals
}
conversionFee
bntBalance
tokenBalance
weight
}
}
`;
function ExchangeRates() {
const { loading, error, data } = useQuery(QUERY);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error :(</p>;
return data.converters.map(({ id, bntBalance, tokenBalance }) => (
<div key={id}>
<p>
{id}: {bntBalance / tokenBalance}
</p>
</div>
));
}