# Welcome to Agnostic

## Quick links

{% content-ref url="/pages/lfmr5j3h97OTClUMO7Yx" %}
[Uniswap V3](/tutorials/uniswap-v3)
{% endcontent-ref %}

{% content-ref url="/pages/qiPlya56hZuDJHFGW8u1" %}
[Introducing Agnostic](/overview/introducing-agnostic)
{% endcontent-ref %}

{% content-ref url="/pages/67HoTNH8uH0YCe70hqv3" %}
[Our Features](/overview/our-features)
{% endcontent-ref %}

## Overview

{% hint style="info" %}
Here are some quotes that define our goals and the philosophy of Agnostic
{% endhint %}

> Paradoxically, while most blockchains consist of publicly available, open lists of records, it is extremely complicated to extract *useful* data from a blockchain \[...] [Agnostic ](https://agnostic.engineering/)is tackling the issue of blockchain data accessibility by providing a platform to help developers access decoded data in real time.
>
> — From [Blueyard](https://blueyard.medium.com/agnostic-aa864b5f9a10)

> Our journey through the complexities of EVM-compatible blockchain data access has been one of discovery, innovation, and growth. As we continue to develop Agnostic, we remain dedicated to empowering builders and analysts with the tools they need to unlock the full potential of the Web3 world. Together, we will shape the future of decentralized technology and create a more open, transparent, and secure digital ecosystem.
>
> — From the [CEO](https://medium.com/agnosticeng/taming-the-beast-a-journey-through-blockchain-data-access-with-agnostic-664bc0447c90)

## Collaborate

We've put together some helpful guides for you to get setup with our product quickly and easily.

{% content-ref url="/pages/gtvqX3JMETCbwN7KyoHD" %}
[Collaborate with your team](/fundamentals/collaborate-with-your-team)
{% endcontent-ref %}

{% content-ref url="/pages/soarWihqByMG4dZufpZq" %}
[Setting permissions](/fundamentals/collaborate-with-your-team/setting-permissions)
{% endcontent-ref %}

{% content-ref url="/pages/VZZc7Lbh4orbpEgu1tV0" %}
[Inviting Members](/fundamentals/collaborate-with-your-team/inviting-members)
{% endcontent-ref %}


# Introducing Agnostic

### Welcome to Agnostic

Welcome to the revolutionary world of **Agnostic**, where blockchain data is unlocked and possibilities are limitless. Our cutting-edge platform empowers engineers like you to harness the full potential of blockchain technology and supercharge your applications with unparalleled insights.

### Simplify Blockchain Development

With Agnostic, you can effortlessly navigate the complex blockchain landscape, gaining deep visibility into transactions, smart contracts, and decentralized applications. Say goodbye to the challenges of working with disparate blockchain data sources and embrace a unified, seamless experience that simplifies your development process.

### Comprehensive Documentation

Our **comprehensive documentation** is your gateway to success. Whether you're a seasoned blockchain expert or just embarking on your journey, our user-friendly resources will guide you every step of the way. Dive into detailed tutorials, discover best practices, and easily unlock the secrets of blockchain data manipulation.

### Powerful Features and Intuitive APIs

Gain a competitive edge with Agnostic's powerful features and intuitive APIs. Seamlessly integrate blockchain data into your applications, uncover valuable insights, and deliver exceptional user experiences. From real-time transaction monitoring to comprehensive analytics, our platform equips you with the tools to build innovative, data-driven solutions.

### Join a Vibrant Community

Join a vibrant community of forward-thinking engineers shaping blockchain technology's future. Collaborate, share knowledge, and exchange ideas to unlock new frontiers in blockchain development. Our documentation serves as your compass, providing you with the knowledge and inspiration to drive your projects forward.

### Unleash the Power of Blockchain Data

Are you ready to revolutionize your approach to blockchain data? Embrace Agnostic and unlock a world of possibilities. Let our documentation be your trusted guide on this exciting journey. Together, let's unleash the power of blockchain data and build a future powered by innovation and limitless potential.

{% hint style="success" %}
Welcome to the Agnostic Documentation – your gateway to blockchain success. Let's embark on this transformative adventure together!
{% endhint %}


# Our Features

### Key Features of Agnostic

#### SQL Query Language

Agnostic provides a powerful SQL query language that allows engineers to interact with blockchain data seamlessly. With the familiarity of SQL, engineers can perform complex data manipulations, aggregations, and filtering operations. SQL's intuitive and expressive nature makes it easy for engineers to extract valuable insights and perform an in-depth analysis of blockchain data.

#### Compatibility with EVM-Compatible Blockchains

Agnostic is designed to support EVM-compatible blockchains such as Ethereum, Arbitrum, and Polygon. This ensures seamless integration and comprehensive support for these networks, enabling engineers to quickly access and analyze blockchain data. By leveraging the capabilities of EVM-compatible blockchains, engineers can tap into the rich ecosystem of decentralized applications and smart contracts.

#### GraphQL API Generation

With Agnostic, engineers can generate a GraphQL API directly from SQL queries. This powerful feature provides flexibility for engineers who prefer working with GraphQL, a popular query language for APIs. By generating a GraphQL API from SQL, engineers can combine the simplicity and expressiveness of SQL with the flexibility and capabilities of GraphQL, enabling them to build efficient and powerful data-driven applications.

#### Integrated Development Environment (IDE)

Agnostic comes with an intuitive and feature-rich Integrated Development Environment (IDE) that enhances the productivity of engineers. The IDE offers intelligent autocomplete, syntax highlighting, and query execution capabilities, making data exploration and analysis a breeze. With a user-friendly interface and powerful tools at their disposal, engineers can easily craft SQL queries, visualize data, and iterate on their analysis process.

#### Seamless Integration with Analytics and Monitoring Tools

Agnostic seamlessly integrates with popular analytics and monitoring tools such as Grafana and Superset. This integration allows engineers to effortlessly connect Agnostic to their existing analytics and monitoring pipelines, enabling them to visualize and monitor blockchain data in real-time. By leveraging the power of these tools, engineers can create rich dashboards, perform advanced analytics, and gain valuable insights from their blockchain data.

#### Serverless and Scalable Architecture

Agnostic is meant to be serverless architecture brick, ensuring high availability, scalability, and cost efficiency. Engineers can focus on data analysis and application development without worrying about infrastructure management or scalability concerns. Agnostic handles the heavy lifting behind the scenes, providing a seamless and scalable experience that allows engineers to unleash their creativity and build innovative blockchain-powered solutions fully.

These key features empower engineers to unlock the full potential of blockchain data and drive innovation in their projects. With Agnostic, engineers can effortlessly explore, analyze, and leverage blockchain data, opening up new possibilities for decentralized applications and smart contract development.


# Execution Layer


# Blocks

The core EVM blockchain data collection

## Availability

{% hint style="success" %}
This collection is available for **Ethereum**, **Polygon,** **Arbitrum,** and **Base**.
{% endhint %}

| Points-of-Presence | Tables                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| eu-west-1          | <p><mark style="color:blue;"><code>evm\_blocks\_ethereum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>evm\_blocks\_arbitrum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>evm\_blocks\_polygon\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>evm\_block\_base\_mainnet\_v1</code></mark></p> |

## Table Schema

<table data-full-width="true"><thead><tr><th>Column Name</th><th>Column Type</th><th>Description</th></tr></thead><tbody><tr><td>chain_name</td><td>string</td><td>Name of the chain (eg: ethereum, arbitrum, polygon, ...)</td></tr><tr><td>chain_network_name</td><td>string</td><td>Name of the network (eg: mainnet)</td></tr><tr><td>hash</td><td>string</td><td>Block hash encoded as binary string</td></tr><tr><td>number</td><td>uint64</td><td>Block height</td></tr><tr><td>parent_hash</td><td>string</td><td>Hash of the block's parent</td></tr><tr><td>transactions_root</td><td>string</td><td>Root of the transaction trie of the block</td></tr><tr><td>state_root</td><td>string</td><td>Root of the final state trie of the block</td></tr><tr><td>receipts_root</td><td>string</td><td>Root of the receipts trie of the block</td></tr><tr><td>miner</td><td>string</td><td>Address to whom the mining rewards were sent</td></tr><tr><td>difficulty</td><td>uint256</td><td>Difficulty for this block</td></tr><tr><td>total_difficulty</td><td>uint256</td><td>Total difficulty of the chain until this block</td></tr><tr><td>size</td><td>uint32</td><td>Size of this block in bytes</td></tr><tr><td>extra_data</td><td>string</td><td>Extra data field of the block</td></tr><tr><td>gas_limit</td><td>uint32</td><td>Maximum gas allowed in the block</td></tr><tr><td>gas_used</td><td>uint32</td><td>Total used gas by all transactions in the block</td></tr><tr><td>timestamp</td><td>datetime</td><td>UNIX timestamp for when the block was formed</td></tr><tr><td>base_fee_per_gas</td><td>uint64</td><td>Base fee per gas consumed in the block</td></tr><tr><td>transaction_count</td><td>uint32</td><td>Number of transactions in the block</td></tr><tr><td>transaction_effective_gas_price</td><td>[]uint64</td><td>Effective gas price for each transaction in the block</td></tr><tr><td>transaction_gas_used</td><td>[]uint32</td><td>Eas used for each transaction in the block</td></tr><tr><td>transaction_status</td><td>[]uint16</td><td>Transaction status for each transaction in the block</td></tr><tr><td>transaction_type</td><td>[]uint16</td><td>Transaction type for each transaction in the block</td></tr></tbody></table>

## Usage

The query below make use of the <mark style="color:blue;">`evm_blocks_ethereum_mainnet_v1`</mark> table to compute the average gas price per hour for the last 24 hours.

```sql
select
    date_trunc('hour', timestamp) as ts,
    avg(arrayAvg(transaction_effective_gas_price)) as avg_gas_price
from
    evm_blocks_ethereum_mainnet_v1
where timestamp >= now() - interval 24 hour
group by ts
order by ts
```


# Smart-contracts


# EVM Events

The core EVM blockchain data collection

## Availability

{% hint style="success" %}
This collection is available for **Ethereum**, **Polygon, Arbitrum, Base** and **BSC**.
{% endhint %}

| Points-of-Presence | Tables                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| eu-west-1          | <p><mark style="color:blue;"><code>evm\_events\_ethereum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>evm\_events\_arbitrum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>evm\_events\_polygon\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>evm\_events\_base\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>evm\_events\_bsc\_mainnet\_v1</code></mark></p> |

## Mapping rules

The table is wide and sparse.  Each event's input is stored in a column named after its <mark style="color:blue;">`index`</mark> in the input list and its derived <mark style="color:blue;">`type`</mark>.&#x20;

The column's name for a given input is derived as such: `input_`<mark style="color:blue;">`index`</mark>`_value_`<mark style="color:blue;">`type`</mark>

{% hint style="info" %}
We support events with up to **12** inputs.
{% endhint %}

The mapping rules used to derive an input type from an ABI type are specified in the table below.

| ABI Type                         | Derived Type   |
| -------------------------------- | -------------- |
| address                          | address        |
| string                           | string         |
| bytes                            | string         |
| bytes\<M> where 0 < M <= 32      | string         |
| bool                             | uint8          |
| uint8                            | uint8          |
| uint`X` where 8 < `X` <= 32      | uint32         |
| uint`X` where 32 < `X` <= 64     | uint64         |
| uint`X` where 64 < `X` <= 256    | uint256        |
| int8                             | int8           |
| int`X` where 8 < `X` <= 32       | int32          |
| int`X` where 32 < `X` <= 64      | int64          |
| int`X` where 64 < `X` <= 256     | int256         |
| address\[]                       | address\_array |
| string\[]                        | string\_array  |
| bool\[]                          | uint8\_array   |
| uint8\[]                         | uint8\_array   |
| uint`X`\[] where 8 < `X` <= 32   | uint32\_array  |
| uint`X`\[] where 32 < `M` <= 64  | uint64\_array  |
| uint`X`\[] where 64 < `M` <= 256 | uint256\_array |
| int8\[]                          | int8\_array    |
| int`X`\[] where 8 < `X` <= 32    | int32\_array   |
| int`X`\[] where 32 < `X` <= 64   | int64\_array   |
| int`X`\[] where 64 < `X` <= 256  | int256\_array  |

{% hint style="info" %}
Here is how we store the various inputs of <mark style="color:blue;">`Transfer`</mark> event:

<mark style="color:blue;">`Transfer(to address, from address, amount uint256))`</mark>

* **to** value is stored in the column **input\_0\_value\_address**
* **from** value is stored in the column **input\_1\_value\_address**
* **amount** is stored in the column **input\_2\_value\_uint256**
  {% endhint %}

## Table Schema

<table data-full-width="false"><thead><tr><th>Column Name</th><th>Column Type</th><th>Description</th></tr></thead><tbody><tr><td>chain_name</td><td>string</td><td>Name of the chain (<code>ethereum</code>, <code>arbitrum</code>, <code>polygon</code>, ...).</td></tr><tr><td>chain_network_name</td><td>string</td><td>name of the network (<code>mainnet</code>).</td></tr><tr><td>block_hash</td><td>string</td><td>Block hash encoded as binary string</td></tr><tr><td>block_number</td><td>uint64</td><td>Block height</td></tr><tr><td>block_index</td><td>uint32</td><td>Index of the event in the block</td></tr><tr><td>transaction_index</td><td>uint32</td><td>Index of the transaction in the block</td></tr><tr><td>transaction_status</td><td>uint32</td><td>Status of the transaction</td></tr><tr><td>timestamp</td><td>datetime</td><td>UNIX timestamp for when the block was collated</td></tr><tr><td>signature</td><td>string</td><td>Signature of the event as defined per the ABI spec (<code>Deposit(address,uint256)</code>)</td></tr><tr><td>fullsig</td><td>string</td><td>Signature of the event as defined per the ABI spec with the addition of the indexed modifier (<code>Transfer(address indexed,address indexed,uint256)</code>)</td></tr><tr><td>address</td><td>string</td><td>Address of the contract that emitted the event</td></tr><tr><td>removed</td><td>uint8</td><td>Removed field of the log</td></tr><tr><td>log_index</td><td>uint32</td><td>Index of the log in the block</td></tr><tr><td>input_<mark style="color:blue;"><code>index</code></mark>_type</td><td>string</td><td>ABI type of the input at <mark style="color:blue;"><code>index</code></mark></td></tr><tr><td>input_<mark style="color:blue;"><code>index</code></mark>_value<em>_</em><mark style="color:blue;"><code>type</code></mark></td><td></td><td>Content if the input at <mark style="color:blue;"><code>index</code></mark></td></tr></tbody></table>

## Usage

The query below make use of the <mark style="color:blue;">`evm_events_ethereum_mainnet_v1`</mark> table to retrieve the number of transfers and the amount transferred for each day since the beginning of the year, for USDC (0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48).

```sql
select 
    date_trunc('day', timestamp) as t, 
    count(*) as count, 
    sum(input_2_value_uint256) as amount 
from evm_events_ethereum_mainnet_v1 
where 
    address = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' 
    and signature = 'Transfer(address,address,uint256)' 
    and timestamp >= '2023-01-01' 
group by t 
order by t desc
```

<figure><img src="/files/48PdD5mQBToWXCVCl6Ts" alt=""><figcaption><p>The query executed with psql</p></figcaption></figure>


# EVM Calls

The core EVM blockchain data collection

## Availability

{% hint style="success" %}
This collection is available for the **Ethereum**, **Polygon,**  **Arbitrum** and **Base**.
{% endhint %}

| Points-of-Presence | Tables                                                                                                                                                                                                                                                                                                                                     |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| eu-west-1          | <p><mark style="color:blue;"><code>evm\_calls\_ethereum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>evm\_calls\_arbitrum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>evm\_calls\_polygon\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>evm\_calls\_base\_mainnet\_v1</code></mark></p> |

## Mapping rules

The table is wide and sparse.  Each call's input and output is stored in a column named after its <mark style="color:blue;">`index`</mark> in the input list and its derived <mark style="color:blue;">`type`</mark>.&#x20;

The column's name for a given input is derived as such: `input_`<mark style="color:blue;">`index`</mark>`_value_`<mark style="color:blue;">`type.`</mark>

The column's name for a given output is derived as such: `output_`<mark style="color:blue;">`index`</mark>`_value_`<mark style="color:blue;">`type`</mark>

{% hint style="info" %}
We support calls with up to **12** inputs and **3** outputs.
{% endhint %}

The mapping rules used to derive an input type from an ABI type are specified in the table below.

| ABI Type                         | Derived Type   |
| -------------------------------- | -------------- |
| address                          | address        |
| string                           | string         |
| bytes                            | string         |
| bytes\<M> where 0 < M <= 32      | string         |
| bool                             | uint8          |
| uint8                            | uint8          |
| uint`X` where 8 < `X` <= 32      | uint32         |
| uint`X` where 32 < `X` <= 64     | uint64         |
| uint`X` where 64 < `X` <= 256    | uint256        |
| int8                             | int8           |
| int`X` where 8 < `X` <= 32       | int32          |
| int`X` where 32 < `X` <= 64      | int64          |
| int`X` where 64 < `X` <= 256     | int256         |
| address\[]                       | address\_array |
| string\[]                        | string\_array  |
| bool\[]                          | uint8\_array   |
| uint8\[]                         | uint8\_array   |
| uint`X`\[] where 8 < `X` <= 32   | uint32\_array  |
| uint`X`\[] where 32 < `M` <= 64  | uint64\_array  |
| uint`X`\[] where 64 < `M` <= 256 | uint256\_array |
| int8\[]                          | int8\_array    |
| int`X`\[] where 8 < `X` <= 32    | int32\_array   |
| int`X`\[] where 32 < `X` <= 64   | int64\_array   |
| int`X`\[] where 64 < `X` <= 256  | int256\_array  |

{% hint style="info" %}
Here is how we store the various inputs and outputs of the  <mark style="color:blue;">transfer</mark> function:

<mark style="color:blue;">`transfer(recipient address, amount uint256)(ok bool)`</mark>

* **recipient** value is stored in the column **input\_0\_value\_address**
* **amount** value is stored in the column **input\_1\_value\_uint256**
* **ok** value is stored in the column **output\_0\_value\_uint8**
  {% endhint %}

## Table Schema

<table data-full-width="false"><thead><tr><th>Column Name</th><th>Column Type</th><th>Description</th></tr></thead><tbody><tr><td>chain_name</td><td>string</td><td>Name of the chain (<code>ethereum</code>, <code>arbitrum</code>, <code>polygon</code>, ...).</td></tr><tr><td>chain_network_name</td><td>string</td><td>name of the network (<code>mainnet</code>).</td></tr><tr><td>block_hash</td><td>string</td><td>Block hash encoded as binary string</td></tr><tr><td>block_number</td><td>uint64</td><td>Block height</td></tr><tr><td>block_index</td><td>uint32</td><td>Index of the call in the block</td></tr><tr><td>transaction_index</td><td>uint32</td><td>Index of the transaction in the block</td></tr><tr><td>transaction_status</td><td>uint32</td><td>Status of the transaction</td></tr><tr><td>timestamp</td><td>datetime</td><td>UNIX timestamp for when the block was collated</td></tr><tr><td>signature</td><td>string</td><td>Signature of the event as defined per the ABI spec (<code>transfer(address,uint256)</code>)</td></tr><tr><td>fullsig</td><td>string</td><td>Signature of the event as defined per the ABI spec with the addition of the indexed modifier (<code>transfer(address,uint256)(bool)</code>)</td></tr><tr><td>from</td><td>string</td><td>Address of the caller</td></tr><tr><td>gas</td><td>uint32</td><td>Number of gas used during the call</td></tr><tr><td>value</td><td>uint256</td><td>Amount of native token sent to the contract</td></tr><tr><td>call_type</td><td>string</td><td>The type of method used (<strong>call</strong>, <strong>delegatecall</strong>, <strong>staticcall</strong>, ...)</td></tr><tr><td>subcalls</td><td>uint32</td><td>The number of traces below this one in the call stack</td></tr><tr><td>call_address</td><td>uint32[]</td><td>The position of this trace in the call stack</td></tr><tr><td>error</td><td>string</td><td>The error returned during the execution of the method, if any</td></tr><tr><td>input_<mark style="color:blue;"><code>index</code></mark>_value<em>_</em><mark style="color:blue;"><code>type</code></mark></td><td></td><td>Content of the input at <mark style="color:blue;"><code>index</code></mark></td></tr><tr><td>output_<mark style="color:blue;"><code>index</code></mark>_type</td><td>string</td><td>ABI type of the output at <mark style="color:blue;"><code>index</code></mark></td></tr><tr><td>output_<mark style="color:blue;"><code>index</code></mark>_value_type</td><td></td><td>Content of the output at <mark style="color:blue;"><code>index</code></mark></td></tr></tbody></table>

## Usage

The below query make use of the <mark style="color:blue;">`evm_events_ethereum_mainnet_v1`</mark> table to report on gas usage per each method of the ShibaInu-ETH Uniswap V2 pair.

We compute the total gas used and average gas used for each method called since genesis.

The result is sorted by decreasing total gas used value.

```sql
select 
    signature,
    sum(gas) as total_gas,
    avg(gas) as avg_gas,
    count(*) as total_calls,
    countIf(error <> '') as total_errors
from evm_calls_ethereum_mainnet
where to = '0x811beEd0119b4AfCE20D2583EB608C6F7AF1954f'
group by signature
order by total_gas DESC
```


# DeFi


# Trades

## Availability

{% hint style="success" %}
This collection is available for the **Ethereum, Polygon,  Arbitrum,** and **Base**.
{% endhint %}

| Points-of-Presence | Tables                                                                                                                                                                                                                                                                                                                                             |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| eu-west-1          | <p><mark style="color:blue;"><code>defi\_trades\_ethereum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>defi\_trades\_polygon\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>defi\_trades\_arbitrum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>defi\_trades\_base\_mainnet\_v1</code></mark></p> |

## Methodology

The table is built by extracting data from DEXes activity and then normalizing it to fit a unified data model.

We currently support the following DEXes:

* **Uniswap V2**
* **Uniswap V3**
* **Curve**

{% hint style="info" %}
We extract data from any contract compatible with one of the above DEXes ABI.

It means that any DEXes that forked or tried to be compatible at the ABI level with these contracts will be indexed automatically.
{% endhint %}

## Table Schema

<table data-full-width="false"><thead><tr><th>Column Name</th><th>Column Type</th><th>Description</th></tr></thead><tbody><tr><td>chain_name</td><td>string</td><td>Name of the chain (<code>ethereum</code>, <code>arbitrum</code>, <code>polygon</code>, ...).</td></tr><tr><td>chain_network_name</td><td>string</td><td>name of the network (<code>mainnet</code>).</td></tr><tr><td>block_hash</td><td>string</td><td>Block hash encoded as binary string</td></tr><tr><td>block_number</td><td>uint64</td><td>Block height</td></tr><tr><td>transaction_index</td><td>uint64</td><td>The index of the transaction in the block</td></tr><tr><td>timestamp</td><td>datetime</td><td>UNIX timestamp for when the block was collated</td></tr><tr><td>decoder_name</td><td>string</td><td>The internal name of the decoder used to decode this trade (uniswap_v2_trade, curve_trade)</td></tr><tr><td>factory</td><td>string</td><td>The address of the DEX factory contract (if any)</td></tr><tr><td>contract</td><td>string</td><td>The address of the DEX pair/pool the actually executed the trade</td></tr><tr><td>sender</td><td>string</td><td>The address of the account the called the contract</td></tr><tr><td>receiver</td><td>string</td><td>The address of the account that received the swapped amount</td></tr><tr><td>origin</td><td>string</td><td>The address of the EOA that triggered the transaction</td></tr><tr><td>token_sold_address</td><td>string</td><td>The address of the sold token</td></tr><tr><td>token_sold_symbol</td><td>string</td><td>The symbol of the sold token</td></tr><tr><td>token_sold_raw_amount</td><td>uint256</td><td>The amount of token sold</td></tr><tr><td>token_sold_amount</td><td>float64</td><td>The amount of token sold divided by <code>pow(10, </code><mark style="color:blue;"><code>decimals</code></mark><code>)</code> where <mark style="color:blue;">decimals</mark> is the number of decimals declared by the token (<strong>USDT</strong> has <strong>6</strong> decimals)</td></tr><tr><td>token_bought_address</td><td>string</td><td>The address of the bought token</td></tr><tr><td>token_bought_symbol</td><td>string</td><td>The symbol of the bought token</td></tr><tr><td>token_bought_raw_amount</td><td>uint256</td><td>The amount of token bought</td></tr><tr><td>token_bought_amount</td><td>float64</td><td>The amount of token bought divided by <code>pow(10, </code><mark style="color:blue;"><code>decimals</code></mark><code>)</code> where <mark style="color:blue;">decimals</mark> is the number of decimals declared by the token (<strong>USDT</strong> has <strong>6</strong> decimals)</td></tr><tr><td>price</td><td>float64</td><td>The price of the trade, computed by doing: <mark style="color:blue;"><code>token_bought_amount / token_sold_mount</code></mark></td></tr></tbody></table>

## Usage

The query below makes use of the <mark style="color:blue;">`defi_trades_ethereum_mainnet_v1`</mark> table to get the necessary data to display the well-known candlestick chart for the price of USDC (0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) on the Uniswap V3 USDC/ETH Pool (0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640) for the last 30 days.

```sql
select 
  date_trunc('day', timestamp) as date,
  argMin(price, timestamp) as open,
  argMax(price, timestamp) as close,
  min(price) as _min,
  max(price) as _max
from defi_trades_ethereum_mainnet_v1
where contract = '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640'
and token_sold_address = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
and timestamp >= now() - interval 30 day
group by date
order by date desc 
```


# Liquidity Events

## Availability

{% hint style="success" %}
This collection is available for the **Ethereum, Polygon,  Arbitrum,** and **Base**.
{% endhint %}

| Points-of-Presence | Tables                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| eu-west-1          | <p><mark style="color:blue;"><code>defi\_liquidity\_events\_ethereum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>defi\_liquidity\_events\_polygon\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>defi\_liquidity\_events\_arbitrum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>defi\_liquidity\_events\_base\_mainnet\_v1</code></mark></p> |

## Methodology

The table is built by extracting data from DEXes activity and then normalizing it to fit a unified data model.

We currently support the following DEXes:

* **Uniswap V2**
* **Uniswap V3**
* **Curve**

{% hint style="info" %}
We extract data from any contract compatible with one of the above DEXes ABI.

It means that any DEXes that forked or tried to be compatible at the ABI level with these contracts will be indexed automatically.
{% endhint %}

## Table Schema

<table data-full-width="false"><thead><tr><th>Column Name</th><th>Column Type</th><th>Description</th></tr></thead><tbody><tr><td>chain_name</td><td>string</td><td>Name of the chain (<code>ethereum</code>, <code>arbitrum</code>, <code>polygon</code>, ...).</td></tr><tr><td>chain_network_name</td><td>string</td><td>name of the network (<code>mainnet</code>).</td></tr><tr><td>block_hash</td><td>string</td><td>Block hash encoded as binary string</td></tr><tr><td>block_number</td><td>uint64</td><td>Block height</td></tr><tr><td>transaction_index</td><td>uint64</td><td>The index of the transaction in the block</td></tr><tr><td>timestamp</td><td>datetime</td><td>UNIX timestamp for when the block was collated</td></tr><tr><td>decoder_name</td><td>string</td><td>The internal name of the decoder used to decode this trade (uniswap_v2_liquidity_event, curve_liquidity_event)</td></tr><tr><td>type</td><td>string</td><td>Either <mark style="color:blue;"><code>mint</code></mark> or <mark style="color:blue;"><code>burn</code></mark></td></tr><tr><td>factory</td><td>string</td><td>The address of the DEX factory contract (if any)</td></tr><tr><td>contract</td><td>string</td><td>The address of the DEX pair/pool</td></tr><tr><td>provider</td><td>string</td><td>The address of the account that provided or withdraw the liquidity</td></tr><tr><td>raw_amounts</td><td>map(string, uint256)</td><td>A map of token amounts provided or withdrawn</td></tr><tr><td>amounts</td><td>map(string, float64)</td><td>A map of token amounts provided or withdrawn. The amount of tokens are divided by <code>pow(10, </code><mark style="color:blue;"><code>decimals</code></mark><code>)</code> where <mark style="color:blue;">decimals</mark> is the number of decimals declared by the token (<strong>USDT</strong> has <strong>6</strong> decimals)</td></tr></tbody></table>

## Usage

The query below makes use of the <mark style="color:blue;">`defi_liquidity_events_ethereum_mainnet_v1`</mark> to chart the daily delta of liquidity for each token of the famous Curve 3Pool (0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7).

```sql
select 
    date_trunc('day', timestamp) as date,
    sum(if(type = 'mint', amounts['0x6b175474e89094c44da98b954eedeac495271d0f'], -amounts['0x6b175474e89094c44da98b954eedeac495271d0f'])) as delta_dai,
    sum(if(type = 'mint', amounts['0xdac17f958d2ee523a2206206994597c13d831ec7'], -amounts['0xdac17f958d2ee523a2206206994597c13d831ec7'])) as delta_usdt,
    sum(if(type = 'mint', amounts['0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'], -amounts['0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'])) as delta_usdc
from defi_liquidity_events_ethereum_mainnet_v1
where contract = '0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7'
and timestamp >= now() - interval 30 day 
group by date
```


# Liquidity Snapshots

## Availability

{% hint style="success" %}
This collection is available for the **Ethereum, Polygon,  Arbitrum,** and **Base**.
{% endhint %}

| Points-of-Presence | Tables                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| eu-west-1          | <p><mark style="color:blue;"><code>defi\_liquidity\_snapshots\_ethereum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>defi\_liquidity\_snapshots\_polygon\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>defi\_liquidity\_snapshots\_arbitrum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>defi\_liquidity\_snapshots\_base\_mainnet\_v1</code></mark></p> |

## Methodology

The table is built by the following process:

1. Identify all liquidity events emitted by supported DEX pools in a block
2. Call the <mark style="color:blue;">`balanceOf`</mark> method for each pair of (pool, ERC-20)&#x20;

We currently support the following DEXes:

* **Uniswap V2**
* **Uniswap V3**
* **Curve**

{% hint style="info" %}
We extract data from any contract compatible with one of the above DEXes ABI.

It means that any DEXes that forked or tried to be compatible at the ABI level with these contracts will be indexed automatically.
{% endhint %}

## Table Schema

<table data-full-width="false"><thead><tr><th>Column Name</th><th>Column Type</th><th>Description</th></tr></thead><tbody><tr><td>chain_name</td><td>string</td><td>Name of the chain (<code>ethereum</code>, <code>arbitrum</code>, <code>polygon</code>, ...).</td></tr><tr><td>chain_network_name</td><td>string</td><td>name of the network (<code>mainnet</code>).</td></tr><tr><td>block_hash</td><td>string</td><td>Block hash encoded as binary string</td></tr><tr><td>block_number</td><td>uint64</td><td>Block height</td></tr><tr><td>transaction_index</td><td>uint64</td><td>The index of the transaction in the block</td></tr><tr><td>timestamp</td><td>datetime</td><td>UNIX timestamp for when the block was collated</td></tr><tr><td>decoder_name</td><td>string</td><td>The internal name of the decoder used to decode this trade (uniswap_v2_liquidity_event, curve_liquidity_event)</td></tr><tr><td>factory</td><td>string</td><td>The address of the DEX factory contract (if any)</td></tr><tr><td>contract</td><td>string</td><td>The address of the DEX pair/pool</td></tr><tr><td>raw_amounts</td><td>map(string, uint256)</td><td>A map of token amounts held by the pool</td></tr><tr><td>amounts</td><td>map(string, float64)</td><td>A map of token amounts held by the pool. The amount of tokens are divided by <code>pow(10, </code><mark style="color:blue;"><code>decimals</code></mark><code>)</code> where <mark style="color:blue;">decimals</mark> is the number of decimals declared by the token (<strong>USDT</strong> has <strong>6</strong> decimals)</td></tr></tbody></table>

## Usage

The query below makes use of the <mark style="color:blue;">`defi_liquidity_snapshots_ethereum_mainnet_v1`</mark> to chart the daily average of liquidity for each token of the famous Curve 3Pool (0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7).

```sql
select
    date_trunc('day', timestamp) as date,
    avg(amounts['0x6b175474e89094c44da98b954eedeac495271d0f']) as dai_liquidity,
    avg(amounts['0xdac17f958d2ee523a2206206994597c13d831ec7']) as usdt_liquidity,
    avg(amounts['0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48']) as usdc_liquidity
from defi_liquidity_snapshots_ethereum_mainnet_v1
where contract = '0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7'
and timestamp >= now() - interval 30 day 
group by date
```


# Token


# Balances

## Availability

{% hint style="success" %}
This table is available for the **Ethereum, Polygon, Arbitrum** and **Base**.
{% endhint %}

| Points-of-Presence | Tables                                                                                                                                                                                                                                                                                                                                                         |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| eu-west-1          | <p><mark style="color:blue;"><code>token\_balances\_ethereum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>token\_balances\_polygon\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>token\_balances\_arbitrum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>token\_balances\_base\_mainnet\_v1</code></mark></p> |

## Methodology

The table is built by the following process:

1. Identify all <mark style="color:blue;">`Transfer`</mark> events (shared by <mark style="color:blue;">`ERC-20`</mark> and <mark style="color:blue;">`ERC-721`</mark>) emitted in a block
2. Call the <mark style="color:blue;">`balanceOf`</mark> method for each pair of (token, wallet) extracted from these events

{% hint style="info" %}
Some smart contracts have very inefficient implementations of the <mark style="color:blue;">`balanceOf`</mark> method. To ensure the timely execution of our indexer, we decided to put a hard cap of gas usage for every <mark style="color:blue;">`balanceOf`</mark> call we make. The current value is **2000000 gas**.
{% endhint %}

## Table Schema

<table data-full-width="false"><thead><tr><th>Column Name</th><th>Column Type</th><th>Description</th></tr></thead><tbody><tr><td>chain_name</td><td>string</td><td>Name of the chain (<code>ethereum</code>, <code>arbitrum</code>, <code>polygon</code>, ...).</td></tr><tr><td>chain_network_name</td><td>string</td><td>name of the network (<code>mainnet</code>).</td></tr><tr><td>block_hash</td><td>string</td><td>Block hash encoded as binary string</td></tr><tr><td>block_number</td><td>uint64</td><td>Block height</td></tr><tr><td>timestamp</td><td>datetime</td><td>UNIX timestamp for when the block was collated</td></tr><tr><td>wallet_address</td><td>string</td><td>The address of the wallet</td></tr><tr><td>token_address</td><td>string</td><td>The address of the token</td></tr><tr><td>value</td><td>uint256</td><td>The amount of token held</td></tr></tbody></table>

## Usage

The below query makes use of the <mark style="color:blue;">`token_balances_ethereum_mainnet_v1`</mark> to list all the latest non-zero balances for every ERC-20 and ERC-721 token for the Binance 14 (0x28C6c06298d514Db089934071355E5743bf21d60) wallet.

```sql
select 
    token_address,
    argMax(value, block_number) as balance
from token_balances_ethereum_mainnet_v1
where wallet_address = '0x28C6c06298d514Db089934071355E5743bf21d60'
and value > 0
group by token_address
order by balance desc
```


# Total Supplies

## Availability

{% hint style="success" %}
This table is available for the **Ethereum, Polygon,  Arbitrum** and **Base**.
{% endhint %}

| Points-of-Presence | Tables                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| eu-west-1          | <p><mark style="color:blue;"><code>token\_total\_supplies\_ethereum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>token\_total\_supplies\_polygon\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>token\_total\_supplies\_arbitrum\_mainnet\_v1</code></mark><br><mark style="color:blue;"><code>token\_total\_supplies\_base\_mainnet\_v1</code></mark></p> |

## Methodology

The table is built by the following process:

1. Identify all <mark style="color:blue;">`Transfer`</mark> events (shared by <mark style="color:blue;">`ERC-20`</mark> and <mark style="color:blue;">`ERC-721`</mark>) emitted in a block
2. Call the <mark style="color:blue;">`totalSupply`</mark> method for each token extracted from these events

{% hint style="info" %}
Some smart contracts have very inefficient implementations of the <mark style="color:blue;">`totalSupply`</mark> method. To ensure the timely execution of our indexer, we decided to put a hard cap of gas usage for every <mark style="color:blue;">`totalSupply`</mark> call we make. The current value is **2000000 gas**.
{% endhint %}

## Table Schema

<table data-full-width="false"><thead><tr><th>Column Name</th><th>Column Type</th><th>Description</th></tr></thead><tbody><tr><td>chain_name</td><td>string</td><td>Name of the chain (<code>ethereum</code>, <code>arbitrum</code>, <code>polygon</code>, ...).</td></tr><tr><td>chain_network_name</td><td>string</td><td>name of the network (<code>mainnet</code>).</td></tr><tr><td>block_hash</td><td>string</td><td>Block hash encoded as binary string</td></tr><tr><td>block_number</td><td>uint64</td><td>Block height</td></tr><tr><td>timestamp</td><td>datetime</td><td>UNIX timestamp for when the block was collated</td></tr><tr><td>token_address</td><td>string</td><td>The address of the token</td></tr><tr><td>value</td><td>uint256</td><td>The total supply of the token</td></tr></tbody></table>

## Usage

The below query makes use of the <mark style="color:blue;">`token_total_supplies_ethereum_mainnet_v1`</mark> to get the maximum total supply of USDC (0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48) per day for the last 30 days.

```sql
select 
	date_trunc('day', timestamp) as date,
	argMax(value, block_number)
from token_total_supplies_ethereum_mainnet_v1
where token_address = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48'
and timestamp >= now() - interval 30 day
group by date
order by date desc
```


# Uniswap V3


# Definition

Can we use Agnostic as a backend for Uniswap analytics?

## The example

> Can we display a price curve of ETH/USDC projected from swap happening on-chain over time to thousands of users with the freshest data?

It shouldn't be an issue with a well-designed protocol like Uniswap and Agnostic powerful live aggregation and serving capabilities.

## The Uniswap V3 data model

Fortunately, Uniswap publishes many valuable Events, allowing us to track the protocol activity with our \`evm\_event\_\*\` data collection.\
\
Let's explore the [documentation](https://docs.uniswap.org/contracts/v3/reference/core/interfaces/pool/IUniswapV3PoolEvents) and find the Swap event signature; it's the one we are looking for here.

```solidity
event Swap(
  address sender,
  address recipient,
  int256 amount0,
  int256 amount1,
  uint160 sqrtPriceX96,
  uint128 liquidity,
  int24 tick
)
```

In this version of Uniswap, we have very interesting values: `sqrtPriceX96` and `tick`. In the previous versions, we had to calculate the price from the amounts directly. Let's try to look at the `tick`.

So, with this explanation from the documentation:

| Name                                    | Type                                   | Description                                                                              |
| --------------------------------------- | -------------------------------------- | ---------------------------------------------------------------------------------------- |
| `sender`                                | address                                | The address that initiated the swap call, and that received the callback                 |
| `recipient`                             | address                                | The address that received the output of the swap                                         |
| `amount0`                               | int256                                 | The delta of the token0 balance of the pool                                              |
| `amount1`                               | int256                                 | The delta of the token1 balance of the pool                                              |
| `sqrtPriceX96`                          | uint160                                | The sqrt(price) of the pool after the swap, as a Q64.96                                  |
| `liquidity`                             | uint128                                | The liquidity of the pool after the swap                                                 |
| <mark style="color:blue;">`tick`</mark> | <mark style="color:blue;">int24</mark> | <mark style="color:blue;">The log base 1.0001 of price of the pool after the swap</mark> |

We should be able to get the price with this simple formula:

```sql
pow(1.0001, tick)
```


# Explore

To explore the Agnostic data ocean, you can use a wide range of tools from `psql` to `Grafana` and, of course, the integrated data visualization tool from Agnostic.

<figure><img src="/files/7OBC1486ilsBFyg0dted" alt=""><figcaption><p>Token price from Uniswap events</p></figcaption></figure>

Let's break down the query with a few comments:

```sql
SELECT
  date_trunc('hour', timestamp) as chart_x, -- we trunc timestamp to hour
  1 / (
    pow (1.0001, avg(input_6_value_int32)) -- we apply our formula to the sixth parameter of the signature: the tick
    / pow (10, 18 - 6) -- we consider each token decimals here
  ) as chart_y 
FROM
  evm_events_ethereum_mainnet -- the event data collection for the Ethereum mainnet
WHERE
  address = '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640' -- the address of the ETH/USDC pool
  and signature = 'Swap(address,address,int256,int256,uint160,uint128,int24)' -- filter the right signature
  and chart_x >= '2023-08-01'
GROUP BY
  chart_x
ORDER BY
  chart_x ASC
```


# Apify


# Portfolio tracker


# Data visualization


# Create your first chart

## Let's dive deep into those tools

This guide will walk you through the simple steps to create your first chart. You can build your charts with the SQL language over the datasets available in **Agnostic**. This guide will walk you through the steps to harness the full potential of this powerful tool.

{% hint style="warning" %}
**Prerequisites:**&#x20;

Before we begin, please ensure that you are logged into your **Agnostic** account and have the right permissions to create charts within your project.
{% endhint %}

### Step 1: Create a chart resource

1. Once you're logged in, you'll land on the project page where you can manage and view project resources like Charts, GraphQL Endpoints, and Dashboards.
2. To create your first chart, locate the "Create" button on the page and click on it. A dropdown menu will appear – select "Chart."
3. A modal will pop up, prompting you to name your chart. Provide a descriptive name for easy identification. For this example, we will use « USDC Transferred to Coinbase VS Binance »

<figure><img src="/files/l04kVDdMP1T2BY2DD8Vj" alt=""><figcaption><p>Create chart modal</p></figcaption></figure>

Once you've clicked on the "Create" button. You'll be seamlessly redirected to the newly created chart, ready for customization and configuration.

### Step 2: Writing SQL Queries

1. In the Chart interface, you'll see a text editor where you can write SQL queries. Start by composing your query based on the dataset available in Agnostic. You can use standard SQL syntax, including SELECT statements, JOINs, GROUP BY, and more.
2. As you type, you'll benefit from autocomplete suggestions for SQL keywords, tables, and columns from the Agnostic dataset. This feature streamlines the query-writing process and helps prevent typos and errors.
3. After composing your query, execute it using the "Play" button. You'll instantly see the results displayed in a table format, resembling a classic database GUI.

### Step 3: Chart Configuration

1. To create a chart, you need to define how the SQL query results will be visualized. Displaying chart relies on aliases to designate the chart's axes:

<table><thead><tr><th width="207">Axis</th><th>Aliases</th></tr></thead><tbody><tr><td><strong>X-axis</strong></td><td>Use the <code>chart_x</code> alias to define your X values</td></tr><tr><td><strong>Y-axis</strong></td><td>Use the <code>chart_y</code> alias to define your Y values</td></tr><tr><td><strong>Z-axis</strong> <em>(Optional)</em></td><td><p>There are two ways to define the Z-axis</p><ul><li>By using the <code>chart_z</code></li><li>Or by using a label on the Y-axis values like so <code>chart_y_{LABEL}</code><br>Example: <code>chart_y_USDC</code> and <code>chart_y_DAI</code> </li></ul></td></tr></tbody></table>

2. Configure your SQL query to generate results that match the axis aliases you've defined.
3. Then select your chart type by clicking on  <img src="/files/uWijw4VM50b3qOSesGpA" alt="Configuration modal" data-size="original"> (Chart configuration) - select "Line"

<figure><img src="/files/ZyKY1I5Y8YthJSjkeOqL" alt=""><figcaption><p>Chart configuration modal</p></figcaption></figure>

#### A clickbait example 👀

Let's create a chart showing the number of USDC transferred to Coinbase vs. Binance by week from May 2021.

```sql
select
  'Coinbase' as chart_z,
  date_trunc('week', timestamp) as chart_x,
  sum(input_2_value_uint256) as chart_y
from 
  evm_events_ethereum_mainnet
where
  timestamp >= '2021-05-01' and
  address = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' and -- USDC token Address
  signature = 'Transfer(address,address,uint256)' and 
  input_1_value_address in (
  	'0x71660c4005BA85c37ccec55d0C4493E66Fe775d3', -- Coinbase 1
  	'0x503828976D22510aad0201ac7EC88293211D23Da', -- Coinbase 2
  	'0xddfAbCdc4D8FfC6d5beaf154f18B778f892A0740', -- Coinbase 3
  	'0x3cD751E6b0078Be393132286c442345e5DC49699', -- Coinbase 4
  	'0xb5d85CBf7cB3EE0D56b3bB207D5Fc4B82f43F511', -- Coinbase 5
  	'0xeB2629a2734e272Bcc07BDA959863f316F4bD4Cf', -- Coinbase 6
  	'0x02466E547BFDAb679fC49e96bBfc62B9747D997C', -- Coinbase 8
  	'0xA9D1e08C7793af67e9d92fe308d5697FB81d3E43', -- Coinbase 10
  	'0x77696bb39917C91A0c3908D577d5e322095425cA', -- Coinbase 11
  	'0x7c195D981AbFdC3DDecd2ca0Fed0958430488e34', -- Coinbase 12
  	'0x95A9bd206aE52C4BA8EecFc93d18EACDd41C88CC', -- Coinbase 13
  	'0xb739D0895772DBB71A89A3754A160269068f0D45'  -- Coinbase 14
  ) 
group by
  chart_x
order by
  chart_x asc

UNION ALL

select
  'Binance' as chart_z,
  date_trunc('week', timestamp) as chart_x,
  sum(input_2_value_uint256) as chart_y
from 
  evm_events_ethereum_mainnet
where
  timestamp >= '2021-05-01' and
  address = '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' and -- USDC token Address
  signature = 'Transfer(address,address,uint256)' and 
  input_1_value_address in (
  	'0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE', -- Binance
  	'0xD551234Ae421e3BCBA99A0Da6d736074f22192FF', -- Binance 2
  	'0x564286362092D8e7936f0549571a803B203aAceD', -- Binance 3
  	'0x0681d8Db095565FE8A346fA0277bFfdE9C0eDBBF', -- Binance 4
  	'0xfE9e8709d3215310075d67E3ed32A380CCf451C8', -- Binance 5
  	'0x4E9ce36E442e55EcD9025B9a6E0D88485d628A67', -- Binance 6
  	'0xBE0eB53F46cd790Cd13851d5EFf43D12404d33E8', -- Binance 7
  	'0xF977814e90dA44bFA03b6295A0616a897441aceC', -- Binance 8
  	'0x001866Ae5B3de6cAa5a51543FD9fB64f524F5478', -- Binance 9
  	'0x85b931A32a0725Be14285B66f1a22178c672d69B', -- Binance 10
  	'0x708396f17127c42383E3b9014072679b2F60B82f', -- Binance 11
  	'0xE0F0CfDe7Ee664943906f17F7f14342E76A5CeC7', -- Binance 12
  	'0x8f22f2063d253846b53609231ed80fa571bc0c8f', -- Binance 13
  	'0x28C6c06298d514Db089934071355E5743bf21d60', -- Binance 14
  	'0x21a31Ee1afC51d94C2eFcCAa2092aD1028285549', -- Binance 15
  	'0xDFd5293D8e347dFe59E90eFd55b2956a1343963d'  -- Binance 16
  )
group by
  chart_x
order by
  chart_x asc
```

<figure><img src="/files/1AJW38LTf2211FNGi3ib" alt=""><figcaption><p>Chart - USDC Transferred (Coinbase/Binance)</p></figcaption></figure>

{% hint style="info" %}
Watch the result from the public chart [USDC Transferred (Coinbase/Binance)](https://app.agnostic.engineering/s/c/7yxFnTYgnAT).
{% endhint %}

### Step 4: Previewing and Saving

1. Once your SQL query and chart aliases are defined, click the "Play" button (on the top right corner of the IDE). **Agnostic** will process your query and generate a chart based on the specified aliases.
2. Review the generated chart to ensure it accurately represents the data and visualization you intended to create.
3. If everything looks good, you can save the chart within your Agnostic project by clicking the "Save" button.

Congratulations! You've successfully created your first chart with Agnostic. You can now view, edit, and share your chart with your team or stakeholders or even with the world by clicking on the button "Share". This tool empowers you to leverage your SQL skills to craft customized visualizations from your blockchain data. Explore the possibilities, refine your queries, and unlock actionable insights with this advanced data visualization tool.

{% hint style="success" %}
Visualize your blockchain data with Agnostic's tools and explore different chart types and configurations for valuable insights.
{% endhint %}


# Building API

## Let's deliver dynamic content through GraphQL API

Our solution uses GraphQL in conjunction with our SQL engine to provide dynamic content based on dynamic requests. This guide will walk you through the process, ensuring you can deliver precisely what you need with ease and efficiency.

{% hint style="warning" %}
**Prerequisites:**&#x20;

Before we begin, please ensure that you are logged into your **Agnostic** account and have the right permissions to create GraphQL API within your project.
{% endhint %}

### Two Ways of Creating a GraphQL API

#### 1. From Scratch

* Once you're logged in, you'll land on the project page where you can manage and view project resources like Charts, GraphQL API, and Dashboards.
* To create your GraphQL API, locate the "Create" button on the page and click on it. A dropdown menu will appear – select "GraphQL API"
* A modal will pop up, prompting you to name your query. Provide a descriptive name for easy identification. The name of must be unique by project. As we will see later, a GraphQL Schema is generated by project

Once you've clicked on the "Create" button. You'll be seamlessly redirected to the newly created GraphQL API.

#### 2. From an Existing Chart

* Go to the chart you want to use as the basis for your API.
* You will be immediately redirected the newly created GraphQL API page. This method automatically uses the query from the chart, saving you from copying and pasting.
* Some adjustments are required to make it works.

### How it Works

Similar to charts, the data delivered by your API will be labeled using SQL aliases. This helps to structure the data for GraphQL queries effectively.

* **Fields:** To define fields in your GraphQL schema, use the alias format `gql_field_string_<field_name>`.
  * Example: `SELECT column_name AS gql_field_string_fieldName FROM table_name;`
* **Arguments:** To define arguments in your GraphQL schema, use the alias format `gql_arg_string_<arg_name>`.
  * Example: `SELECT column_name AS gql_field_string_fieldName FROM table_name WHERE column_name = gql_arg_string_argumentName;`

As you are editing, you will see a preview of the generated schema.

<figure><img src="/files/YfvbZ1V3IN3xBngmsa0D" alt=""><figcaption><p>Daily count calls GraphQL API</p></figcaption></figure>

Once you've created your schema as it pleases you, you can test it by clicking on the tab "GraphQL query". On one side, you will have the GraphQL Editor where you can edit your GraphQL query on the other side you'll have the result in JSON format. Don't forget to save once you've finished to adjust the fields and arguments for your GraphQL API.

### How to Use your GraphQL API

To make full use of the GraphQL API you've created with **Agnostic**, follow the steps outlined below.

#### Endpoint URL

The URL for the GraphQL proxy is:

```
https://graphql.eu-west-1.agnostic.engineering/graphql
```

#### API Token

To authenticate your requests, you'll need an API Token. This token can be passed either through query parameters or headers.

* Query Parameters:&#x20;

```
https://graphql.eu-west-1.agnostic.engineering/graphql?Authorization=<token>
```

* Headers:

```
Authorization: <token>
```

#### Schema Generation

Schemas are generated based on the project you are working on. The project is automatically detected by the API Token you use, ensuring that your queries are correctly aligned with your project's schema

#### Example Usage

```bash
curl -X POST 'https://graphql.eu-west-1.agnostic.engineering/graphql' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: <token>' \
  -d '{"query": "{ count_daily_calls { date count } }"}'
```

Using the GraphQL API in Agnostic is a powerful way to interact with your project's data. By correctly using your API Token, you can securely query data within your project's schema. Enjoy the flexibility and efficiency of GraphQL with **Agnostic**!


# HTTP Interface

How to use the HTTP interface

## Endpoints

The HTTP interface is composed of only two routes.

<table><thead><tr><th>path</th><th>description</th><th>input</th><th>output</th><th data-hidden>name</th></tr></thead><tbody><tr><td>/catalog</td><td>get schemas, tables, columns metadata</td><td></td><td>A JSON-formatted representation of the database catalog</td><td>catalog</td></tr><tr><td>/query</td><td>process SQL queries</td><td>An SQL query in the HTTP request's body</td><td>A JSON-formatted result set</td><td>query</td></tr></tbody></table>

## Caching

Various parameters of the query influence the caching behavior of the query endpoint. We try to stay as close to standard HTTP caching as possible and implement custom extensions only when needed. Cache-related parameters must be passed through the standard `Cache-Control` header (or `cache-control` query param).

| supported directive | semantic                                                 |
| ------------------- | -------------------------------------------------------- |
| `no-cache`          | Bypass query cache                                       |
| `no-store`          | Do not store the result of this query in the query cache |
| `max-age=N`         | The client can tolerate a result at most `N` seconds old |

We support some custom request headers related to the caching behavior of the HTTP interface.

| header                             |                                                                                                                                                                                                                                      |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `X-Agnostic-Cache-Refresh-Trigger` | <p>The value must be a float between 0 and 1.<br>On cache hit, we compute the ratio <code>Age / Max-Age</code> with this value and trigger an asynchronous cache refresh when the value is higher than the aforementioned ratio.</p> |

Some cache-related headers are set on the response.

| header             | meaning                                                                                                                                                                                                                                               |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `X-Agnostic-Cache` | will be set to `hit` if the resultset comes from the cache, `miss` otherwise                                                                                                                                                                          |
| `Cache-Control`    | `max-age`, `no-cache` and `no-store` directives will be set to ensure no intermediate (browser, proxy, ...) cache the response. This ensures we have complete control over caching so that features like asynchronous cache refresh work as expected. |
| `Age`              | this header is set on cache hit with the age (in seconds) of the served result                                                                                                                                                                        |


# Authentication


# Authentication details

{% content-ref url="/pages/E9VrzzUO0z4YsfWe54pn" %}
[Broken mention](broken://pages/E9VrzzUO0z4YsfWe54pn)
{% endcontent-ref %}

{% content-ref url="/pages/gor1hNzM4imXE8lmCb6P" %}
[PostgreSQL](/fundamentals/authentication-details/postgresql)
{% endcontent-ref %}


# PostgreSQL

{% hint style="info" %}
You can use a wide range of tools thanks to this compatibility: [psql](https://www.postgresql.org/docs/current/app-psql.html), [Grafana](https://grafana.com/), [Superset](https://superset.apache.org/), or even [TablePlus](https://tableplus.com/).
{% endhint %}

## Connection details

<table><thead><tr><th width="374">Field</th><th>Value</th></tr></thead><tbody><tr><td><strong>host</strong></td><td><p><code>pg.eu-west-1.agnostic.engineering</code></p><p><code>pg.us-east-1.agnostic.engineering</code></p></td></tr><tr><td><strong>port</strong></td><td><code>5432</code></td></tr><tr><td><strong>user</strong></td><td><code>&#x3C;Authentication Token></code></td></tr></tbody></table>

Here is an example with `psql`:

```
psql -h sql.eu-west-1.agnostic.engineering -p 5432 -U GZRewjgxJ1jDatk84FtrVmg7kLeHine3VyPkJcQzf1s9
```

<figure><img src="/files/8wJ1uWatwrWUq3nZH3Ow" alt=""><figcaption></figcaption></figure>


# HTTP

## Connection details

<table><thead><tr><th width="374">Field</th><th>Value</th></tr></thead><tbody><tr><td><strong>host</strong></td><td><p><code>sql.eu-west-1.agnostic.engineering</code></p><p><code>sql.us-east-1.agnostic.engineering</code></p></td></tr><tr><td><strong>port</strong></td><td><code>443</code></td></tr><tr><td><strong>access token</strong></td><td><code>Either as </code><mark style="color:blue;"><code>Authorization</code></mark><code> header or as </code><mark style="color:blue;"><code>token</code></mark><code> query parameter.</code></td></tr></tbody></table>

Here is examples with `curl`:

```
curl 'https://sql.eu-west-1.agnostic.engineering/query?authorization=GZRewjgxJ1jDatk84FtrVmg7kLeHine3VyPkJcQzf1s9' --data 'select max(block_number) from evm_events_ethereum_mainnet_v1'
```


# Understanding Projects

Projects are the namespace for your resources; They help you group your Charts and GraphQL API, like a folder.

<figure><img src="/files/tESMjREW4pbr2xeoHIXZ" alt=""><figcaption></figcaption></figure>


# Collaborate with your team


# Setting permissions

{% hint style="warning" %}
**Agnostic Tip:** Set the right level of permission to protect your work and your production workload.
{% endhint %}

## Permission levels

You will encounter three levels of permission in the application:

<table><thead><tr><th width="180">Role</th><th>Capabilities</th></tr></thead><tbody><tr><td>Owner</td><td>Has all admin privileges</td></tr><tr><td>Editor</td><td>Can edit resources</td></tr><tr><td>Viewer</td><td>Can only view resources</td></tr></tbody></table>


# Inviting Members

**Adding Users to Your Organization in Agnostic**

{% hint style="warning" %}
**Prerequisites:**&#x20;

Before we begin, please ensure that you are logged into your **Agnostic** account and have the right permissions to add a team member to your organization.
{% endhint %}

1. Navigate to the "Team" page within your Organization page. This is where you can manage the members of your organization.
2. On the "Team" page, you should see an option to "+ New member". Click on this option to begin.
3. In the provided dialog, enter the email address of the user you want to add to your organization. Ensure that you have the correct email address as this will be used to identify and grant access to the user.
4. Next, select the role you want to assign to the user. You will be able to change it later at will.
5. After specifying the email address and role, click the "Invite" button to add the user to your organization.
6. The user will now be included in your organization with the assigned role. They will have access to the resources and features corresponding to their role within Agnostic.
7. The added user will not typically receive an email invitation since there's no invitation system in place. Instead, their access will be activated immediately upon being added to the organization.

By following these steps, you can efficiently manage and add users to your Agnostic organization, allowing your team members to collaborate and work together on your blockchain data projects.


