You can limit access to your Farcaster Frame to only certain users that fulfill a requirement by creating an allow list based on certain criteria.
Allow List Demo Get Started
First, install the Airstack Frog Recipes:
npm yarn pnpm bun
Copy npm install @airstack/frog hono
Copy yarn add @airstack/frog hono
Copy pnpm install @airstack/frog hono
Copy bun install @airstack/frog hono
Create A Custom Allow List
You can create an allow list that checks various onchain data easily using the createAllowList
function. Some of the parameters that you can add to the allow list are:
Name Type Description POAP Gating â Check If POAPs with the given event IDs are attended by a Farcaster user.
numberOfFollowersOnFarcaster
Check If the number of Farcaster followers greater than or equal to the given number.
Check if the given FIDs are being followed by a Farcaster user.
{tokenAddress: string; chain: TokenBlockchain;}[]
Token Gating â Check If tokens are currently held by a Farcaster user.
Once you have the criteria set, the function will help you check whether all the criterias are fulfilled.
By default, it will only return true
for Farcaster users that satisfy ALL the given requirements. However, if you would like to check your user with a different logic, you can provide an optional custom isAllowedFunction
:
TypeScript JavaScript Response
Copy import {
createAllowList ,
CreateAllowListInput ,
CreateAllowListOutput ,
TokenBlockchain ,
} from "@airstack/frames" ;
const allowListCriteria = {
eventIds : [ 166577 ] ,
numberOfFollowersOnFarcaster : 100 ,
isFollowingOnFarcaster : [ 2602 ] ,
tokens : [
{
tokenAddress : "0x95cb845b525f3a2126546e39d84169f1eca8c77f" ,
chain : TokenBlockchain .Ethereum ,
} ,
{
tokenAddress : "0x2d45c399d7ca25341992038f12610c41a00a66ed" ,
chain : TokenBlockchain .Base ,
} ,
{
tokenAddress : "0x743658ace931ea241dd0cb4ed38ec72cc8162ce1" ,
chain : TokenBlockchain .Zora ,
} ,
] ,
};
const input : CreateAllowListInput = {
fid : 602 ,
allowListCriteria ,
isAllowedFunction : function (data) {
console .log (data);
return true ;
} ,
};
const { isAllowed , error } : CreateAllowListOutput = await createAllowList (
input
);
if (error) throw new Error (error);
console .log (isAllowed);
Copy const { createAllowList , TokenBlockchain } = require ( "@airstack/frames" );
const allowListCriteria = {
eventIds : [ 166577 ] ,
numberOfFollowersOnFarcaster : 100 ,
isFollowingOnFarcaster : [ 2602 ] ,
tokens : [
{
tokenAddress : "0x95cb845b525f3a2126546e39d84169f1eca8c77f" ,
chain : TokenBlockchain .Ethereum ,
} ,
{
tokenAddress : "0x2d45c399d7ca25341992038f12610c41a00a66ed" ,
chain : TokenBlockchain .Base ,
} ,
{
tokenAddress : "0x743658ace931ea241dd0cb4ed38ec72cc8162ce1" ,
chain : TokenBlockchain .Zora ,
} ,
] ,
};
const input = {
fid : 602 ,
allowListCriteria ,
isAllowedFunction : function (data) {
console .log (data);
return true ;
} ,
};
const { isAllowed , error } = await createAllowList (input);
if (error) throw new Error (error);
console .log (isAllowed);
Copy {
"isAllowed" : true ,
"error" : null
}
Check If POAP(s) Is Attended By A Farcaster User
You can check if a Farcaster user has attended a given list of POAP event IDs by using the checkPoapAttendedByFarcasterUser
function:
TypeScript JavaScript Response
Copy import {
checkPoapAttendedByFarcasterUser ,
CheckPoapAttendedByFarcasterUserInput ,
CheckPoapAttendedByFarcasterUserOutput ,
} from "@airstack/frames" ;
const input : CheckPoapAttendedByFarcasterUserInput = {
fid : 15971 ,
eventId : [ 160005 , 159993 , 13242 ] ,
};
const { data , error } : CheckPoapAttendedByFarcasterUserOutput =
await checkPoapAttendedByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy const { checkPoapAttendedByFarcasterUser } = require ( "@airstack/frames" );
const input = {
fid : 15971 ,
eventId : [ 160005 , 159993 , 13242 ] ,
};
const { data , error } = await checkPoapAttendedByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy [
{ "eventId" : 160005 , "isAttended" : true } ,
{ "eventId" : 159993 , "isAttended" : true } ,
{ "eventId" : 13242 , "isAttended" : false }
]
Check If Token(s) Hold By A Farcaster User
You can check if a Farcaster user is holding a given list of tokens across Ethereum, Base, Degen Chain, and other Airstack-supported chains by using the checkTokenHoldByFarcasterUser
function:
TypeScript JavaScript Response
Copy import {
checkTokenHoldByFarcasterUser ,
CheckTokenHoldByFarcasterUserInput ,
CheckTokenHoldByFarcasterUserOutput ,
TokenBlockchain ,
} from "@airstack/frames" ;
const input : CheckTokenHoldByFarcasterUserInput = {
fid : 15971 ,
token : [
{
chain : TokenBlockchain .Base ,
tokenAddress : "0x4c17ff12d9a925a0dec822a8cbf06f46c6268553" ,
} ,
{
chain : TokenBlockchain .Ethereum ,
tokenAddress : "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85" ,
} ,
{
chain : TokenBlockchain .Zora ,
tokenAddress : "0xa15bb830acd9ab46164e6840e3ef2dbbf9c5e2b3" ,
} ,
] ,
};
const { data , error } : CheckTokenHoldByFarcasterUserOutput =
await checkTokenHoldByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy import {
checkTokenHoldByFarcasterUser ,
TokenBlockchain ,
} from "@airstack/frames" ;
const input = {
fid : 15971 ,
token : [
{
chain : TokenBlockchain .Base ,
tokenAddress : "0x4c17ff12d9a925a0dec822a8cbf06f46c6268553" ,
} ,
{
chain : TokenBlockchain .Ethereum ,
tokenAddress : "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85" ,
} ,
{
chain : TokenBlockchain .Zora ,
tokenAddress : "0xa15bb830acd9ab46164e6840e3ef2dbbf9c5e2b3" ,
} ,
] ,
};
const { data , error } = await checkTokenHoldByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy [
{
"chain" : "base" ,
"tokenAddress" : "0x4c17ff12d9a925a0dec822a8cbf06f46c6268553" ,
"isHold" : false
} ,
{
"chain" : "ethereum" ,
"tokenAddress" : "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85" ,
"isHold" : true
} ,
{
"chain" : "zora" ,
"tokenAddress" : "0xa15bb830acd9ab46164e6840e3ef2dbbf9c5e2b3" ,
"isHold" : true
}
]
Check If Token(s) Minted By A Farcaster User
You can check if a Farcaster user has minted a given list of tokens across Ethereum, Base, Degen Chain, and other Airstack-supported chains by using the checkTokenHoldByFarcasterUser
function:
TypeScript JavaScript Response
Copy import {
checkTokenMintedByFarcasterUser ,
CheckTokenMintedByFarcasterUserInput ,
CheckTokenMintedByFarcasterUserOutput ,
TokenBlockchain ,
} from "@airstack/frames" ;
const input : CheckTokenMintedByFarcasterUserInput = {
fid : 15971 ,
token : [
{
chain : TokenBlockchain .Base ,
tokenAddress : "0x57965af45c3b33571aa5419cc5e9012d8dcab181" ,
} ,
{
chain : TokenBlockchain .Ethereum ,
tokenAddress : "0xad08067c7d3d3dbc14a9df8d671ff2565fc5a1ae" ,
} ,
{
chain : TokenBlockchain .Zora ,
tokenAddress : "0xa15bb830acd9ab46164e6840e3ef2dbbf9c5e2b3" ,
} ,
] ,
};
const { data , error } : CheckTokenMintedByFarcasterUserOutput =
await checkTokenMintedByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy const {
checkTokenMintedByFarcasterUser ,
TokenBlockchain ,
} = require ( "@airstack/frames" );
const input = {
fid : 15971 ,
token : [
{
chain : TokenBlockchain .Base ,
tokenAddress : "0x57965af45c3b33571aa5419cc5e9012d8dcab181" ,
} ,
{
chain : TokenBlockchain .Ethereum ,
tokenAddress : "0xad08067c7d3d3dbc14a9df8d671ff2565fc5a1ae" ,
} ,
{
chain : TokenBlockchain .Zora ,
tokenAddress : "0xa15bb830acd9ab46164e6840e3ef2dbbf9c5e2b3" ,
} ,
] ,
};
const { data , error } = await checkTokenMintedByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy [
{
"chain" : "base" ,
"tokenAddress" : "0x57965af45c3b33571aa5419cc5e9012d8dcab181" ,
"isMinted" : true
} ,
{
"chain" : "ethereum" ,
"tokenAddress" : "0xad08067c7d3d3dbc14a9df8d671ff2565fc5a1ae" ,
"isMinted" : true
} ,
{
"chain" : "zora" ,
"tokenAddress" : "0xa15bb830acd9ab46164e6840e3ef2dbbf9c5e2b3" ,
"isMinted" : false
}
]
Check If User Is Following Farcaster User(s)
You can check if a Farcaster user is following a list of FIDs by using the checkIsFollowingFarcasterUser
function:
TypeScript JavaScript Response
Copy import {
checkIsFollowingFarcasterUser ,
CheckIsFollowingFarcasterUserInput ,
CheckIsFollowingFarcasterUserOutput ,
} from "@airstack/frames" ;
const input : CheckIsFollowingFarcasterUserInput = {
fid : 602 ,
isFollowing : [ 2602 , 15971 , 13242 ] ,
};
const { data , error } : CheckIsFollowingFarcasterUserOutput =
await checkIsFollowingFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy const { checkIsFollowingFarcasterUser } = require ( "@airstack/frames" );
const input = {
fid : 602 ,
isFollowing : [ 2602 , 15971 , 13242 ] ,
};
const { data , error } = await checkIsFollowingFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy [
{ "fid" : 2602 , "isFollowing" : true } ,
{ "fid" : 15971 , "isFollowing" : true } ,
{ "fid" : 13242 , "isFollowing" : false }
]
Check If User Is Followed By Farcaster User(s)
You can check if a Farcaster user is being followed by a list of FIDs by using the checkIsFollowedByFarcasterUser
function:
TypeScript JavaScript Response
Copy import {
checkIsFollowedByFarcasterUser ,
CheckIsFollowedByFarcasterUserInput ,
CheckIsFollowedByFarcasterUserOutput ,
} from "@airstack/frames" ;
const input : CheckIsFollowedByFarcasterUserInput = {
fid : 602 ,
isFollowedBy : [ 2602 , 15971 , 13242 ] ,
};
const { data , error } : CheckIsFollowedByFarcasterUserOutput =
await checkIsFollowedByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy const {
checkIsFollowedByFarcasterUser ,
CheckIsFollowedByFarcasterUserInput ,
CheckIsFollowedByFarcasterUserOutput ,
} = require ( "@airstack/frames" );
const input = {
fid : 602 ,
isFollowedBy : [ 2602 , 15971 , 13242 ] ,
};
const { data , error } = await checkIsFollowedByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy [
{ "fid" : 2602 , "isFollowedBy" : true } ,
{ "fid" : 15971 , "isFollowedBy" : true } ,
{ "fid" : 13242 , "isFollowedBy" : false }
]
Check If Farcaster User Has Any Non-Virtual POAPs
Video Demo You can check if the Farcaster user has attended any non-virtual or in-real-life (IRL) POAP events by providing the Farcaster user's fid
from the Frame Signature Packet to the $farcasterUser
variable using the Poaps
API:
Try Demo
Show me all POAPs owned by a Farcaster user and see if they are virtual or not Code
Query Variables Response
Copy query POAPsOwned ($farcasterUser: Identity ! ) {
Poaps(
input: {
filter : { owner : { _eq : $farcasterUser } }
blockchain : ALL
limit : 50
}
) {
Poap {
mintOrder
mintHash
poapEvent {
isVirtualEvent
}
}
pageInfo {
nextCursor
prevCursor
}
}
}
Copy {
"farcasterUser" : "fc_fid:3"
}
Copy {
"data" : {
"Poaps" : {
"Poap" : [
{
"mintOrder" : 740 ,
"mintHash" : "0xdf9e6af3bab24eaac6e35a0474f97b4373eeff7bfff8fb4c964956860b4975e6" ,
"poapEvent" : {
"isVirtualEvent" : false // This event is non-virtual or IRL
}
} ,
{
"mintOrder" : 5496 ,
"mintHash" : "0x8cbd346bbe318483e4c2134de97dc9e93cbc1e8a9774408d8ff20b747d8cd043" ,
"poapEvent" : {
"isVirtualEvent" : true // This event is virtual or online
}
} ,
// more POAPs held by specified Farcaster user
]
}
}
}
Check If Farcaster User Has Certain POAP(s)
You can check if the Farcaster user has attended certain POAP event(s) by using the checkPoapAttendedByFarcasterUser
function:
TypeScript JavaScript Result
Copy import {
checkPoapAttendedByFarcasterUser ,
CheckPoapAttendedByFarcasterUserInput ,
CheckPoapAttendedByFarcasterUserOutput ,
} from "@airstack/frames" ;
const input : CheckPoapAttendedByFarcasterUserInput = {
fid : 15971 ,
eventId : [ 160005 , 159993 , 13242 ] ,
};
const { data , error } : CheckPoapAttendedByFarcasterUserOutput =
await checkPoapAttendedByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy const { checkPoapAttendedByFarcasterUser } = require ( "@airstack/frames" );
const input = {
fid : 15971 ,
eventId : [ 160005 , 159993 , 13242 ] ,
};
const { data , error } = await checkPoapAttendedByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy [
{ "eventId" : 160005 , "isAttended" : true } ,
{ "eventId" : 159993 , "isAttended" : true } ,
{ "eventId" : 13242 , "isAttended" : false }
]
Check If Farcaster User Has X or More Followers on Farcaster
Video Demo You can check if the Farcaster user has X or more Farcaster followers by providing the Farcaster user's fid
from the Frame Signature Packet to the $farcasterUser
variable using the Socials
API:
Try Demo
Code
Query Variables Response
Copy query MyQuery ($farcasterUser: Identity ! ) {
Socials(
input: {
filter : {
followerCount : { _gt : 100 }
dappName : { _eq : farcaster }
identity : { _eq : $farcasterUser }
}
blockchain : ethereum
limit : 200
}
) {
Social {
followerCount
}
}
}
Copy {
"farcasterUser" : "fc_fid:3"
}
Copy {
"data" : {
"Socials" : {
"Social" : [
{
// Follower number will be shown if above the threshold,
// in this case above 100. Otherwise, will be shown null.
"followerCount" : 131001
}
]
}
}
}
Check If Farcaster User Is Followed By Certain High Profile Users
You can check if the Farcaster user is followed by certain high profile users, e.g. vitalik.eth , jessepollak , etc., by using the checkIsFollowedByFarcasterUser
function:
TypeScript JavaScript Result
Copy import {
checkIsFollowedByFarcasterUser ,
CheckIsFollowedByFarcasterUserInput ,
CheckIsFollowedByFarcasterUserOutput ,
} from "@airstack/frames" ;
const input : CheckIsFollowedByFarcasterUserInput = {
fid : 602 ,
isFollowedBy : [
99 , // jessepollak
5650 , // vitalik.eth
] ,
};
const { data , error } : CheckIsFollowedByFarcasterUserOutput =
await checkIsFollowedByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy const { checkIsFollowedByFarcasterUser } = require ( "@airstack/frames" );
const input = {
fid : 602 ,
isFollowedBy : [
99 , // jessepollak
5650 , // vitalik.eth
] ,
};
const { data , error } = await checkIsFollowedByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy [
{ "fid" : 99 , "isFollowedBy" : true } ,
{ "fid" : 5650 , "isFollowedBy" : false }
]
Check If Farcaster User Hold Any High Value NFTs
You can check if the Farcaster user has any high value NFTs, e.g. BAYC , by using the checkTokenHoldByFarcasterUser
function:
TypeScript JavaScript Result
Copy import {
checkTokenHoldByFarcasterUser ,
CheckTokenHoldByFarcasterUserInput ,
CheckTokenHoldByFarcasterUserOutput ,
TokenBlockchain ,
} from "@airstack/frames" ;
const input : CheckTokenHoldByFarcasterUserInput = {
fid : 21018 ,
token : [
{
chain : TokenBlockchain .Ethereum ,
tokenAddress : "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D" ,
} ,
] ,
};
const { data , error } : CheckTokenHoldByFarcasterUserOutput =
await checkTokenHoldByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy const {
checkTokenHoldByFarcasterUser ,
TokenBlockchain ,
} = require ( "@airstack/frames" );
const input = {
fid : 21018 ,
token : [
{
chain : TokenBlockchain .Ethereum ,
tokenAddress : "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D" ,
} ,
] ,
};
const { data , error } = await checkTokenHoldByFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy [
{
"chain" : "ethereum" ,
"tokenAddress" : "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D" ,
"isHold" : true
}
]
Check If Farcaster User Follows The Creator Of The Frames
You can check if the Farcaster user follows the Frames' creator by using the checkIsFollowingFarcasterUser
function:
TypeScript JavaScript Result
Copy import {
checkIsFollowingFarcasterUser ,
CheckIsFollowingFarcasterUserInput ,
CheckIsFollowingFarcasterUserOutput ,
} from "@airstack/frames" ;
const input : CheckIsFollowingFarcasterUserInput = {
fid : 3 ,
isFollowing : [ 99 ] ,
};
const { data , error } : CheckIsFollowingFarcasterUserOutput =
await checkIsFollowingFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy import {
checkIsFollowingFarcasterUser ,
CheckIsFollowingFarcasterUserInput ,
CheckIsFollowingFarcasterUserOutput ,
} from "@airstack/frames" ;
const input : CheckIsFollowingFarcasterUserInput = {
fid : 3 , // The creator of frame
isFollowing : [ 99 ] , // The fid of user interacting with your frames
};
const { data , error } : CheckIsFollowingFarcasterUserOutput =
await checkIsFollowingFarcasterUser (input);
if (error) throw new Error (error);
console .log (data);
Copy [{ "fid" : 99 , "isFollowing" : true }]
Check If Farcaster User Transacted On Certain Blockchain Before Certain Date
Video Demo You can check if the Farcaster user transacted on certain blockchain, e.g. Ethereum, Base, Degen Chain, and other Airstack-supported chains by providing the Farcaster user's fid
from the Frame Signature Packet to the $farcasterUser
variable and the before date to check to the $beforeDate
variable using the Wallet
API:
Try Demo
Code
Query Variables Response
Copy query MyQuery ($farcasterUser: Identity ! , $beforeDate: Time ! ) {
TokenTransfers(
input: {
filter : {
from : { _eq : $farcasterUser }
blockTimestamp : { _lt : $beforeDate }
}
blockchain : ethereum
}
) {
TokenTransfer {
transactionHash
blockTimestamp
}
}
}
Copy {
"farcasterUser" : "fc_fid:3" ,
"beforeDate" : "2024-02-01T00:00:00Z"
}
Copy {
"data" : {
"TokenTransfers" : {
// If this array is non-empty, then you can allow user to interact w/ Frames
// Otherwise, do not allow them
"TokenTransfer" : [
{
"transactionHash" : "0xd14592edcacdcf81c06aa9588abcb38c1b553e066c175bbb9aa794a321608ad7" ,
"blockTimestamp" : "2023-08-08T06:35:35Z"
} ,
{
"transactionHash" : "0x2c40ac77d54a15cb9b766d1bdb036ca2fad11f8bd0f69c9c21d96a2fc4f3116f" ,
"blockTimestamp" : "2023-08-27T19:39:23Z"
} ,
{
"transactionHash" : "0xb92628bc8769f60b472f4989b81be9a22e4ce606fad5a39292a5c4ced1d8ee6d" ,
"blockTimestamp" : "2021-04-09T18:01:18Z"
} ,
]
}
}
}
Check If Farcaster User Has Casted In A Given Channel
You can check if Farcaster user has casted in a given channel by using the FarcasterChannelParticipants
API and providing:
the "cast" value to the $channelActions
variable,
the channel ID (e.g. /farcaster channel ID is "farcaster") to $channelId
variable, and
the FID to the $participant
variable
Try Demo
Code
Query Response
Copy query MyQuery {
FarcasterChannelParticipants(
input: {
filter : {
participant : { _eq : "fc_fid:602" }
channelId : { _eq : "airstack" }
channelActions : { _eq : cast }
}
blockchain : ALL
}
) {
FarcasterChannelParticipant {
lastActionTimestamp
}
}
}
Copy {
"data" : {
"FarcasterChannelParticipants" : {
"FarcasterChannelParticipant" : [
{
"lastActionTimestamp" : "2024-02-23T17:12:13Z"
}
]
}
}
}
Check If Farcaster User Has A Power Badge
You can check if Farcaster user has a power badge by using the Socials
API:
Try Demo
Code
Query Response
Copy query MyQuery {
Socials(
input: {
filter : { identity : { _eq : "fc_fid:602" }, dappName : { _eq : farcaster } }
blockchain : ethereum
}
) {
Social {
isFarcasterPowerUser
}
}
}
Copy {
"data" : {
"Socials" : {
"Social" : [
{
"isFarcasterPowerUser" : true
}
]
}
}
}
Developer Support
If you have any questions or need help building an allow list for your Farcaster Frames using the Airstack Frames SDK, please join our Airstack's Telegram group.
More Resources