Cover Image for Conditional Aggregation in GraphQL APIs

Conditional Aggregation in GraphQL APIs

GraphQL Tutorials

We have introduced three new functions to enable conditional aggregation in our APIs.

These three functions are:

  • any
  • maximum
  • minimum

These functions allow different types of aggregation on any APIs and also provide a natural way to extract the events that were not possible previously.

In this article, we will show you getting events using these as well as how to use these functions in any other API.

Fetching Uniswap Events

In the following example, we are getting Swap event for the USDC/ETH pair on the Uniswap.

You can run the query below to check the results and see how Bitquery APIs are giving events in a natural way, unlike before, where you need to add some logic to parse them.

{
  ethereum(network: ethereum) {
    arguments(
      options: { limitBy: { each: "sender", limit: 1 }, desc: "block.height" }
      smartContractAddress: { is: "0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc" }
      smartContractEvent: { is: "Swap" }
    ) {
      block {
        height
      }
      transaction {
        hash
      }
      sender: any(of: argument_value, argument: { is: "sender" })
      to: any(of: argument_value, argument: { is: "to" })
      amount0In: any(of: argument_value, argument: { is: "amount0In" })
      amount0Out: any(of: argument_value, argument: { is: "amount0Out" })
      amount1In: any(of: argument_value, argument: { is: "amount1In" })
      amount1Out: any(of: argument_value, argument: { is: "amount1Out" })
    }
  }
}

Let’s dive deep into the above query and see what’s going on.

As you can see, we have a new function any that takes multiple optional arguments. (Only of is a mandatory argument)

  • of* : You can use any attribute here, date, txHash, argument_value
  • get: specific field you want (will see example below)
  • Filters: In the above example, it is argument

For example, the following line means, give me any argument’s value where the argument is amount0In .

amount0In: any(of: argument_value, argument: {is: "amount0In"})

Also notice, we were using limitBy clause for limiting our results based on the argument name. You can use any argument name to limit your results.

Now, let’s say you want the maximum value of a particular argument by comparing all events. You can do something like the following.

{
  ethereum(network: ethereum) {
    arguments(
      options: { limit: 10 }
      smartContractAddress: { is: "0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc" }
      smartContractEvent: { is: "Swap" }
    ) {
      amount1Out: maximum(of: argument_value, argument: { is: "amount1Out" })
    }
  }
}

Focus on the following line, in which we are getting the maximum of the argument’s value where the argument is amount1Out.

amount1Out: maximum(of: argument_value, argument: {is: "amount1Out"})

Let’s say you want to know who was the caller for this transaction or when this transaction was executed. You can replace the above line with the following.

Getting the Caller for the tx which emitted event with max amount1Out. ?

amount1Out: maximum(of: argument_value, get: caller,
argument: {is: "amount1Out"})

Getting the date for the tx which emitted event with max amount1Out. ?

amount1Out: maximum(of: argument_value, get: date,
argument: {is: "amount1Out"})

Digging into a particular address

Now let’s say you want to know the maximum amount1Out for a particular address. You can use txFrom attributes in the filter or in the maximum function.

txFrom in maximum function

{
  ethereum(network: ethereum) {
    arguments(
      options: { limit: 10 }
      smartContractAddress: { is: "0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc" }
      smartContractEvent: { is: "Swap" }
    ) {
      amount1Out: maximum(
        of: argument_value
        txFrom: { is: "0x514950ab8697f4142ea6ac0bd6c60e06cbb0a009" }
        argument: { is: "amount1Out" }
      )
    }
  }
}

txFrom in the Filters

{
  ethereum(network: ethereum) {
    arguments(
      options: { limit: 10 }
      txFrom: { is: "0x514950ab8697f4142ea6ac0bd6c60e06cbb0a009" }
      smartContractAddress: { is: "0xb4e16d0168e52d35cacd2c6185b44281ec28c9dc" }
      smartContractEvent: { is: "Swap" }
    ) {
      amount1Out: maximum(of: argument_value, argument: { is: "amount1Out" })
    }
  }
}

Using conditional aggregation in DEX APIs

Let’s say you want to know the details of Uniswap trade with the maximum buy amount. Here is how you can use the maximum function to get that.

{
  ethereum {
    dexTrades(exchangeName: { is: "Uniswap" }) {
      buyamount: maximum(of: buy_amount)
      maker: maximum(of: buy_amount, get: maker)
      taker: maximum(of: buy_amount, get: taker)
      txHash: maximum(of: buy_amount, get: tx_hash)
    }
  }
}

Transaction APIs

Let’s say you want to know the biggest transaction done by an address. You can get the using our transaction API and maximum function.

{
  ethereum {
    transactions(
      txSender: { is: "0x2c82E14352e98c931852D9BB5f0760E36942CC3c" }
    ) {
      amount: maximum(of: amount)
      currency {
        symbol
      }
    }
  }
}

If you dig into our schema, you will see that anymaximum and minimum function supports many different attributes and can be used with different types of APIs such as smart contract, transaction, caller, event, etc.

You can use minimum function similar to the maximum function.

In the coming months, we will be adding more functions to make it easier to work with Blockchain data. These functions are an essential part of our next big update Flexigraph, which will allow anyone to build their own schema on our schema and customize it based on your application context.

You might also be interested in:

About Bitquery

Bitquery is your comprehensive toolkit designed with developers in mind, simplifying blockchain data access. Our products offer practical advantages and flexibility.

  • APIs - Explore API: Easily retrieve precise real-time and historical data for over 40 blockchains using GraphQL. Seamlessly integrate blockchain data into your applications, making data-driven decisions effortless.

  • Coinpath® - Try Coinpath: Streamline compliance and crypto investigations by tracing money movements across 40+ blockchains. Gain insights for efficient decision-making.

  • Data in Cloud - Try Demo Bucket: Access indexed blockchain data cost-effectively and at scale for your data pipeline. We currently support Ethereum, BSC, Solana, with more blockchains on the horizon, simplifying your data access.

  • Explorer - Try Explorer: Discover an intuitive platform for exploring data from 40+ blockchains. Visualize data, generate queries, and integrate effortlessly into your applications.

Bitquery empowers developers with straightforward blockchain data tools. If you have questions or need assistance, connect with us on our Telegram channel or via email at sales@bitquery.io. Stay updated on the latest in cryptocurrency by subscribing to our newsletter below.

Subscribe to our newsletter

Subscribe and never miss any updates related to our APIs, new developments & latest news etc. Our newsletter is sent once a week on Monday.