Build Power Badges for your Client using Global & Personalized Ranking APIs by OpenRank

Create your own custom PowerBadge for your client

Custom Power Badge Strategies:

  1. Based on Top X Globally Ranked Users

  2. Based on a Cut Off Percentile

  3. Based on Top X Profiles from a Customized Graph Generated for a Given List of Input FIDs

Before delving into the code for each strategy, we need to introduce some utility functions at the outset. These functions will be utilized later to transform data, ensuring compatibility with the input parameter schema.

// Function to call global rankings
async function fetchGlobalRankings (offset, limit) {
    const globalRankingsBaseURL = 'https://graph.cast.k3l.io/scores/global/engagement/rankings'
    const globalRankingsParameters = `offset=${offset}&limit=${limit}`
    const globalRankingsURL = `${globalRankingsBaseURL}?${globalRankingsParameters}`
    const globalRankingsResponse = await fetch(globalRankingsURL, {
        method: 'GET',
        headers: {
            "Content-Type": "application/json"
        },
    });
    const globalRankedArrayResponse  = await globalRankingsResponse.json()
    const globalRankedArray = globalRankedArrayResponse.result;
    return globalRankedArray
}

// Function to call Personalized Rankings End Point
async function fetchPersonalizedRankings (fidsArray, limit = 100, lite = true) {
    const personalizedRankingsBaseURL = 'https://graph.cast.k3l.io/scores/personalized/engagement/fids'
    const personalizedRankingsParameters = `&limit=${limit}&lite=${lite}`
    const personalizedRankingsURL = `${personalizedRankingsBaseURL}?${personalizedRankingsParameters}`
    const personalizedRankingsResponse = await fetch(personalizedRankingsURL, {
        method: 'POST',
        headers: {
            "Content-Type": "application/json"
        },
        body: JSON.stringify(fidsArray)
    });
    const personalizedRankedArrayResponse  = await personalizedRankingsResponse.json()
    const personalizedRankedArray = personalizedRankedArrayResponse.result;
    return personalizedRankedArray
}

And finally some utility functions:

// Utilities
// Function to merge objects in array of objects by FID
function mergeObjectsByFID(array) {
    return array.reduce((acc, obj) => {
        const found = acc.find(item => item.fid === obj.fid);
        if (found) {
            // If an object with the same fid is found, merge the objects
            Object.assign(found, obj);
        } else {
            // If not found, add the object to the accumulator
            acc.push({ ...obj });
        }
        return acc;
    }, []);
}

Strategy 1: Top X Globally Ranked users

The fetchTopXUsers async function retrieves the top users from a global ranking system. It iterates through the rankings in batches of 1000, avoiding duplicates by tracking seen user identifiers. The loop breaks when the desired number of top users is reached or when there are no more records to fetch. The function returns an array containing the specified number of unique top users.

The fetchTopXUsers async function takes one parameter, numberOfTopUsers, specifying the desired number of top users to fetch. It returns an array containing the unique top users retrieved from the global ranking system, limited to the specified number.

With this strategy, you now have the capability to distribute customized power badges to the top 10,000, 5,000, 1,000, etc globally ranked users.

More information on how these global ranks are generated can be found here

async function fetchTopXUsers(numberOfTopUsers) {
    const limit = 1000;
    let offset = 0;
    let resultResponses = [];
    const seenFIDs = new Set();

    while (resultResponses.length < numberOfTopUsers) {
        const globalRankingsResponse = await fetchGlobalRankings(offset, limit);
        if (globalRankingsResponse.length === 0) {
            break; // No more data to fetch
        }
        for (const obj of globalRankingsResponse) {
            if (!seenFIDs.has(obj.fid)) {
                resultResponses.push(obj);
                seenFIDs.add(obj.fid);
            }
            if (resultResponses.length === numberOfTopUsers) {
                break;
            }
        }

        offset += limit; // Increment the offset for the next API call
    }
    return resultResponses.slice(0, numberOfTopUsers); // Ensure exactly `count` objects are returned
}
const topXGlobalRankedUsers = await fetchTopXUsers(1000);
// console.log('Top X Global Ranked Users: ', topXGlobalRankedUsers);

Strategy 2: Till a certain Cut Off Percentile

This function fetchFIDsUntilCutoffPercentile retrieves user data from the global rankings API until reaching a specified percentile cutoff. It accepts a cutoffPercentile parameter indicating the desired percentile threshold. The function aggregates fetched data until an object's percentile value falls below the cutoff, then filters the aggregated results to include only objects meeting or exceeding the cutoff percentile. Finally, it returns the filtered user data. Example usage demonstrates fetching users up to the 98th percentile and logging the result.

async function fetchFIDsUntilCutoffPercentile(cutoffPercentile) {
    const limit = 1000;
    let offset = 0;
    let resultResponses = [];
    let keepFetching = true;

    while (keepFetching) {
        // Fetch data from the API with offset and limit
        const response = await fetchGlobalRankings(offset, limit);

        // Aggregate the results
        resultResponses = resultResponses.concat(response);

        // Check if any object in the fetched data reaches or exceeds the cutoff percentile
        if (response.some(obj => obj.percentile < cutoffPercentile)) {
            keepFetching = false;
        }

        // Increment the offset for the next fetch call
        offset += limit;

        // If no more data is returned, stop fetching
        if (response.length < limit) {
            break;
        }
    }
    // Filter the aggregated results to include only those objects up to the cutoff percentile
    const filteredObjects = resultResponses.filter(obj => obj.percentile >= cutoffPercentile);
    const mergedFilteredObjects = mergeObjectsByFID(filteredObjects);
    return mergedFilteredObjects;
}

const topXPercentileUsers = await fetchObjectsUntilCutoffPercentile(98);
console.log('Top X Percentile Users: ', topXPercentileUsers);

Strategy 3: Top X Profiles from Custom FIDs graph

This function topXProfilesFromCustomFIDsGraph retrieves top user profiles based on a custom array FIDs using personalized rankings. It accepts two parameters: fidsArray, an array of user identifiers, and count, the number of top profiles to retrieve. The function limits the input FIDs array to 99 elements due to API restrictions, fetches personalized rankings based on the modified input array, and returns an array containing the top user profiles.

Example usage demonstrates fetching the top profiles based on FIDs [1, 2, 3] and logging the result.

Thee is a temporary restriction of this endpoint:

  1. You can input a maximum of 100 FIDs.

  2. Currently, the output is capped at 5000.

Both of these things should be fixed and opened up in the coming months

async function topXProfilesFromCustomFIDsGraph(fidsArray, count) {
    const inputFIDsArray = fidsArray.slice(0, 99);
    const response = await fetchPersonalizedRankings(inputFIDsArray, count);
    return response;
}
const topXProfilesFromFIDsUsers = await topXProfilesFromFIDs([1,2,3], 5000);
console.log('Top X Profiles From FIDs: ', topXProfilesFromFIDsUsers);

Future:

The current global rankings are determined by seed peers and weights selected by us, along with certain Dune queries.

However, in the upcoming months, we aim to extend this capability to developers, empowering them to customize both seed peers and weights. This enhancement will enable developers to create their own power badge ranking system, allowing for the customization of various parameters such as seed peers and weights. By tailoring these parameters to their preferences, developers can refine the ranking criteria to better suit their specific needs and objectives.

Last updated

Logo

Copyright 2024