Subgraph
Hungry for data? Hot n' fresh Superfluid subgraphs ready to consume!
The Graph is the indexing layer of our industry. There is an ocean of open data created by blockchain networks, and the Graph will help you query it. You can use the Graph to get data on activity in the Superfluid ecosystem as well as many other types of on-chain data. You can also use the GraphQL Playground to start getting Superfluid specific data on any network.
URLs
Click a link to start testing queries in the playground:
Optimism Kovan
Arbitrum Rinkeby
Resources
โญNew to GraphQL required reading - https://graphql.org/learn/
How to make subgraph queries - https://thegraph.com/docs/en/developer/query-the-graph/
Deploy your own subgraph - https://thegraph.com/docs/en/developer/create-subgraph-hosted/
GraphQL Schema for Superfluid - https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/subgraph/schema.graphql
Apollo Client - for writing queries in your front end - https://www.apollographql.com/docs/
Contributing & Local Deployment
If you'd like to help improve the subgraph, there is a complete development guide available in the repo:
Helpful Tips
All addresses (
id
,underlyingAddress
, etc.) are lowercase (i.e. not checksummed). Be sure to convert addresses to lowercase first before making queries.
Notable Breaking Changes When Migrating From Our Legacy Subgraph to V1 (as of October 2021)
The field
totalSubscriptions
on theIndex
,AccountTokenSnapshot
andTokenStatistic
types is nowtotalSubscriptionsWithUnits
.The
Subscriber
entity has been changed toSubscription
. If you have been using thesubscriber
property when querying any events, this has been changed tosubscriptions
everywhere. The only place wheresubscriber
is still a field is on theSubscription
entity as a property of typeAccount
.The
createdAt
andupdatedAt
fields are nowcreatedAtTimestamp
andupdatedAtTimestamp
on every type.
Schema
The Superfluid Subgraph consists of many entities that can be queried. You can think of entities as similar to tables within a traditional database. We have added significantly more entities in October 2021 - particularly new event entities and aggregate entities. We'll give you an overview of the subgraph's structure in this post, but you can always dive deeper by looking at the schema inside of our repository.
Event Entities
These entities are for the most part 1-to-1 mappings with the raw events from the contract. However for some of them, we have added additional data. This is noted in the schema.graphql
file and will be viewable in the playground as well. These entities are created once and never updated. For example, the FlowUpdatedEvent
type will mirror the properties on the FlowUpdated
event inside of the Superfluid contracts.
Note: Each event entity
id
is formulated as follows:eventName-transactionHash-logIndex
.
Note: event types in our legacy subgraph did not have 'Event' appended onto the end of their name. In our new v1 implementation, every event type is named 'Event Name' + 'Event.' For example,
FlowUpdated
is nowFlowUpdatedEvent
andIndexCreated
is nowIndexCreatedEvent
. This schema is applied to every other event type as well.
Higher Order Level Entities
Higher order level entities (HOL) are an additional abstraction on top of events. They are not ephemeral in the same way the event entities are. They contain data on an entity over its "lifetime" and therefore may be updated over time. Here is an overview of our Higher Order Level Entities:
Account
An entity created for any address which interacts with the Superfluid protocol.
Token
An entity created for all 'valid' SuperTokens. Valid tokens are defined as tokens that have set the Superfluid host's value to the correct Superfluid host address within the token contract.
Note: this network directory is where you can find the address of the host for each network.
Index
An entity that represents an Index
within a Superfluid instant distribution agreement (IDA)
IndexSubscription
An entity that contains subscription data for a subscriber
account of a particular index
Stream
An entity that represents the lifetime of a stream between a sender
and a receiver
. An account can create a stream or update its flow rate, but when they delete it, it is considered "dead." The next stream that is created between the same sender
and receiver
will generate a new stream entity. Therefore, multiple stream entities can be created between the same sender
and receiver
.
StreamPeriod
An entity that represents a period of time in a Stream
with a specific constant flowRate. You can think of it as a portion of a Stream
. Each time a Stream's flowRate
is updated, a new StreamPeriod
will be created.
Note: the stream type is a replacement for the previously used Flow type (as of October '21). The below image provides a good visual outline of how the
Stream
andStreamPeriod
types compare to the previously usedFlow
type.
Aggregate Entities
Aggregate entities are exactly what the name suggests - they are entities that store aggregate data. More specifically, we do this at an account-token level and also at a global token level. Here is an overview of our two Aggregate Entities:
TokenStatistic
An entity which aggregates all data for a single Token type.
AccountTokenSnapshot
An aggregate entity which aggregates data on an account's interaction with a given token
.
Examples
There are many different ways to get the same data using GraphQL. Here are some examples to help get you started using the Superfluid subgraphs.
Super Token Data
The number of items returned by a query can sometimes be limited. In this example, we are explicitly requesting that up to 100 items should be returned, by using the first
parameter
Note: keep in mind that a maximum of 1000 items may be returned in a single query.
Get All Streams for a Given Account
List all streams that an account is currently receiving. You can swap receiver for sender to get all streams that an account is currently sending.
Getting Stream Data Between 2 Parties
The following query will allow us to answer the following questions for an active stream between Alice ("0x658...") and Bob ("0xd66...")
token
will return the token entity type - with the symbol
and id
in this case.
createdAtTimestamp
will return the timestamp at which the stream
was created.
updatedAtTimestamp
will return the timestamp of the last time the stream was updated.
currentFlowRate
will return the current flow rate of the stream.
streamedUntilUpdatedAt
will return the amount streamed until updatedAtTimestamp
/updatedAtBlock
Note: to get the current (dynamic) total amount streamed, you can use the following formula: streamedUntilUpdatedAt + ((current time in seconds) - updatedAtTimestamp) * currentFlowRate
Get The Most Recently Updated Flows
Here, we can query the FlowUpdatedEvent type and use first
, orderBy
and orderDirection
to get the 10 most recently updated flows.
Note: as explained in the previous higher order level entities section under the
Stream
type, it's important to understand the difference between a Flow and a Stream. A Flow represents all streaming activity between 2 addresses for a given token, while a Stream may only represent a portion of that flow. A new stream period is created each time theflowRate
is updated, and a new stream is created each time a stream is terminated and restarted again (with the creation happening upon restarting)
oldFlowRate
- the flowRate of the previous stream (will return "0" if this is a newly created Flow)
flowRate
- the flowRate of the current stream
userData
- user data associated with the update.
stream
- the Stream type associated with the flow. In our case, the next few items will come from the Stream type. Several streams may be returned if there have been multiple streams created for this flow
.
token
- the token
used in the updated flow. Here we are returning this token's symbol
sender
- the sender
of the updated flow. Here we will return this sender's id
(their address)
receiver
- the receiver
of the updated flow. Here we will return this receiver's id
(their address)
Get an Account's IDA Index Subscriptions
Here, we can query all of the subscriptions a particular account is subscribed to.
subscriptions
will return an IndexSubscription
type for each Index
that this account is subscribed to
token
- the Token
used in each subscription. Here we display the symbol
.
id
- the ID of the IndexSubscription
. This ID is composed of: subscriberAddress
-publisherAddress
-tokenAddress
-IndexId
approved
- a boolean value that represents whether or not the subscription is approved
. Approved subscriptions don't require subscribers to claim tokens that are distributed from the publisher.
units
- the total number of units allocated to this account in the index. If units
is 0, it indicates that the subscription is "deleted". They are no longer subscribed to the index.
totalAmountReceivedUntilUpdatedAt
- the total amount of tokens that this account has received via this IDA index until updatedAtTimestamp
/updatedAtBlock
.
Get Recent Index Information By Querying an Event Type
In this example, we can filter by & return data using a combination of an event type and HOL type. Here, we'll get the 10 most recent indexUpdatedEvents where the newIndexValue is greater than 1000 tokens.
We'll return the following from the Index type
indexValue
- used to calculate the distribution amount that a user receives when the publisher updates the index value. The distribution amount can be calculated using the following formula:
(index.indexValue - subscriber.indexValue) * subscriber.units
totalUnitsPending
- he number of units allocated by the Index
that are pending. This refers to the current (as of updatedAt) totalUnitsPending
- not all that has ever been pending.
totalUnitsApproved
- he number of units allocated by the Index
that have been approved. This refers to the current (as of updatedAt) totalUnitsApproved
- not all that has ever been approved.
totalUnits
- the sum of totalUnitsPending
and totalUnitsApproved
.
token
- the type Token
used in the index.
symbol
- the symbol of the Token
used in the index
Get Aggregate Flow Data For a Given Token
As an example of how to use aggregate entities, let's take a look at a query using the Token Statistic type. In this case, we can see aggregate data for Super DAI on Polygon.
totalNumberOfActiveStreams
- the total count of active streams using the token.
totalNumberOfActiveIndexes
- total number of active IDA indexes for the token.
totalAmountStreamedUntilUpdatedAt
- all-time total amount streamed until the updatedAtTimestamp
/updatedAtBlock
.
totalOutFlowRate
- total outflow rate of the token
(how much value is being moved).
totalAmountDistributedUntilUpdatedAt
- all-time total amount distributed until the updatedAtTimestamp
/updatedAtBlock
.
Get Data On a Specific Account
To query data on a specific account, we can use both the Account entity and the aggregate AccountTokenSnapshot entity. Note: if you're only interested in seeing an account's activity with a particular token, you can query AccountTokenSnapshot to get that data. Otherwise, the Account
entity will return an AccountTokenSnapshot
for every token used for each id
(i.e. for each Account's address).
On the Account
entity:
isSuperApp
- returns true
if the account is a super app, false
if not.
inflows
- will return all Streams
where Account
is the sender
.
outflows
- will return all Streams
where Account
is the receiver
.
On the AccountTokenSnapshot
entity:
token
- the address of the token used in streams or subscriptions
totalNumberOfActiveStreams
- the total number of streams the account is associated with for the given token
totalNetFlowRate
- the total net flow rate of the account
for the given token as of updatedAtTimestamp
/updatedAtBlock
.
Your query here!
If you design a useful query, let us know and we will share it here!
Legacy Subgraph Documentation
Legacy Subgraph URLs
Click a link to start testing queries in the playground:
Legacy Schema
The Legacy schema contains fewer entities and some subtle differences in schema. These differences are outlined in the above sections, but you can find the previous schema in full here:
NOTE: Please refer to the above section on Breaking Changes as of October 2021, and the section on Streams vs Flows in the above section on the V1 Subgraph documentation. For example, you'll notice in the below example that the
Flow
type is used in a query. This type has been deprecated.
How much USDCx has Alice streamed to Bob? [Legacy Query]
The Subgraph can only return a flow's sum
since the last on-chain event (flowUpdated
, flowCreated
, or flowDeleted
). Therefore, if flowRate
is greater than zero, you will need to calculate the tokens flowed since the last event. Use this equation to get the the total sum of tokens flowed:
Last updated
Was this helpful?