Skip to content

Commit

Permalink
Add interest rate fetching to the subgraph client
Browse files Browse the repository at this point in the history
In this update, we introduced a new function `getInterestRates` to the subgraph client API. The function allows querying MorphoBlueMarket for its interest rates within a particular time range. A specific GraphQL query, `GetInterestRates`, has been defined for this purpose. The upgrade enhances data interaction with the decentralized finance market.
  • Loading branch information
jakubswierczek committed Apr 16, 2024
1 parent 069112c commit 12c0d56
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 7 deletions.
19 changes: 19 additions & 0 deletions packages/morpho-blue-subgraph/queries/intrest-rates.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
query GetInterestRates($marketId: String!, $marketIdBytes: ID!, $fromTimestamp: BigInt!, $toTimestamp: BigInt!) {
market(id: $marketIdBytes) {
id
collateralToken {
address
symbol
}
debtToken {
address
symbol
}
}
interestRates(where: { market: $marketId, timestamp_gte: $fromTimestamp, timestamp_lte: $toTimestamp }, orderBy: timestamp, orderDirection: desc) {
id
rate
timestamp
type
}
}
95 changes: 88 additions & 7 deletions packages/morpho-blue-subgraph/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { request } from 'graphql-request'

import { ChainId } from '@summerfi/serverless-shared'
import type { Address } from '@summerfi/serverless-shared'
import { ChainId } from '@summerfi/serverless-shared'
import { Logger } from '@aws-lambda-powertools/logger'
import { CollateralLockedDocument } from './types/graphql/generated'
import { CollateralLockedDocument, GetInterestRatesDocument } from './types/graphql/generated'

const chainIdSubgraphMap: Partial<Record<ChainId, string>> = {
[ChainId.MAINNET]: 'summer-morpho-blue',
Expand Down Expand Up @@ -33,11 +33,6 @@ export interface CollateralLocked {
owner: Address
}

/**
* The key of the first record is the owner of the collaterals, second record is the collateral address
*/
export type CollateralLockedRecord = Record<Address, Record<Address, CollateralLocked>>

export interface CollateralLockedResult {
lockedCollaterals: CollateralLocked[]
}
Expand All @@ -46,6 +41,35 @@ export type GetCollateralLocked = (
params: GetCollateralLockedParams,
) => Promise<CollateralLockedResult>

export interface GetInterestRateParams {
marketId: `0x${string}`
fromTimestamp: bigint
toTimestamp: bigint
}

export interface InterestRate {
rate: number
type: 'borrow' | 'lend'
timestamp: bigint
}

export interface MorphoBlueMarketInterestRateResult {
marketId: `0x${string}`
collateralToken: {
symbol: string
address: Address
}
debtToken: {
symbol: string
address: Address
}
interestRates: InterestRate[]
}

export type GetInterestRate = (
params: GetInterestRateParams,
) => Promise<MorphoBlueMarketInterestRateResult>

async function getCollateralLocked(
params: GetCollateralLockedParams,
config: SubgraphClientConfig,
Expand All @@ -67,14 +91,71 @@ async function getCollateralLocked(
}
}

async function getInterestRates(
params: GetInterestRateParams,
config: SubgraphClientConfig,
): Promise<MorphoBlueMarketInterestRateResult> {
const url = getEndpoint(config.chainId, config.urlBase)
const result = await request(url, GetInterestRatesDocument, {
marketId: params.marketId,
marketIdBytes: params.marketId,
fromTimestamp: params.fromTimestamp,
toTimestamp: params.toTimestamp,
})

if (result.market == null) {
config.logger?.warn('No market found for marketId', { marketId: params.marketId })
return {
marketId: params.marketId,
collateralToken: {
symbol: 'UNKNOWN',
address: '0x0',
},
debtToken: {
symbol: 'UNKNOWN',
address: '0x0',
},
interestRates: [],
}
}

config.logger?.info('Interest rates found', {
length: result.interestRates.length,
marketId: params.marketId,
collateralToken: result.market.collateralToken?.symbol,
debtToken: result.market.debtToken?.symbol,
})

const mapped: InterestRate[] = result.interestRates.map((c) => ({
rate: Number(c.rate),
type: c.type === 'borrow' ? ('borrow' as const) : ('lend' as const),
timestamp: c.timestamp,
}))

return {
marketId: result.market.id as `0x${string}`,
collateralToken: {
symbol: result.market.collateralToken!.symbol,
address: result.market.collateralToken!.address as Address,
},
debtToken: {
symbol: result.market.debtToken!.symbol,
address: result.market.debtToken!.address as Address,
},
interestRates: mapped,
}
}

export interface MorphoBlueSubgraphClient {
getCollateralLocked: GetCollateralLocked
getInterestRate: GetInterestRate
}

export function getMorphoBlueSubgraphClient(
config: SubgraphClientConfig,
): MorphoBlueSubgraphClient {
return {
getCollateralLocked: (params: GetCollateralLockedParams) => getCollateralLocked(params, config),
getInterestRate: (params: GetInterestRateParams) => getInterestRates(params, config),
}
}
40 changes: 40 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions summerfi-api/get-apy-function/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@aws-lambda-powertools/metrics": "^2.0.2",
"@aws-lambda-powertools/tracer": "^2.0.2",
"@summerfi/serverless-shared": "workspace:*",
"@summerfi/morpho-blue-subgraph": "workspace:*",
"viem": "^1.19.11",
"zod": "^3.22.4"
},
Expand Down

0 comments on commit 12c0d56

Please sign in to comment.