Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add featured pools #496

Merged
merged 14 commits into from
Dec 22, 2023
Merged

add featured pools #496

merged 14 commits into from
Dec 22, 2023

Conversation

mendesfabio
Copy link
Contributor

@mendesfabio mendesfabio commented Oct 26, 2023

hey, folks! this is my first PR to the API 🎉 I talked to @danielmkm and he suggested me to work on this, some context:

Gareth made this repository to house metadata for pools. Would be great is if the API fetched this JSON and then merged it with the actual pool data, and returned it in the same format as is returned by the poolGetPools query GqlPoolMinimal. Lastly, expose a query named poolGetFeaturedPools and return an array of featured pools.

He suggested the following model for a featured pool:

{
    "id": ID!,
    "primary": Boolean!,
    "imageUrl": String!,
    "pool": GqlPoolMinimal!
}

Happy to hear any feedback!

@mendesfabio mendesfabio requested a review from danielmkm October 26, 2023 13:28
@gmbronco
Copy link
Contributor

gmbronco commented Oct 30, 2023

Hey! Thanks for the pull request; nice one! I would suggest caching the GitHub data in the database so that we don't depend on fetching from an external URL.

Copy link
Contributor

@franzns franzns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, the code works like this but it should be integrated in the content service that we already have. Check how we expose featured pools here:
https://github.com/beethovenxfi/beethovenx-backend/blob/v3-main/modules/pool/lib/pool-gql-loader.service.ts#L93

You should be able to extend the github content service for Balancer: https://github.com/beethovenxfi/beethovenx-backend/blob/v3-main/modules/content/github-content.service.ts#L161

You can take a look at how we did it for the featured pools for beets: https://github.com/beethovenxfi/beethovenx-backend/blob/v3-main/modules/content/github-content.service.ts#L161

You can also try and persist the data into the database as jarek suggested, but can also leave that for another day.

Let me know if you have any questions.

const poolsMetadata = await poolMetadataService.getPoolsMetadata();
const poolIds = poolsMetadata.map((pool) => pool.id);

const pools = await this.getPools({ where: { idIn: poolIds } });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fetches the pools from the subgraph but we want to avoid that. Pools are synced to the database. You can query them like this:

    const pools = await prisma.prismaPool.findMany({
        where: { id: { in: poolIds }, chain: networkContext.chain },
    });

This returns the prismaPool object, not sure if you need additional data. Also, you need to pass it the chain you request the pools for via network context. Or better, your gql resolver should take a chain array as argument and you query the pools for those chains.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -114,7 +114,7 @@ export class PoolService {
return this.poolSwapService.getJoinExits(args);
}

public async getFeaturedPoolGroups(): Promise<GqlPoolFeaturedPoolGroup[]> {
public async getFeaturedPoolGroups(chains: Chain[]): Promise<GqlPoolFeaturedPoolGroup[]> {
const cached: GqlPoolFeaturedPoolGroup[] = await this.cache.get(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@franzns I'm in doubt about how to re-write this and poolGqlLoaderService.getFeaturedPoolGroups() functions given chains. Should we try to get it from cache for every network and for the ones it doesn't find we get it from poolGqlLoaderService?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine to simply get rid of this cache since we are caching on Stellate. This was from a time before that.

@@ -159,7 +166,15 @@ export class GithubContentService implements ContentService {
}
async syncPoolContentData(): Promise<void> {}
async getFeaturedPoolGroups(): Promise<HomeScreenFeaturedPoolGroup[]> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would need to be changed to take the chain (or chains) as an argument. Also for the sanity content service.

poolGetFeaturedPoolGroups: async (parent, args, context) => {
return poolService.getFeaturedPoolGroups();
poolGetFeaturedPoolGroups: async (parent, { chains }, context) => {
return poolService.getFeaturedPoolGroups(chains);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we would want to do the same that we do e.g. poolGetAllPoolsSnapshots below. We have a migration period where we still support both, the header chainId as well as the chains param

@mendesfabio
Copy link
Contributor Author

hey I could add the filter by chains with support for param via headers. The query below seems to be returning what we needed - as specified in PR description:

{
    "id": ID!,
    "primary": Boolean!,
    "imageUrl": String!,
    "pool": GqlPoolMinimal!
}

I didn't know exactly how to test the Sanity stuff and ensure the same query works there given chains param instead of networkContext - if you want to go ahead and fix that I appreciate.

image

async getFeaturedPoolGroups(): Promise<HomeScreenFeaturedPoolGroup[]> {
return [];
async getFeaturedPoolGroups(chains: Chain[]): Promise<HomeScreenFeaturedPoolGroup[]> {
const { data } = await axios.get<FeaturedPoolMetadata[]>(POOLS_METADATA_URL);
Copy link
Contributor

@gmbronco gmbronco Dec 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have native fetch now, how about we move away from axios?

Comment on lines +161 to 170
public async getFeaturedPoolGroups(chains: Chain[]): Promise<GqlPoolFeaturedPoolGroup[]> {
const featuredPoolGroups = [];
if (chains.some((chain) => BalancerChainIds.includes(chainToIdMap[chain]))) {
const githubContentService = new GithubContentService();
featuredPoolGroups.push(...(await githubContentService.getFeaturedPoolGroups(chains)));
} else if (chains.some((chain) => BeethovenChainIds.includes(chainToIdMap[chain]))) {
const sanityContentService = new SanityContentService('FANTOM');
featuredPoolGroups.push(...(await sanityContentService.getFeaturedPoolGroups(chains)));
}
const poolIds = featuredPoolGroups
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we remove if / else and just query both? they will return empty array if there is no pools for a chain, right?

@@ -27,16 +36,14 @@ export class GithubContentService implements ContentService {
async syncTokenContentData(): Promise<void> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make sense to sync all the tokens at once without splitting per chain? i'm not sure if we aren't overcomplicating it here, since the whole list is fetched anyways.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bit lower there is upsert call, it can take chain as token.chainId instead of networkContext

@@ -77,12 +83,12 @@ export class SanityContentService implements ContentService {

await prisma.prismaToken.upsert({
where: {
address_chain: { address: tokenAddress, chain: networkContext.chain },
address_chain: { address: tokenAddress, chain: this.chain },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't the chain returned in the response? is so we could use it here instead of setting it up externally

@franzns franzns self-requested a review December 22, 2023 16:09
@franzns franzns merged commit 8fadbac into v3-canary Dec 22, 2023
1 check passed
@franzns franzns deleted the feat/featured-pools branch December 22, 2023 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants