From c2bf4cc63c63463fa46b0c586c377afbe46ce5c3 Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Fri, 5 Jul 2024 10:32:07 +0100 Subject: [PATCH 1/4] feat: Add a refresh method on pools that should efficiently refresh a pools SG data. --- balancer-js/src/modules/data/pool/subgraph.ts | 38 ++++++++++++++++++- balancer-js/src/modules/data/types.ts | 2 +- balancer-js/src/modules/pools/index.ts | 12 ++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/balancer-js/src/modules/data/pool/subgraph.ts b/balancer-js/src/modules/data/pool/subgraph.ts index f0492ea8a..ac8d3966b 100644 --- a/balancer-js/src/modules/data/pool/subgraph.ts +++ b/balancer-js/src/modules/data/pool/subgraph.ts @@ -121,8 +121,42 @@ export class PoolsSubgraphRepository return pools.map((pool) => mapType(pool, this.chainId)); } - async find(id: string): Promise { - return await this.findBy('id', id); + /** + * Find pool data for id + * @param id + * @param refresh If true will refetch from SG and update cache + * @returns + */ + async find(id: string, refresh = false): Promise { + // If we're not refreshing and the pool exists in caches then return + if (!refresh && this.pools) { + const cachedPool = (await this.pools).find((pool) => pool.id === id); + if (cachedPool) return cachedPool; + } + + // Fetch pool data from SG, update cache and return + const logger = Logger.getInstance(); + + // SG fetch + logger.time(`fetching pool ${id}`); + const poolQuery = await this.client.Pool({ id }); + logger.timeEnd(`fetching pool ${id}`); + + if (!poolQuery.pool) return undefined; + + const pool = mapType(poolQuery.pool, this.chainId); + // If the pool is already cached, replace it with the new one + logger.time(`updating cache`); + const pools = await this.pools; + if (pools) { + const index = pools.findIndex((p) => p.address === pool.address); + if (index !== -1) { + this.pools = Promise.resolve([...pools.splice(index, 1), pool]); + } else this.pools = Promise.resolve([...pools, pool]); + } else this.pools = Promise.resolve([pool]); + logger.timeEnd(`updating cache`); + + return pool; } async findBy(param: PoolAttribute, value: string): Promise { diff --git a/balancer-js/src/modules/data/types.ts b/balancer-js/src/modules/data/types.ts index 96ae3cb8f..3ed1040ae 100644 --- a/balancer-js/src/modules/data/types.ts +++ b/balancer-js/src/modules/data/types.ts @@ -10,7 +10,7 @@ export * from './pool-shares/types'; export * from './gauge-shares/types'; export interface Findable { - find: (id: string) => Promise; + find: (id: string, refresh?: boolean) => Promise; findBy: (attribute: P, value: V) => Promise; } diff --git a/balancer-js/src/modules/pools/index.ts b/balancer-js/src/modules/pools/index.ts index d81a6b598..c6606b4bd 100644 --- a/balancer-js/src/modules/pools/index.ts +++ b/balancer-js/src/modules/pools/index.ts @@ -285,6 +285,18 @@ export class Pools implements Findable { return this.repositories.pools; } + /** + * Fetches new data from subgraph for pool + * (Will update PoolsSubgraphRepository cache) + * @param pool + * @returns + */ + async refresh(poolId: string): Promise { + const poolRefreshed = await this.repositories.pools.find(poolId, true); + if (!poolRefreshed) return poolRefreshed; + return Pools.wrap(poolRefreshed, this.networkConfig); + } + /** * Calculates APR on any pool data * From 9c4e62d69d87f39d13f08c631c076189da892e16 Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Fri, 5 Jul 2024 10:44:05 +0100 Subject: [PATCH 2/4] fix: Update SG codegen urls. --- balancer-js/src/modules/subgraph/codegen.yml | 8 +- .../generated/balancer-gauges.graphql | 94 +++++++++++ .../subgraph/generated/balancer-gauges.ts | 73 ++++++++ .../balancer-subgraph-schema.graphql | 159 ++++++++++++++++++ .../generated/balancer-subgraph-types.ts | 156 +++++++++++++++++ 5 files changed, 486 insertions(+), 4 deletions(-) diff --git a/balancer-js/src/modules/subgraph/codegen.yml b/balancer-js/src/modules/subgraph/codegen.yml index 1e06d6c7a..2f4189a0c 100644 --- a/balancer-js/src/modules/subgraph/codegen.yml +++ b/balancer-js/src/modules/subgraph/codegen.yml @@ -1,7 +1,7 @@ overwrite: true generates: src/modules/subgraph/generated/balancer-subgraph-types.ts: - schema: ${BALANCER_SUBGRAPH_URL:https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2} + schema: ${BALANCER_SUBGRAPH_URL:https://api.studio.thegraph.com/query/75376/balancer-v2/version/latest} documents: 'src/modules/subgraph/balancer-v2/**/*.graphql' plugins: - typescript @@ -13,11 +13,11 @@ generates: Bytes: string BigDecimal: string src/modules/subgraph/generated/balancer-subgraph-schema.graphql: - schema: ${BALANCER_SUBGRAPH_URL:https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-v2} + schema: ${BALANCER_SUBGRAPH_URL:https://api.studio.thegraph.com/query/75376/balancer-v2/version/latest} plugins: - schema-ast src/modules/subgraph/generated/balancer-gauges.ts: - schema: ${BALANCER_GAUGES_URL:https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges} + schema: ${BALANCER_GAUGES_URL:https://api.studio.thegraph.com/query/75376/balancer-gauges/version/latest} documents: 'src/modules/subgraph/balancer-gauges/**/*.graphql' plugins: - typescript @@ -31,7 +31,7 @@ generates: namingConvention: enumValues: keep src/modules/subgraph/generated/balancer-gauges.graphql: - schema: ${BALANCER_GAUGES_URL:https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges} + schema: ${BALANCER_GAUGES_URL:https://api.studio.thegraph.com/query/75376/balancer-gauges/version/latest} plugins: - schema-ast hooks: diff --git a/balancer-js/src/modules/subgraph/generated/balancer-gauges.graphql b/balancer-js/src/modules/subgraph/generated/balancer-gauges.graphql index bb022a5bc..6187d274f 100644 --- a/balancer-js/src/modules/subgraph/generated/balancer-gauges.graphql +++ b/balancer-js/src/modules/subgraph/generated/balancer-gauges.graphql @@ -11,6 +11,11 @@ directive @entity on OBJECT """Defined a Subgraph ID for an object type""" directive @subgraphId(id: String!) on OBJECT +enum Aggregation_interval { + day + hour +} + scalar BigDecimal scalar BigInt @@ -99,6 +104,30 @@ enum GaugeFactory_orderBy { numGauges } +type GaugeInjector { + """ GaugeInjector contract address """ + id: ID! +} + +input GaugeInjector_filter { + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [GaugeInjector_filter] + id: ID + id_gt: ID + id_gte: ID + id_in: [ID!] + id_lt: ID + id_lte: ID + id_not: ID + id_not_in: [ID!] + or: [GaugeInjector_filter] +} + +enum GaugeInjector_orderBy { + id +} + type GaugeShare { """ User's balance of gauge deposit tokens """ balance: BigDecimal! @@ -1084,6 +1113,34 @@ type Query { """ subgraphError: _SubgraphErrorPolicy_! = deny ): GaugeFactory + gaugeInjector( + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + id: ID! + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): GaugeInjector + gaugeInjectors( + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + first: Int = 100 + orderBy: GaugeInjector_orderBy + orderDirection: OrderDirection + skip: Int = 0 + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + where: GaugeInjector_filter + ): [GaugeInjector!]! gaugeShare( """ The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. @@ -1875,6 +1932,34 @@ type Subscription { """ subgraphError: _SubgraphErrorPolicy_! = deny ): GaugeFactory + gaugeInjector( + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + id: ID! + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): GaugeInjector + gaugeInjectors( + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + first: Int = 100 + orderBy: GaugeInjector_orderBy + orderDirection: OrderDirection + skip: Int = 0 + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + where: GaugeInjector_filter + ): [GaugeInjector!]! gaugeShare( """ The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. @@ -2257,6 +2342,12 @@ type Subscription { ): [VotingEscrow!]! } +""" +A string representation of microseconds UNIX timestamp (16 digits) + +""" +scalar Timestamp + type User { """ List of gauge the user has shares """ gaugeShares(first: Int = 100, orderBy: GaugeShare_orderBy, orderDirection: OrderDirection, skip: Int = 0, where: GaugeShare_filter): [GaugeShare!] @@ -2504,6 +2595,9 @@ type _Block_ { """The block number""" number: Int! + """The hash of the parent block""" + parentHash: Bytes + """Integer representation of the timestamp stored in blocks for the chain""" timestamp: Int } diff --git a/balancer-js/src/modules/subgraph/generated/balancer-gauges.ts b/balancer-js/src/modules/subgraph/generated/balancer-gauges.ts index 5f4a0ae6d..84e34a9af 100644 --- a/balancer-js/src/modules/subgraph/generated/balancer-gauges.ts +++ b/balancer-js/src/modules/subgraph/generated/balancer-gauges.ts @@ -17,8 +17,14 @@ export type Scalars = { BigInt: string; Bytes: string; Int8: any; + Timestamp: any; }; +export enum Aggregation_Interval { + day = 'day', + hour = 'hour' +} + export type BlockChangedFilter = { number_gte: Scalars['Int']; }; @@ -104,6 +110,31 @@ export enum GaugeFactory_OrderBy { numGauges = 'numGauges' } +export type GaugeInjector = { + __typename?: 'GaugeInjector'; + /** GaugeInjector contract address */ + id: Scalars['ID']; +}; + +export type GaugeInjector_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + or?: InputMaybe>>; +}; + +export enum GaugeInjector_OrderBy { + id = 'id' +} + export type GaugeShare = { __typename?: 'GaugeShare'; /** User's balance of gauge deposit tokens */ @@ -1039,6 +1070,8 @@ export type Query = { gauge?: Maybe; gaugeFactories: Array; gaugeFactory?: Maybe; + gaugeInjector?: Maybe; + gaugeInjectors: Array; gaugeShare?: Maybe; gaugeShares: Array; gaugeType?: Maybe; @@ -1099,6 +1132,24 @@ export type QueryGaugeFactoryArgs = { }; +export type QueryGaugeInjectorArgs = { + block?: InputMaybe; + id: Scalars['ID']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryGaugeInjectorsArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + export type QueryGaugeShareArgs = { block?: InputMaybe; id: Scalars['ID']; @@ -1700,6 +1751,8 @@ export type Subscription = { gauge?: Maybe; gaugeFactories: Array; gaugeFactory?: Maybe; + gaugeInjector?: Maybe; + gaugeInjectors: Array; gaugeShare?: Maybe; gaugeShares: Array; gaugeType?: Maybe; @@ -1760,6 +1813,24 @@ export type SubscriptionGaugeFactoryArgs = { }; +export type SubscriptionGaugeInjectorArgs = { + block?: InputMaybe; + id: Scalars['ID']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptionGaugeInjectorsArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + export type SubscriptionGaugeShareArgs = { block?: InputMaybe; id: Scalars['ID']; @@ -2291,6 +2362,8 @@ export type _Block_ = { hash?: Maybe; /** The block number */ number: Scalars['Int']; + /** The hash of the parent block */ + parentHash?: Maybe; /** Integer representation of the timestamp stored in blocks for the chain */ timestamp?: Maybe; }; diff --git a/balancer-js/src/modules/subgraph/generated/balancer-subgraph-schema.graphql b/balancer-js/src/modules/subgraph/generated/balancer-subgraph-schema.graphql index bc315729b..52f2f2542 100644 --- a/balancer-js/src/modules/subgraph/generated/balancer-subgraph-schema.graphql +++ b/balancer-js/src/modules/subgraph/generated/balancer-subgraph-schema.graphql @@ -11,6 +11,11 @@ directive @entity on OBJECT """Defined a Subgraph ID for an object type""" directive @subgraphId(id: String!) on OBJECT +enum Aggregation_interval { + day + hour +} + type AmpUpdate { endAmp: BigInt! endTimestamp: BigInt! @@ -179,6 +184,7 @@ type Balancer { poolCount: Int! pools(first: Int = 100, orderBy: Pool_orderBy, orderDirection: OrderDirection, skip: Int = 0, where: Pool_filter): [Pool!] protocolFeesCollector: Bytes + snapshots(first: Int = 100, orderBy: BalancerSnapshot_orderBy, orderDirection: OrderDirection, skip: Int = 0, where: BalancerSnapshot_filter): [BalancerSnapshot!] totalLiquidity: BigDecimal! totalProtocolFee: BigDecimal totalSwapCount: BigInt! @@ -342,6 +348,7 @@ input Balancer_filter { protocolFeesCollector_not: Bytes protocolFeesCollector_not_contains: Bytes protocolFeesCollector_not_in: [Bytes!] + snapshots_: BalancerSnapshot_filter totalLiquidity: BigDecimal totalLiquidity_gt: BigDecimal totalLiquidity_gte: BigDecimal @@ -389,6 +396,7 @@ enum Balancer_orderBy { poolCount pools protocolFeesCollector + snapshots totalLiquidity totalProtocolFee totalSwapCount @@ -593,6 +601,69 @@ enum CircuitBreaker_orderBy { upperBoundPercentage } +type FXOracle { + decimals: Int + divisor: String + id: ID! + tokens: [Bytes!]! +} + +input FXOracle_filter { + """Filter for the block changed event.""" + _change_block: BlockChangedFilter + and: [FXOracle_filter] + decimals: Int + decimals_gt: Int + decimals_gte: Int + decimals_in: [Int!] + decimals_lt: Int + decimals_lte: Int + decimals_not: Int + decimals_not_in: [Int!] + divisor: String + divisor_contains: String + divisor_contains_nocase: String + divisor_ends_with: String + divisor_ends_with_nocase: String + divisor_gt: String + divisor_gte: String + divisor_in: [String!] + divisor_lt: String + divisor_lte: String + divisor_not: String + divisor_not_contains: String + divisor_not_contains_nocase: String + divisor_not_ends_with: String + divisor_not_ends_with_nocase: String + divisor_not_in: [String!] + divisor_not_starts_with: String + divisor_not_starts_with_nocase: String + divisor_starts_with: String + divisor_starts_with_nocase: String + id: ID + id_gt: ID + id_gte: ID + id_in: [ID!] + id_lt: ID + id_lte: ID + id_not: ID + id_not_in: [ID!] + or: [FXOracle_filter] + tokens: [Bytes!] + tokens_contains: [Bytes!] + tokens_contains_nocase: [Bytes!] + tokens_not: [Bytes!] + tokens_not_contains: [Bytes!] + tokens_not_contains_nocase: [Bytes!] +} + +enum FXOracle_orderBy { + decimals + divisor + id + tokens +} + type GradualWeightUpdate { endTimestamp: BigInt! endWeights: [BigInt!]! @@ -765,6 +836,7 @@ enum InvestType { type JoinExit { amounts: [BigDecimal!]! + block: BigInt id: ID! pool: Pool! sender: Bytes! @@ -785,6 +857,14 @@ input JoinExit_filter { amounts_not_contains: [BigDecimal!] amounts_not_contains_nocase: [BigDecimal!] and: [JoinExit_filter] + block: BigInt + block_gt: BigInt + block_gte: BigInt + block_in: [BigInt!] + block_lt: BigInt + block_lte: BigInt + block_not: BigInt + block_not_in: [BigInt!] id: ID id_gt: ID id_gte: ID @@ -880,6 +960,7 @@ input JoinExit_filter { enum JoinExit_orderBy { amounts + block id pool pool__address @@ -1245,6 +1326,7 @@ type Pool { isInRecoveryMode: Boolean isPaused: Boolean joinExitEnabled: Boolean + joinsExits(first: Int = 100, orderBy: JoinExit_orderBy, orderDirection: OrderDirection, skip: Int = 0, where: JoinExit_filter): [JoinExit!] lambda: BigDecimal lastJoinExitAmp: BigInt lastPostJoinExitInvariant: BigDecimal @@ -2434,6 +2516,7 @@ input Pool_filter { joinExitEnabled_in: [Boolean!] joinExitEnabled_not: Boolean joinExitEnabled_not_in: [Boolean!] + joinsExits_: JoinExit_filter lambda: BigDecimal lambda_gt: BigDecimal lambda_gte: BigDecimal @@ -2955,6 +3038,7 @@ enum Pool_orderBy { isInRecoveryMode isPaused joinExitEnabled + joinsExits lambda lastJoinExitAmp lastPostJoinExitInvariant @@ -3396,6 +3480,34 @@ type Query { subgraphError: _SubgraphErrorPolicy_! = deny where: CircuitBreaker_filter ): [CircuitBreaker!]! + fxoracle( + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + id: ID! + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): FXOracle + fxoracles( + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + first: Int = 100 + orderBy: FXOracle_orderBy + orderDirection: OrderDirection + skip: Int = 0 + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + where: FXOracle_filter + ): [FXOracle!]! gradualWeightUpdate( """ The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. @@ -4101,6 +4213,34 @@ type Subscription { subgraphError: _SubgraphErrorPolicy_! = deny where: CircuitBreaker_filter ): [CircuitBreaker!]! + fxoracle( + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + id: ID! + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + ): FXOracle + fxoracles( + """ + The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. + """ + block: Block_height + first: Int = 100 + orderBy: FXOracle_orderBy + orderDirection: OrderDirection + skip: Int = 0 + + """ + Set to `allow` to receive data even if the subgraph has skipped over errors while syncing. + """ + subgraphError: _SubgraphErrorPolicy_! = deny + where: FXOracle_filter + ): [FXOracle!]! gradualWeightUpdate( """ The block at which the query should be executed. Can either be a `{ hash: Bytes }` value containing a block hash, a `{ number: Int }` containing the block number, or a `{ number_gte: Int }` containing the minimum block number. In the case of `number_gte`, the query will be executed on the latest block only if the subgraph has progressed to or past the minimum block number. Defaults to the latest block when omitted. @@ -4692,6 +4832,7 @@ type Subscription { } type Swap { + block: BigInt caller: Bytes! id: ID! poolId: Pool! @@ -4874,6 +5015,14 @@ input Swap_filter { """Filter for the block changed event.""" _change_block: BlockChangedFilter and: [Swap_filter] + block: BigInt + block_gt: BigInt + block_gte: BigInt + block_in: [BigInt!] + block_lt: BigInt + block_lte: BigInt + block_not: BigInt + block_not_in: [BigInt!] caller: Bytes caller_contains: Bytes caller_gt: Bytes @@ -5040,6 +5189,7 @@ input Swap_filter { } enum Swap_orderBy { + block caller id poolId @@ -5123,6 +5273,12 @@ enum Swap_orderBy { valueUSD } +""" +A string representation of microseconds UNIX timestamp (16 digits) + +""" +scalar Timestamp + type Token { address: String! decimals: Int! @@ -6069,6 +6225,9 @@ type _Block_ { """The block number""" number: Int! + """The hash of the parent block""" + parentHash: Bytes + """Integer representation of the timestamp stored in blocks for the chain""" timestamp: Int } diff --git a/balancer-js/src/modules/subgraph/generated/balancer-subgraph-types.ts b/balancer-js/src/modules/subgraph/generated/balancer-subgraph-types.ts index 5da13f246..1249c1db8 100644 --- a/balancer-js/src/modules/subgraph/generated/balancer-subgraph-types.ts +++ b/balancer-js/src/modules/subgraph/generated/balancer-subgraph-types.ts @@ -17,8 +17,14 @@ export type Scalars = { BigInt: string; Bytes: string; Int8: any; + Timestamp: any; }; +export enum Aggregation_Interval { + Day = 'day', + Hour = 'hour' +} + export type AmpUpdate = { __typename?: 'AmpUpdate'; endAmp: Scalars['BigInt']; @@ -189,6 +195,7 @@ export type Balancer = { poolCount: Scalars['Int']; pools?: Maybe>; protocolFeesCollector?: Maybe; + snapshots?: Maybe>; totalLiquidity: Scalars['BigDecimal']; totalProtocolFee?: Maybe; totalSwapCount: Scalars['BigInt']; @@ -205,6 +212,15 @@ export type BalancerPoolsArgs = { where?: InputMaybe; }; + +export type BalancerSnapshotsArgs = { + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + where?: InputMaybe; +}; + export type BalancerSnapshot = { __typename?: 'BalancerSnapshot'; id: Scalars['ID']; @@ -362,6 +378,7 @@ export type Balancer_Filter = { protocolFeesCollector_not?: InputMaybe; protocolFeesCollector_not_contains?: InputMaybe; protocolFeesCollector_not_in?: InputMaybe>; + snapshots_?: InputMaybe; totalLiquidity?: InputMaybe; totalLiquidity_gt?: InputMaybe; totalLiquidity_gte?: InputMaybe; @@ -409,6 +426,7 @@ export enum Balancer_OrderBy { PoolCount = 'poolCount', Pools = 'pools', ProtocolFeesCollector = 'protocolFeesCollector', + Snapshots = 'snapshots', TotalLiquidity = 'totalLiquidity', TotalProtocolFee = 'totalProtocolFee', TotalSwapCount = 'totalSwapCount', @@ -608,6 +626,70 @@ export enum CircuitBreaker_OrderBy { UpperBoundPercentage = 'upperBoundPercentage' } +export type FxOracle = { + __typename?: 'FXOracle'; + decimals?: Maybe; + divisor?: Maybe; + id: Scalars['ID']; + tokens: Array; +}; + +export type FxOracle_Filter = { + /** Filter for the block changed event. */ + _change_block?: InputMaybe; + and?: InputMaybe>>; + decimals?: InputMaybe; + decimals_gt?: InputMaybe; + decimals_gte?: InputMaybe; + decimals_in?: InputMaybe>; + decimals_lt?: InputMaybe; + decimals_lte?: InputMaybe; + decimals_not?: InputMaybe; + decimals_not_in?: InputMaybe>; + divisor?: InputMaybe; + divisor_contains?: InputMaybe; + divisor_contains_nocase?: InputMaybe; + divisor_ends_with?: InputMaybe; + divisor_ends_with_nocase?: InputMaybe; + divisor_gt?: InputMaybe; + divisor_gte?: InputMaybe; + divisor_in?: InputMaybe>; + divisor_lt?: InputMaybe; + divisor_lte?: InputMaybe; + divisor_not?: InputMaybe; + divisor_not_contains?: InputMaybe; + divisor_not_contains_nocase?: InputMaybe; + divisor_not_ends_with?: InputMaybe; + divisor_not_ends_with_nocase?: InputMaybe; + divisor_not_in?: InputMaybe>; + divisor_not_starts_with?: InputMaybe; + divisor_not_starts_with_nocase?: InputMaybe; + divisor_starts_with?: InputMaybe; + divisor_starts_with_nocase?: InputMaybe; + id?: InputMaybe; + id_gt?: InputMaybe; + id_gte?: InputMaybe; + id_in?: InputMaybe>; + id_lt?: InputMaybe; + id_lte?: InputMaybe; + id_not?: InputMaybe; + id_not_in?: InputMaybe>; + or?: InputMaybe>>; + tokens?: InputMaybe>; + tokens_contains?: InputMaybe>; + tokens_contains_nocase?: InputMaybe>; + tokens_not?: InputMaybe>; + tokens_not_contains?: InputMaybe>; + tokens_not_contains_nocase?: InputMaybe>; +}; + +export enum FxOracle_OrderBy { + Decimals = 'decimals', + Divisor = 'divisor', + Id = 'id', + Tokens = 'tokens' +} + export type GradualWeightUpdate = { __typename?: 'GradualWeightUpdate'; endTimestamp: Scalars['BigInt']; @@ -776,6 +858,7 @@ export enum InvestType { export type JoinExit = { __typename?: 'JoinExit'; amounts: Array; + block?: Maybe; id: Scalars['ID']; pool: Pool; sender: Scalars['Bytes']; @@ -796,6 +879,14 @@ export type JoinExit_Filter = { amounts_not_contains?: InputMaybe>; amounts_not_contains_nocase?: InputMaybe>; and?: InputMaybe>>; + block?: InputMaybe; + block_gt?: InputMaybe; + block_gte?: InputMaybe; + block_in?: InputMaybe>; + block_lt?: InputMaybe; + block_lte?: InputMaybe; + block_not?: InputMaybe; + block_not_in?: InputMaybe>; id?: InputMaybe; id_gt?: InputMaybe; id_gte?: InputMaybe; @@ -891,6 +982,7 @@ export type JoinExit_Filter = { export enum JoinExit_OrderBy { Amounts = 'amounts', + Block = 'block', Id = 'id', Pool = 'pool', PoolAddress = 'pool__address', @@ -1259,6 +1351,7 @@ export type Pool = { isInRecoveryMode?: Maybe; isPaused?: Maybe; joinExitEnabled?: Maybe; + joinsExits?: Maybe>; lambda?: Maybe; lastJoinExitAmp?: Maybe; lastPostJoinExitInvariant?: Maybe; @@ -1352,6 +1445,15 @@ export type PoolHistoricalValuesArgs = { }; +export type PoolJoinsExitsArgs = { + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + where?: InputMaybe; +}; + + export type PoolPriceRateProvidersArgs = { first?: InputMaybe; orderBy?: InputMaybe; @@ -2536,6 +2638,7 @@ export type Pool_Filter = { joinExitEnabled_in?: InputMaybe>; joinExitEnabled_not?: InputMaybe; joinExitEnabled_not_in?: InputMaybe>; + joinsExits_?: InputMaybe; lambda?: InputMaybe; lambda_gt?: InputMaybe; lambda_gte?: InputMaybe; @@ -3057,6 +3160,7 @@ export enum Pool_OrderBy { IsInRecoveryMode = 'isInRecoveryMode', IsPaused = 'isPaused', JoinExitEnabled = 'joinExitEnabled', + JoinsExits = 'joinsExits', Lambda = 'lambda', LastJoinExitAmp = 'lastJoinExitAmp', LastPostJoinExitInvariant = 'lastPostJoinExitInvariant', @@ -3397,6 +3501,8 @@ export type Query = { balancers: Array; circuitBreaker?: Maybe; circuitBreakers: Array; + fxoracle?: Maybe; + fxoracles: Array; gradualWeightUpdate?: Maybe; gradualWeightUpdates: Array; joinExit?: Maybe; @@ -3519,6 +3625,24 @@ export type QueryCircuitBreakersArgs = { }; +export type QueryFxoracleArgs = { + block?: InputMaybe; + id: Scalars['ID']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type QueryFxoraclesArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + export type QueryGradualWeightUpdateArgs = { block?: InputMaybe; id: Scalars['ID']; @@ -3908,6 +4032,8 @@ export type Subscription = { balancers: Array; circuitBreaker?: Maybe; circuitBreakers: Array; + fxoracle?: Maybe; + fxoracles: Array; gradualWeightUpdate?: Maybe; gradualWeightUpdates: Array; joinExit?: Maybe; @@ -4030,6 +4156,24 @@ export type SubscriptionCircuitBreakersArgs = { }; +export type SubscriptionFxoracleArgs = { + block?: InputMaybe; + id: Scalars['ID']; + subgraphError?: _SubgraphErrorPolicy_; +}; + + +export type SubscriptionFxoraclesArgs = { + block?: InputMaybe; + first?: InputMaybe; + orderBy?: InputMaybe; + orderDirection?: InputMaybe; + skip?: InputMaybe; + subgraphError?: _SubgraphErrorPolicy_; + where?: InputMaybe; +}; + + export type SubscriptionGradualWeightUpdateArgs = { block?: InputMaybe; id: Scalars['ID']; @@ -4409,6 +4553,7 @@ export type SubscriptionUsersArgs = { export type Swap = { __typename?: 'Swap'; + block?: Maybe; caller: Scalars['Bytes']; id: Scalars['ID']; poolId: Pool; @@ -4592,6 +4737,14 @@ export type Swap_Filter = { /** Filter for the block changed event. */ _change_block?: InputMaybe; and?: InputMaybe>>; + block?: InputMaybe; + block_gt?: InputMaybe; + block_gte?: InputMaybe; + block_in?: InputMaybe>; + block_lt?: InputMaybe; + block_lte?: InputMaybe; + block_not?: InputMaybe; + block_not_in?: InputMaybe>; caller?: InputMaybe; caller_contains?: InputMaybe; caller_gt?: InputMaybe; @@ -4758,6 +4911,7 @@ export type Swap_Filter = { }; export enum Swap_OrderBy { + Block = 'block', Caller = 'caller', Id = 'id', PoolId = 'poolId', @@ -5820,6 +5974,8 @@ export type _Block_ = { hash?: Maybe; /** The block number */ number: Scalars['Int']; + /** The hash of the parent block */ + parentHash?: Maybe; /** Integer representation of the timestamp stored in blocks for the chain */ timestamp?: Maybe; }; From 8e9d8de0ec6f7d1ed92e62bea27016df2a3f1967 Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Fri, 5 Jul 2024 11:37:27 +0100 Subject: [PATCH 3/4] fix: Use custom query when passed. Update broken tests. --- .../src/modules/data/liquidity-gauges/multicall.spec.ts | 3 ++- balancer-js/src/modules/data/pool/subgraph.ts | 5 ++++- balancer-js/src/modules/pools/apr/apr.integration.spec.ts | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/balancer-js/src/modules/data/liquidity-gauges/multicall.spec.ts b/balancer-js/src/modules/data/liquidity-gauges/multicall.spec.ts index 08738d6a6..d91ad8cb5 100644 --- a/balancer-js/src/modules/data/liquidity-gauges/multicall.spec.ts +++ b/balancer-js/src/modules/data/liquidity-gauges/multicall.spec.ts @@ -1,3 +1,4 @@ +// yarn test:only ./src/modules/data/liquidity-gauges/multicall.spec.ts import { expect } from 'chai'; import { JsonRpcProvider } from '@ethersproject/providers'; import { Zero } from '@ethersproject/constants'; @@ -65,7 +66,7 @@ describe('Liquidity gauge multicall', () => { const fetcher = new LiquidityGaugesMulticallRepository(multicall, 1); const gauges = new LiquidityGaugesSubgraphRepository( - 'https://api.thegraph.com/subgraphs/name/balancer-labs/balancer-gauges' + 'https://api.studio.thegraph.com/query/75376/balancer-gauges/version/latest' ); let gaugeAddresses: string[]; diff --git a/balancer-js/src/modules/data/pool/subgraph.ts b/balancer-js/src/modules/data/pool/subgraph.ts index ac8d3966b..87fe30938 100644 --- a/balancer-js/src/modules/data/pool/subgraph.ts +++ b/balancer-js/src/modules/data/pool/subgraph.ts @@ -38,6 +38,7 @@ export class PoolsSubgraphRepository public skip = 0; private blockHeight: undefined | (() => Promise); private query: GraphQLQuery; + private isCustomQuery: boolean; /** * Repository with optional lazy loaded blockHeight @@ -60,7 +61,7 @@ export class PoolsSubgraphRepository }, }, }; - + this.isCustomQuery = !!options.query; const args = Object.assign({}, options.query?.args || defaultArgs); const attrs = Object.assign({}, options.query?.attrs || {}); @@ -128,6 +129,8 @@ export class PoolsSubgraphRepository * @returns */ async find(id: string, refresh = false): Promise { + if(this.isCustomQuery) + return await this.findBy('id', id); // If we're not refreshing and the pool exists in caches then return if (!refresh && this.pools) { const cachedPool = (await this.pools).find((pool) => pool.id === id); diff --git a/balancer-js/src/modules/pools/apr/apr.integration.spec.ts b/balancer-js/src/modules/pools/apr/apr.integration.spec.ts index b48099287..0cde300ce 100644 --- a/balancer-js/src/modules/pools/apr/apr.integration.spec.ts +++ b/balancer-js/src/modules/pools/apr/apr.integration.spec.ts @@ -23,7 +23,8 @@ const usdStable = const auraBALveBAL = '0x3dd0843a028c86e0b760b1a76929d1c5ef93a2dd000200000000000000000249'; -describe('APR tests', () => { +// APRs are offered via API now +describe.skip('APR tests', () => { describe('pool with yield tokens', () => { it('has tokenAprs', async () => { const pool = await pools.find(ethStEth); From 5de2ba82a6904e17174945ca4c79ee6395d1f735 Mon Sep 17 00:00:00 2001 From: johngrantuk Date: Fri, 5 Jul 2024 11:39:50 +0100 Subject: [PATCH 4/4] chore: lint! --- balancer-js/src/modules/data/pool/subgraph.ts | 3 +-- balancer-js/src/modules/pools/apr/apr.integration.spec.ts | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/balancer-js/src/modules/data/pool/subgraph.ts b/balancer-js/src/modules/data/pool/subgraph.ts index 87fe30938..6644501c9 100644 --- a/balancer-js/src/modules/data/pool/subgraph.ts +++ b/balancer-js/src/modules/data/pool/subgraph.ts @@ -129,8 +129,7 @@ export class PoolsSubgraphRepository * @returns */ async find(id: string, refresh = false): Promise { - if(this.isCustomQuery) - return await this.findBy('id', id); + if (this.isCustomQuery) return await this.findBy('id', id); // If we're not refreshing and the pool exists in caches then return if (!refresh && this.pools) { const cachedPool = (await this.pools).find((pool) => pool.id === id); diff --git a/balancer-js/src/modules/pools/apr/apr.integration.spec.ts b/balancer-js/src/modules/pools/apr/apr.integration.spec.ts index 0cde300ce..f88d4759d 100644 --- a/balancer-js/src/modules/pools/apr/apr.integration.spec.ts +++ b/balancer-js/src/modules/pools/apr/apr.integration.spec.ts @@ -23,7 +23,7 @@ const usdStable = const auraBALveBAL = '0x3dd0843a028c86e0b760b1a76929d1c5ef93a2dd000200000000000000000249'; -// APRs are offered via API now +// APRs are offered via API now describe.skip('APR tests', () => { describe('pool with yield tokens', () => { it('has tokenAprs', async () => {