Skip to content

Commit

Permalink
Use new args type, add filtering, remove BPT from tokens list
Browse files Browse the repository at this point in the history
  • Loading branch information
timjrobinson committed Aug 15, 2023
1 parent 376db7a commit f30cccb
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 77 deletions.
98 changes: 29 additions & 69 deletions src/composables/queries/usePoolsQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,20 @@ import { Pool } from '@/services/pool/types';
import useNetwork from '../useNetwork';
import { useTokens } from '@/providers/tokens.provider';
import { configService } from '@/services/config/config.service';
import { GraphQLArgs, PoolsRepositoryFetchOptions } from '@balancer-labs/sdk';
import { getPoolsFallbackRepository } from '@/dependencies/PoolsFallbackRepository';
import { PoolDecorator } from '@/services/pool/decorators/pool.decorator';
import { PoolsRepositoryFetchOptions } from '@balancer-labs/sdk';
import { flatten } from 'lodash';
import { tokenTreeLeafs } from '../usePoolHelpers';
import { balancerSubgraphService } from '@/services/balancer/subgraph/balancer-subgraph.service';
import { balancerAPIService } from '@/services/balancer/api/balancer-api.service';
import { poolsStoreService } from '@/services/pool/pools-store.service';
import { isBalancerApiDefined } from '@/lib/utils/balancer/api';
import { bnum } from '@/lib/utils';
import { PoolFilterOptions } from '@/types/pools';
import {
GqlPoolOrderBy,
GqlPoolOrderDirection,
} from '@/services/api/graphql/generated/api-types';
import { ApiArgs } from '@/services/balancer/api/entities/pools';
import { mapNetworkToApiChain, mapPoolTypeToApiType } from '@/lib/utils/api';

