Token Gate User By Certain Fan Token
In this tutorial, you will learn how to build token gate feature to limit access to a certain fan token holders by calling the Moxie Protocol Subgraph API.
You can either use the subgraph APIs or Airstack API to build Fan Token gating for your app/project.
Method #1: Airstack API
Using the Airstack MoxieUserPortolio
API, you can simply provide the user FID and the designated Fan Token to check their holdings, both staked and non-staked in the Moxie Power Staking contract.
To learn more, click here.
Method #2: Subgraphs
Moxie protocol users have Moxie token currently vesting in their vesting contract. A huge portion of them use these to bid on auctions and buy/sell fan tokens on the Moxie protocol.
Therefore, it is important that you include the user's vesting addresses in the query when building token gate feature to limit access to a certain token holders. To get user's vesting contract addresses, click here.
Pre-requisites
Install dependenciesgraphql
and graphql-request
to your project :- npm
- yarn
- pnpm
- bun
npm install graphql graphql-request
yarn add graphql graphql-request
pnpm add graphql graphql-request
bun install graphql graphql graphql-request
Step 1: Add The API Query To Your Code
To build token gate feature to limit access to a certain fan token holders, you can use the following query:
- Query
- Variable
- Response
query MyQuery($userAddresses: [ID!], $fanTokenSymbol: String) {
users(where: { id_in: $userAddresses }) {
portfolio(where: { subjectToken_: { symbol: $fanTokenSymbol} }) {
balance
}
}
}
{
"userAddresses": [
"0x00d620def6ccb76c92dbfc87bc2bebab7637ec53"
],
/**
* There are 3 types of fan tokens, here's how the symbol is formatted:
* - USER -> fid:<fid>
* - CHANNEL -> cid:<channel-id>
* - NETWORK (Only for Farcaster) -> id:farcaster
*/
"fanTokenSymbol": "cid:fitness"
}
{
"data": {
"users": [
{
"portfolio": [
{
"balance": "10000000000000000000"
}
]
}
]
}
}
graphql-request
library:- TypeScript
- JavaScript
import { gql, GraphQLClient } from "graphql-request";
const graphQLClient = new GraphQLClient(
"https://api.studio.thegraph.com/query/23537/moxie_protocol_stats_mainnet/version/latest"
);
const query = gql`
query MyQuery($userAddresses: [ID!], $fanTokenSymbol: String) {
users(where: { id_in: $userAddresses }) {
portfolio(where: { subjectToken_: { symbol: $fanTokenSymbol} }) {
balance
}
}
}
`;
const variable = {
"userAddresses": [
"0x00d620def6ccb76c92dbfc87bc2bebab7637ec53"
],
/**
* There are 3 types of fan tokens, here's how the symbol is formatted:
* - USER -> fid:<fid>
* - CHANNEL -> cid:<channel-id>
* - NETWORK (Only for Farcaster) -> id:farcaster
*/
"fanTokenSymbol": "cid:fitness"
}
try {
const data = await graphQLClient.request(query, variable);
console.log(
// Check if the user has a balance greater than 0
Number.parseInt(data?.users?.[0]?.portfolio?.[0]?.balance) > 0
);
} catch (e) {
throw new Error(e);
}
const { gql, GraphQLClient } = require("graphql-request");
const graphQLClient = new GraphQLClient(
"https://api.studio.thegraph.com/query/23537/moxie_protocol_stats_mainnet/version/latest"
);
const query = gql`
query MyQuery($userAddresses: [ID!], $fanTokenSymbol: String) {
users(where: { id_in: $userAddresses }) {
portfolio(where: { subjectToken_: { symbol: $fanTokenSymbol} }) {
balance
}
}
}
`;
const variable = {
"userAddresses": [
"0x00d620def6ccb76c92dbfc87bc2bebab7637ec53"
],
/**
* There are 3 types of fan tokens, here's how the symbol is formatted:
* - USER -> fid:<fid>
* - CHANNEL -> cid:<channel-id>
* - NETWORK (Only for Farcaster) -> id:farcaster
*/
"fanTokenSymbol": "cid:fitness"
}
try {
const data = await graphQLClient.request(query, variable);
console.log(
// Check if the user has a balance greater than 0
Number.parseInt(data?.users?.[0]?.portfolio?.[0]?.balance) > 0
);
} catch (e) {
throw new Error(e);
}
Step 2: Execute Your Code
Once you have your code ready, you can execute it by running the following command:
- TypeScript
- JavaScript
ts-node index.ts
node index.js
If it runs successfully, you should see the data returned in the terminal:
true // true if balance is greater than 0, otherwise false
Congrats! 🥳🎉 You've just fetched user's balance of a certain fan token and use it to build token gate feature to limit access to a certain fan token holders!
Developer Support
If you have any questions or need help with other use cases, feel free to join the /airstack Warpcast channel and ask your questions there.
Our team is always ready to help you with any questions you may have.