Examples of common flows
Here are some common architectural flows you may need to integrate into your application. These include ways to gather the prerequisite data necessary for each backend functionality described earlier.
Get a campaign's CID
To get a hold of a campaign's IPFS CID you can:
Check the create event emitted by the Merkle factory
- Use the Sablier V2 subgraphs / indexers to query for that particular piece of information.
For approach "B", run the following query against the official endpoints:
- The Graph
- Envio
query getCampaignData($campaignId: String!){
campaign(id: $campaignId){
id
lockup
root
ipfsCID
aggregateAmount
totalRecipients
}
}
query getCampaignData($campaignId: String!){
Campaign(where: {id: {_eq: $campaignId}} ){
id
lockup
root
ipfsCID
aggregateAmount
totalRecipients
}
}
Check eligibility for an address
To check if an address is eligible, you'll have to use the /api/eligibility route provided by the v2-merkle-api backend.
Steps
- Get the campaign CID (see the example above)
- Call the
/api/eligibility
route using the CID and the wallet address
Please read more on the dedicated route documentation within the /api/eligibility section of the functionality page.
As an alternative, you can also check the eligibility of an address (and bypass the backend) by simply searching for that address in the list stored within the IPFS file from step 1. You'll still have to download the file first, using its CID.
Get the tokenId after a claim
After someone claims, you may want to show them a preview of the stream (or its NFT). To do that, you'll have to get a
hold of the tokenId
(or streamId
) related to that user's claim.
To get a hold of a tokenId
linked to a claim you can:
Listen to the claim method and the Claim event emitted by the Merkle contract instance
- Use the Sablier V2 subgraphs / indexers to query for that particular piece of information.
For approach "B", run the following query against the official endpoints (make sure the address is lowercased):
- The Graph
- Envio
query getClaimForRecipient($campaignId: String!, $recipient: String){
actions(where: {campaign: $campaignId, category: Claim, claimRecipient: $recipient }){
campaign{
id
lockup
}
claimTokenId
claimRecipient
claimIndex
}
}
query getClaimForRecipient($campaignId: String!, $recipient: String){
Action(where: {
_and: [
{campaign: {_eq: $campaignId}}
{category: {_eq: Claim}}
{claimRecipient: {_eq: $recipient}}
]
}){
campaignObject{
id
lockup
}
claimTokenId
claimRecipient
claimIndex
}
}
Bonus: Stream NFT
To get the Stream NFT, using the same query as in option "B", retrieve the lockup
contract (where the Stream NFT is
issued) and its tokenId
. With them you can call the
tokenURI
method, which will return the SVG
code of the onchain NFT.
The actual SVG tags are encoded inside the response of the tokenURI
method. You can feed this blob to an HTML img
tag or choose to render the SVG tags themselves. To get a hold of this code in plain format (not in base64
) you could
run the following Javascript code which decodes the response and
const toPart = output.split("data:application/json;base64,").pop();
const toString = Buffer.from(toPart || "", "base64").toString("utf-8");
const toJSON = JSON.parse(toString);
const blob = _.get(toJSON, "image")?.split("data:image/svg+xml;base64,")[1];
const toSVG = Buffer.from(blob || "", "base64").toString("utf-8");
Check if a user claimed their stream
To check if a user has already claimed their stream from a campaign you can:
Call the hasClaimed method form the Merkle contract instance
- Use the Sablier V2 subgraphs / indexers to query for that particular piece of information.
Approach A
For approach "A" you'll need to perform the following actions:
- Get a hold of the campaign's CID, lockup contract and user address (for the first items, see the Get a campaign's CID example above)
- Check the eligibility of a user (see Eligibility example
above) and extract their
index
- Call the
hasClaimed
method inside thelockup
contract using theindex
retrieved at step 2
The index of a particular user represents their assigned order number in the eligibility list. We use this value to generate a proof in case the recipient is eligible and to register their claim directly inside the contract.
Approach B
For approach "B", run the same query as in the Get the tokenId after a claim example. If the query yields any results, that means the user has claimed their stream.
A missing claim could also mean the user wasn't eligible in the first place. We recommend checking for eligibility alongside any existing claim checks.