type PoolsQueryResponse = {
pools: Pool[];
Expand All @@ -28,7 +31,7 @@ export default function usePoolsQuery(filterOptions: PoolFilterOptions) {
/**
* COMPOSABLES
*/
const { injectTokens, tokens: tokenMeta } = useTokens();
const { injectTokens } = useTokens();
const { networkId } = useNetwork();
let poolsRepository = initializePoolsRepository();

Expand All @@ -37,14 +40,6 @@ export default function usePoolsQuery(filterOptions: PoolFilterOptions) {
*/

function initializePoolsRepository() {
const FallbackRepository = getPoolsFallbackRepository();
const fallbackRepository = new FallbackRepository(buildRepositories(), {
timeout: 30 * 1000,
});
return fallbackRepository;
}

function initializeDecoratedAPIRepository() {
return {
fetch: async (options: PoolsRepositoryFetchOptions): Promise<Pool[]> => {
const pools = await balancerAPIService.pools.get(getQueryArgs(options));
Expand All @@ -63,80 +58,47 @@ export default function usePoolsQuery(filterOptions: PoolFilterOptions) {
};
}

function initializeDecoratedSubgraphRepository() {
return {
fetch: async (options: PoolsRepositoryFetchOptions): Promise<Pool[]> => {
const pools = await balancerSubgraphService.pools.get(
getQueryArgs(options)
);

const poolDecorator = new PoolDecorator(pools);
let decoratedPools = await poolDecorator.decorate(tokenMeta.value);

const tokens = flatten(
pools.map(pool => [
...pool.tokensList,
...tokenTreeLeafs(pool.tokens),
pool.address,
])
);
await injectTokens(tokens);

decoratedPools = await poolDecorator.reCalculateTotalLiquidities();

return decoratedPools;
},
};
}

function buildRepositories() {
const repositories: any[] = [];
if (isBalancerApiDefined) {
const balancerApiRepository = initializeDecoratedAPIRepository();
repositories.push(balancerApiRepository);
function convertSortFieldToOrderBy(
sortField: string | undefined
): GqlPoolOrderBy {
switch (sortField) {
case 'apr':
return GqlPoolOrderBy.Apr;
case 'volume':
return GqlPoolOrderBy.Volume24h;
case 'totalLiquidity':
default:
return GqlPoolOrderBy.TotalLiquidity;
}
const subgraphRepository = initializeDecoratedSubgraphRepository();
repositories.push(subgraphRepository);

return repositories;
}

function getQueryArgs(options: PoolsRepositoryFetchOptions): GraphQLArgs {
function getQueryArgs(options: PoolsRepositoryFetchOptions): ApiArgs {
const { tokens, poolIds, poolTypes, sortField } = filterOptions.value;
const hasPoolIdFilters = !!poolIds?.length && poolIds?.length > 0;
const hasPoolTypeFilters = !!poolTypes?.length;

const tokensListFilterOperation = filterOptions.value.useExactTokens
? 'eq'
: 'contains';

const tokenListFormatted =
tokens?.map(address => address.toLowerCase()) || [];

const orderBy = isBalancerApiDefined
? sortField || 'totalLiquidity'
: 'totalLiquidity';
const orderBy = convertSortFieldToOrderBy(sortField);

const queryArgs: GraphQLArgs = {
chainId: configService.network.chainId,
const queryArgs: ApiArgs = {
orderBy,
orderDirection: 'desc',
orderDirection: GqlPoolOrderDirection.Desc,
where: {
tokensList: { [tokensListFilterOperation]: tokenListFormatted },
poolType: { in: POOLS.IncludedPoolTypes },
totalShares: { gt: 0.00001 },
id: { not_in: POOLS.BlockList },
chainIn: [mapNetworkToApiChain(configService.network.chainId)],
tokensIn: tokenListFormatted,
poolTypeIn: POOLS.IncludedPoolTypes.map(mapPoolTypeToApiType),
idNotIn: POOLS.BlockList,
},
};

if (queryArgs.where && hasPoolTypeFilters && !!poolTypes?.length) {
queryArgs.where.poolType = {
in: poolTypes,
};
queryArgs.where.poolTypeIn = poolTypes.map(mapPoolTypeToApiType);
}

if (queryArgs.where && hasPoolIdFilters) {
queryArgs.where.id = { in: filterOptions.value.poolIds };
queryArgs.where.idIn = filterOptions.value.poolIds;
}
if (options.first) {
queryArgs.first = filterOptions.value.first || options.first;
Expand All @@ -145,8 +107,6 @@ export default function usePoolsQuery(filterOptions: PoolFilterOptions) {
queryArgs.skip = options.skip;
}

// console.log('queryArgs', queryArgs);

return queryArgs;
}

Expand Down
64 changes: 64 additions & 0 deletions src/lib/utils/api.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
GqlChain,
GqlPoolFilterType,
GqlPoolMinimalType,
} from '@/services/api/graphql/generated/api-types';
import { Network } from '@/lib/config';
Expand Down Expand Up @@ -37,6 +38,32 @@ export function mapApiChain(
}
}

export function mapNetworkToApiChain(network: Network): GqlChain {
switch (network) {
case Network.ARBITRUM:
return GqlChain.Arbitrum;
case Network.AVALANCHE:
return GqlChain.Avalanche;
case Network.BASE:
return GqlChain.Base;
case Network.GNOSIS:
return GqlChain.Gnosis;
case Network.FANTOM:
return GqlChain.Fantom;
case Network.OPTIMISM:
return GqlChain.Optimism;
case Network.POLYGON:
return GqlChain.Polygon;
case Network.MAINNET:
return GqlChain.Mainnet;
case Network.ZKEVM:
return GqlChain.Zkevm;

default:
throw new Error(`Unexpected Network: ${network}`);
}
}

export function mapApiPoolType(
apiPoolType: GqlPoolMinimalType
): PoolType | null {
Expand Down Expand Up @@ -65,3 +92,40 @@ export function mapApiPoolType(
return null;
}
}

export function mapPoolTypeToApiType(
poolType: PoolType | string
): GqlPoolFilterType {
switch (poolType) {
case PoolType.Element:
return GqlPoolFilterType.Element;
case PoolType.Gyro2:
return GqlPoolFilterType.Gyro3;
case PoolType.Gyro3:
return GqlPoolFilterType.Gyro3;
case PoolType.GyroE:
return GqlPoolFilterType.Gyroe;
case PoolType.Investment:
return GqlPoolFilterType.Investment;
case PoolType.EulerLinear:
return GqlPoolFilterType.Linear;
case PoolType.Linear:
return GqlPoolFilterType.Linear;
case PoolType.LiquidityBootstrapping:
return GqlPoolFilterType.LiquidityBootstrapping;
case PoolType.MetaStable:
return GqlPoolFilterType.MetaStable;
case PoolType.StablePhantom:
return GqlPoolFilterType.PhantomStable;
case PoolType.Stable:
return GqlPoolFilterType.Stable;
case PoolType.ComposableStable:
return GqlPoolFilterType.Stable;
case PoolType.FX:
return GqlPoolFilterType.Stable;
case PoolType.Weighted:
return GqlPoolFilterType.Weighted;
default:
throw new Error(`Unexpected Pool Type ${poolType}`);
}
}
6 changes: 6 additions & 0 deletions src/services/api/graphql/generated/api-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1358,8 +1358,10 @@ export type QueryUserGetSwapsArgs = {

export type GetPoolsQueryVariables = Exact<{
first?: InputMaybe<Scalars['Int']>;
skip?: InputMaybe<Scalars['Int']>;
orderBy?: InputMaybe<GqlPoolOrderBy>;
orderDirection?: InputMaybe<GqlPoolOrderDirection>;
where?: InputMaybe<GqlPoolFilter>;
}>;

export type GetPoolsQuery = {
Expand Down Expand Up @@ -1495,13 +1497,17 @@ export type VeBalGetVotingListQuery = {
export const GetPoolsDocument = gql`
query GetPools(
$first: Int
$skip: Int
$orderBy: GqlPoolOrderBy
$orderDirection: GqlPoolOrderDirection
$where: GqlPoolFilter
) {
pools: poolGetPools(
first: $first
skip: $skip
orderBy: $orderBy
orderDirection: $orderDirection
where: $where
) {
id
chain
Expand Down
4 changes: 3 additions & 1 deletion src/services/api/graphql/pool.graphql
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
query GetPools(
$first: Int
$skip: Int
$orderBy: GqlPoolOrderBy
$orderDirection: GqlPoolOrderDirection
$where: GqlPoolFilter
) {
pools: poolGetPools (first: $first, orderBy: $orderBy, orderDirection: $orderDirection) {
pools: poolGetPools (first: $first, skip: $skip, orderBy: $orderBy, orderDirection: $orderDirection, where: $where) {
id
chain
address
Expand Down
30 changes: 23 additions & 7 deletions src/services/balancer/api/entities/pools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { getApi } from '@/dependencies/balancer-api';
import { Pool } from '@/services/pool/types';
import {
GetPoolsQuery,
GqlPoolFilter,
GqlPoolOrderBy,
GqlPoolOrderDirection,
} from '@/services/api/graphql/generated/api-types';
import { PoolsQueryBuilder } from '@/types/subgraph';
import {
AprBreakdown,
GraphQLArgs,
GraphQLQuery,
PoolToken,
PoolType,
Expand All @@ -24,6 +24,14 @@ import { mapApiChain, mapApiPoolType } from '@/lib/utils/api';
export type ApiPools = GetPoolsQuery['pools'];
export type ApiPool = ApiPools[number];

export interface ApiArgs {
first?: number;
skip?: number;
orderBy?: GqlPoolOrderBy;
orderDirection?: GqlPoolOrderDirection;
where?: GqlPoolFilter;
}

export default class Pools {
service: Service;
queryBuilder: PoolsQueryBuilder;
Expand All @@ -38,13 +46,15 @@ export default class Pools {
this.queryBuilder = _queryBuilder;
}

public async get(args: GraphQLArgs = {}): Promise<Pool[]> {
public async get(args: ApiArgs = {}): Promise<Pool[]> {
const api = getApi();
console.log('Getting pools from API');
const response = await api.GetPools({
first: args.first || 10,
orderBy: GqlPoolOrderBy.TotalLiquidity,
orderDirection: GqlPoolOrderDirection.Desc,
skip: args.skip || 0,
orderBy: args.orderBy || GqlPoolOrderBy.TotalLiquidity,
orderDirection: args.orderDirection || GqlPoolOrderDirection.Desc,
where: args.where,
});
const pools: ApiPools = response.pools;
console.log('Got pools from API', pools);
Expand Down Expand Up @@ -123,9 +133,15 @@ export default class Pools {
owner: apiPool.owner ?? undefined,
factory: apiPool.factory ?? undefined,
symbol: apiPool.symbol ?? undefined,
tokens: (apiPool.allTokens || []).map(this.mapToken),
tokensList: (apiPool.allTokens || []).map(t => t.address),
tokenAddresses: (apiPool.allTokens || []).map(t => t.address),
tokens: (apiPool.allTokens || [])
.map(this.mapToken)
.filter(token => token.address !== apiPool.address),
tokensList: (apiPool.allTokens || [])
.map(t => t.address)
.filter(address => address !== apiPool.address),
tokenAddresses: (apiPool.allTokens || [])
.map(t => t.address)
.filter(address => address !== apiPool.address),
totalLiquidity: apiPool.dynamicData.totalLiquidity,
totalShares: apiPool.dynamicData.totalShares,
totalSwapFee: apiPool.dynamicData.lifetimeSwapFees,
Expand Down

0 comments on commit f30cccb

Please sign in to comment.