Get All Creator Coins Owned By Certain User
In this tutorial, you will learn how to get all the Creator Coins owned by a certain user, whether it is hold in their wallet/vesting contract or locked in the staking contract, by calling the Moxie Protocol Subgraph API.
You can either use the subgraph APIs or Airstack API to fetch this data.
Method #1: Airstack API
Using the Airstack MoxieUserPortolio
API, you can simply provide the user FID to get all the Creator Coins owned by the user, both staked and non-staked in the Moxie Power Staking contract.
To learn more, click here.
Method #2: Subgraphs
Pre-requisites
- Install dependencies
graphql
andgraphql-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
- For profile resolution from FID to addresses, use a third-service API provider, such as Airstack. If you are using Airstack, you can get the Airstack API key and install the Airstack Node SDK:
- npm
- yarn
- pnpm
- bun
npm install @airstack/node
yarn add @airstack/node
pnpm add @airstack/node
bun install graphql @airstack/node
For access to the Airstack API key, you'll need to hold at least 1 /airstack Channel Creator Coin in either your Farcaster custodial wallet or one of your Farcaster verified wallets AND make sure that you have connected one of those wallet or your Farcaster account to your Airstack account.
If you don't have it yet, you can buy it here.
Step 1: Resolve User's FID to Addresses
You can use the call a third-party API provider, such as Airstack, to get all user's Farcaster verified wallets and the Moxie Vesting Subgraph API to get all user's vesting contract wallet addresses with the following utility function:
- TypeScript
- JavaScript
import { gql, GraphQLClient } from "graphql-request";
import { config } from "dotenv";
config();
const airstackGraphQLClient = new GraphQLClient("https://api.airstack.xyz/gql");
const vestingSubgraphQLClient = new GraphQLClient(
"https://api.studio.thegraph.com/query/23537/moxie_vesting_mainnet/version/latest"
);
const airstackQuery = gql`
query MyQuery($fid: String) {
Socials(
input: { filter: { userId: { _eq: $fid } }, blockchain: ethereum }
) {
Social {
connectedAddresses {
address
blockchain
}
}
}
}
`;
const vestingSubgraphQuery = gql`
query MyQuery($beneficiaries: [Bytes!]) {
tokenLockWallets(where: { beneficiary_in: $beneficiaries }) {
address: id
}
}
`;
const resolveFidToAddresses = async (fid: number) => {
try {
const farcasterWalletData = await airstackGraphQLClient.request(
airstackQuery,
{
fid: fid?.toString(),
},
{
// Provide Airstack API key here
Authorization: process.env.AIRSTACK_API_KEY,
}
);
const userAddresses =
// Get all Farcaster verified wallet addresses
farcasterWalletData?.Socials?.Social?.[0]?.connectedAddresses
// Filter out non-Ethereum addresses
?.filter(({ blockchain }) => blockchain === "ethereum")
?.map(({ address }) => address) ?? [];
const vestingAddressesData = await vestingSubgraphQLClient.request(
vestingSubgraphQuery,
{
beneficiaries: userAddresses,
}
);
return [
...userAddresses,
...vestingAddressesData.tokenLockWallets.map((t) => t?.address),
];
} catch (e) {
throw new Error(e);
}
};
export default resolveFidToAddresses;
const { gql, GraphQLClient } = require("graphql-request");
const { config } = require("dotenv");
config();
const airstackGraphQLClient = new GraphQLClient("https://api.airstack.xyz/gql");
const vestingSubgraphQLClient = new GraphQLClient(
"https://api.studio.thegraph.com/query/23537/moxie_vesting_mainnet/version/latest"
);
const airstackQuery = gql`
query MyQuery($fid: String) {
Socials(
input: { filter: { userId: { _eq: $fid } }, blockchain: ethereum }
) {
Social {
connectedAddresses {
address
blockchain
}
}
}
}
`;
const vestingSubgraphQuery = gql`
query MyQuery($beneficiaries: [Bytes!]) {
tokenLockWallets(where: { beneficiary_in: $beneficiaries }) {
address: id
}
}
`;
const resolveFidToAddresses = async (fid) => {
try {
const farcasterWalletData = await airstackGraphQLClient.request(
airstackQuery,
{
fid: fid?.toString(),
},
{
// Provide Airstack API key here
Authorization: process.env.AIRSTACK_API_KEY,
}
);
const userAddresses =
// Get all Farcaster verified wallet addresses
farcasterWalletData?.Socials?.Social?.[0]?.connectedAddresses
// Filter out non-Ethereum addresses
?.filter(({ blockchain }) => blockchain === "ethereum")
?.map(({ address }) => address) ?? [];
const vestingAddressesData = await vestingSubgraphQLClient.request(
vestingSubgraphQuery,
{
beneficiaries: userAddresses,
}
);
return [
...userAddresses,
...vestingAddressesData.tokenLockWallets.map((t) => t?.address),
];
} catch (e) {
throw new Error(e);
}
};
module.exports = resolveFidToAddresses;
To resolve, simply call the function and provide the user's FID as input. In return, you will get an array of the user's Farcaster verified wallets and vesting contract wallet addresses that can be used in Step 2.
Step 2: Add The API Query To Your Code
To get all the Creator Coins owned by a certain user, you can use the following query on the Moxie Protocol Subgraph API and provide the array of addresses resolved in Step 1 as input to the $userAddresses
variable:
- Query
- Variable
- Response
query MyQuery($userAddresses: [ID!]) {
users(where: { id_in: $userAddresses }) {
portfolio {
stakedBalance
unstakedBalance
buyVolume
sellVolume
subjectToken {
name
symbol
}
}
}
}
{
"userAddresses": ["0x00d620def6ccb76c92dbfc87bc2bebab7637ec53"]
}
{
"data": {
"users": [
{
"portfolio": [
{
"stakedBalance": "442691639238050376",
"unstakedBalance": "0",
"buyVolume": "0",
"sellVolume": "0",
"subjectToken": {
"name": "sarvesh371",
"symbol": "fid:11536"
}
}
]
}
]
}
}
With this GraphQL query, you can add it to your source code and call the API with the graphql-request
library:
- TypeScript
- JavaScript
import { gql, GraphQLClient } from "graphql-request";
import resolveFidToAddresses from "./utils/resolve";
// Add you FID here
const fid = 3;
const graphQLClient = new GraphQLClient(
"https://api.studio.thegraph.com/query/23537/moxie_protocol_stats_mainnet/version/latest"
);
const query = gql`
query MyQuery($userAddresses: [ID!]) {
users(where: { id_in: $userAddresses }) {
portfolio {
stakedBalance
unstakedBalance
buyVolume
sellVolume
subjectToken {
name
symbol
}
}
}
}
`;
const variable = {
// You can remove await if you are using `moxie_resolve.json`
userAddresses: await resolveFidToAddresses(fid),
};
try {
const data = await graphQLClient.request(query, variable);
console.log(data);
} catch (e) {
throw new Error(e);
}
const { gql, GraphQLClient } = require("graphql-request");
const resolveFidToAddresses = require("./utils/resolve");
// Add you FID here
const fid = 3;
const graphQLClient = new GraphQLClient(
"https://api.studio.thegraph.com/query/23537/moxie_protocol_stats_mainnet/version/latest"
);
const query = gql`
query MyQuery($userAddresses: [ID!]) {
users(where: { id_in: $userAddresses }) {
portfolio {
stakedBalance
unstakedBalance
buyVolume
sellVolume
subjectToken {
name
symbol
}
}
}
}
`;
const variable = {
// You can remove await if you are using `moxie_resolve.json`
userAddresses: await resolveFidToAddresses(fid),
};
try {
const data = await graphQLClient.request(query, variable);
console.log(data);
} catch (e) {
throw new Error(e);
}
Step 3: 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:
{
"data": {
"users": [
{
"portfolio": [
{
"stakedBalance": "442691639238050376",
"unstakedBalance": "0",
"buyVolume": "0",
"sellVolume": "0",
"subjectToken": {
"name": "sarvesh371",
"symbol": "fid:11536"
}
}
]
}
]
}
}
Congrats! 🥳🎉 You've just fetched all Creator Coins owned by a certain user!
Developer Support
If you have any questions or need help with other use cases, feel free to join the Moxie Official Warpcast channel and ask your questions there.
Our team is always ready to help you with any questions you may have.