Learn how to get recommended followers for Farcaster users based on on-chain insights from token transfers, POAPs, NFTS, and token holder combinations.
Airstack provides easy-to-use APIs for enriching Farcaster applications and for integrating onchain and offchain data with Farcaster.
Table Of Contents
In this guide you will learn how to use Airstack to:
Airstack provides an AI solution for you to build GraphQL queries to fulfill your use case easily. You can find the AI prompt of each query in the demo's caption or title for yourself to try.
Get Recommendation Follows For Farcaster User(s) Based on Token Transfers
To get recommendations by token transfers, simply fetch all token transfers that is received and sent from the Farcaster user(s):
The follow recommendation will provide a list of Farcaster users with the Farcaster user name from the profileName field and Farcaster user ID from the userId field.
Get Recommendation Follows For Farcaster User(s) Based on NFTs
To get recommendations by NFTs, first fetch all NFTs that is owned by the Farcaster user(s) on Ethereum, Polygon, and Base:
{"data": {"ethereum": {"TokenNft": [ {"tokenBalances": [ {"owner": {"identity":"0x0734d56da60852a03e2aafae8a36ffd8c12b32f1","socials": [ {"profileName":"0age","userId":"4262" } ] } } ] }, {"tokenBalances": [ {"owner": {"identity":"0xb16266ba63506cb4de9b2328bada30064e196a3b","socials":null// Have no Farcaster, can be filtered out } } ] } ] },"polygon": {"TokenNft": [ {"tokenBalances": [ {"owner": {"identity":"0x87fdd2217f4d8531b5d091d1b290eb64d26f415b","socials":null } } ] } ] },"base": {"TokenNft":null } }}
The follow recommendation will provide a list of Farcaster users with the Farcaster user name from the profileName field and Farcaster user ID from the userId field.
Get Recommendation Follows For Farcaster User(s) Based on NFTs and POAPs Commonly Held
Fetching
You can fetch follow recommendations based on the common holder of a specific NFT and a specific POAP by providing the token contract address and the POAP event ID:
defformat_function(data): result = []if data isnotNoneand'TokenBalances'in data and'TokenBalance'in data['TokenBalances']:for item in data['TokenBalances']['TokenBalance']:if'owner'in item and'poaps'in item['owner']and item['owner']['poaps'] isnotNone:for poap in item['owner']['poaps']:if'owner'in poap and'socials'in poap['owner']: result.append(poap['owner']['socials']) result = [item for sublist in result for item in sublist]return result
The final result will the the list of all common holders in an array:
{"data": {"SocialFollowers": {"Follower": [ {"followerAddress": {"addresses": ["0xb83d63d179838b439f3fa9f35d87f29fcec7b343","0x7bdee41767e9aac283b86dd73133dd34d735cfac" ],"socials": [ {"profileName":"vipulgoyal",// One of Farcaster follower that can be recommended"userId":"11282","userAssociatedAddresses": ["0xb83d63d179838b439f3fa9f35d87f29fcec7b343","0x7bdee41767e9aac283b86dd73133dd34d735cfac" ] } ] },"followingAddress": {"addresses": ["0xa14b4c95b5247199d74c5578531b4887ca5e4909","0xd7029bdea1c17493893aafe29aad69ef892b8ff2","0x74232bf61e994655592747e20bdf6fa9b9476f79","0xb877f7bb52d28f06e60f557c00a56225124b357f" ],"domains": [ {"name":"dwr.eth" }, {"name":"noun124.eth" }, {"name":"dwr.mirror.xyz" }, {"name":"danromero.eth" } ],"socials": [ {"profileName":"dwr.eth","userId":"3","userAssociatedAddresses": ["0xa14b4c95b5247199d74c5578531b4887ca5e4909","0xd7029bdea1c17493893aafe29aad69ef892b8ff2","0x74232bf61e994655592747e20bdf6fa9b9476f79","0xb877f7bb52d28f06e60f557c00a56225124b357f" ] } ] } },// more Farcaster followers ] } }}
With the response, you can get all followerAddress.socials and compile them into an array of Farcaster accounts that you can recommend for the given user(s) to follow.
Get Recommendation Follows For Farcaster User(s) Based on Lens Following
Fetching
You can fetch follow recommendations for Farcaster user(s) by simply showing them all their Lens following and show their corresponding Farcaster accounts, if any:
{"data": {"SocialFollowings": {"Following": [ {"followingAddress": {"addresses": ["0x66da63b03feca7dd44a5bb023bb3645d3252fa32" ],"socials": [ {"profileName":"keeks",// One of Lens following that can be recommended"userId":"3283","userAssociatedAddresses": ["0xadc0b2321bb9779bf2a565c51456fa300517bed5","0x66da63b03feca7dd44a5bb023bb3645d3252fa32" ] } ] },"followerAddress": {"addresses": ["0xd7029bdea1c17493893aafe29aad69ef892b8ff2" ],"domains": [ {"name":"dwr.eth" }, {"name":"dwr.mirror.xyz" }, {"name":"danromero.eth" } ],"socials": [ {"profileName":"dwr.eth","userId":"3","userAssociatedAddresses": ["0xff3174d9f52f8c24f9c884600ac80c2b2dda4556","0xd7029bdea1c17493893aafe29aad69ef892b8ff2","0xa14b4c95b5247199d74c5578531b4887ca5e4909","0xb877f7bb52d28f06e60f557c00a56225124b357f","0x74232bf61e994655592747e20bdf6fa9b9476f79","0x8fc5d6afe572fefc4ec153587b63ce543f6fa2ea" ] } ] } }, {"followingAddress": {"addresses": ["0xcd3b95032441457aa6382fd1312753353368be41" ],"socials":null// This Lens following have no Farcaster, should be filtered out },"followerAddress": {"addresses": ["0xd7029bdea1c17493893aafe29aad69ef892b8ff2" ],"domains": [ {"name":"dwr.eth" }, {"name":"dwr.mirror.xyz" }, {"name":"danromero.eth" } ],"socials": [ {"profileName":"dwr.eth","userId":"3","userAssociatedAddresses": ["0xff3174d9f52f8c24f9c884600ac80c2b2dda4556","0xd7029bdea1c17493893aafe29aad69ef892b8ff2","0xa14b4c95b5247199d74c5578531b4887ca5e4909","0xb877f7bb52d28f06e60f557c00a56225124b357f","0x74232bf61e994655592747e20bdf6fa9b9476f79","0x8fc5d6afe572fefc4ec153587b63ce543f6fa2ea" ] } ] } },// more Lens following ] } }}
All the Farcaster accounts that can be used for recommendation will be returned in followingAddress.socials.
Formatting
To get the list of all following in a flat array and filter out all those that don't have any Farcaster account, use the following format function:
/** * @description Formats the given data. * @example * // For React * const { data } = useQuery(query); * formatFunction(data); * * // For Node * const { data } = await fetchQuery(query); * formatFunction(data); * * @param{Object} data â data result from the Airstack API call * @returns â an array of Farcaster and their user details for recommendataion */constformatFunction= (data) =>data?.SocialFollowings?.Following?.map(({ followingAddress }) =>followingAddress?.xmtp?.length?followingAddress?.socials :null ).filter(Boolean).flat(1).filter((address, index, array) =>array.indexOf(address) === index) ?? [];
"""Formats the given data.Examples: query_response = await execute_query_client.execute_query() formatted_data = format_function(query_response.data)Args: data (dict): Data result from the Airstack API call.Returns: list: An array of Farcaster and their user details for recommendation."""defformat_function(data): result = []if data and'SocialFollowings'in data and'Following'in data['SocialFollowings']:for following in data['SocialFollowings']['Following']: if 'followingAddress' in following and following['followingAddress']['xmtp'] is not None and len(following['followingAddress']['xmtp']) > 0 and following['followingAddress']['socials'] is not None:
result.extend(following['followingAddress']['socials'])return result
The formatted data will have data structure that look as follows:
[ {"profileName":"keeks","userId":"3283","userAssociatedAddresses": ["0xadc0b2321bb9779bf2a565c51456fa300517bed5","0x66da63b03feca7dd44a5bb023bb3645d3252fa32" ] }// more recommended users]
Developer Support
If you have any questions or need help regarding building a recommendation engine, please join our Airstack's Telegram group.