diff --git a/packages/hyperdrive-appconfig/src/appconfig/AppConfig.ts b/packages/hyperdrive-appconfig/src/appconfig/AppConfig.ts index ff302cbef..176765fe8 100644 --- a/packages/hyperdrive-appconfig/src/appconfig/AppConfig.ts +++ b/packages/hyperdrive-appconfig/src/appconfig/AppConfig.ts @@ -1,8 +1,9 @@ import { Address } from "abitype"; import { ChainConfig, ChainId } from "src/chains/chains"; import { HyperdriveConfig } from "src/hyperdrives/HyperdriveConfig"; +import { AnyRewardKey } from "src/hyperdrives/rewards"; import { protocols } from "src/protocols"; -import { RewardFunctionKey } from "src/rewards/rewards"; +import { RewardResolverKey } from "src/rewards/rewards"; import { TokenConfig } from "src/tokens/types"; import { yieldSources } from "src/yieldSources/yieldSources"; import { ZapConfig } from "src/zaps/ZapsConfig"; @@ -18,5 +19,5 @@ export interface AppConfig { protocols: typeof protocols; yieldSources: typeof yieldSources; zaps: Record; - rewards: Record; + rewards: Record; } diff --git a/packages/hyperdrive-appconfig/src/appconfig/HyperdriveConfigResolver.ts b/packages/hyperdrive-appconfig/src/appconfig/HyperdriveConfigResolver.ts index 3603f3c86..62a50d224 100644 --- a/packages/hyperdrive-appconfig/src/appconfig/HyperdriveConfigResolver.ts +++ b/packages/hyperdrive-appconfig/src/appconfig/HyperdriveConfigResolver.ts @@ -1,8 +1,17 @@ import { ReadHyperdrive } from "@delvtech/hyperdrive-viem"; import { HyperdriveConfig } from "src/hyperdrives/HyperdriveConfig"; +import { AnyRewardKey } from "src/hyperdrives/rewards"; +import { RewardResolverKey } from "src/rewards/rewards"; import { TokenConfig } from "src/tokens/types"; import { PublicClient } from "viem"; +export interface HyperdriveConfigResolverResult { + hyperdriveConfig: HyperdriveConfig; + sharesTokenConfig?: TokenConfig; + baseTokenConfig?: TokenConfig; + rewards?: Record; +} + export type HyperdriveConfigResolver = ( hyperdrive: ReadHyperdrive, publicClient: PublicClient, @@ -12,9 +21,4 @@ export type HyperdriveConfigResolver = ( * would timeout. */ earliestBlock?: bigint, -) => Promise<{ - hyperdriveConfig: HyperdriveConfig; - sharesTokenConfig?: TokenConfig; - baseTokenConfig?: TokenConfig; - rewards?: string[]; -}>; +) => Promise; diff --git a/packages/hyperdrive-appconfig/src/appconfig/getAppConfig.ts b/packages/hyperdrive-appconfig/src/appconfig/getAppConfig.ts index d0587a336..efc36697f 100644 --- a/packages/hyperdrive-appconfig/src/appconfig/getAppConfig.ts +++ b/packages/hyperdrive-appconfig/src/appconfig/getAppConfig.ts @@ -10,8 +10,10 @@ import { getCbethHyperdrive } from "src/hyperdrives/cbeth/getCbethHyperdrive"; import { getCustomHyperdrive } from "src/hyperdrives/custom/getCustomHyperdrive"; import { getGnosisWstethHyperdrive } from "src/hyperdrives/gnosisWsteth/getGnosisWstethHyperdrive"; import { getMorphoHyperdrive } from "src/hyperdrives/morpho/getMorphoHyperdrive"; +import { AnyRewardKey } from "src/hyperdrives/rewards"; import { getStethHyperdrive } from "src/hyperdrives/steth/getStethHyperdrive"; import { protocols } from "src/protocols"; +import { RewardResolverKey } from "src/rewards/rewards"; import { AERO_ICON_URL, DAI_ICON_URL, @@ -64,7 +66,7 @@ const hyperdriveKindResolvers: Record< isBaseTokenWithdrawalEnabled: false, isShareTokenWithdrawalEnabled: true, }, - rewards: { + rewardsMap: { short: ["fetchLineaRewards"], lp: ["fetchLineaRewards"], }, @@ -84,7 +86,7 @@ const hyperdriveKindResolvers: Record< isBaseTokenDepositEnabled: false, isShareTokenDepositsEnabled: true, }, - rewards: { + rewardsMap: { short: ["fetchLineaRewards"], lp: ["fetchLineaRewards"], }, @@ -134,7 +136,7 @@ const hyperdriveKindResolvers: Record< isBaseTokenDepositEnabled: true, isShareTokenDepositsEnabled: true, }, - rewards: { + rewardsMap: { short: ["fetchEtherfiRewards"], lp: ["fetchEtherfiRewards"], }, @@ -218,7 +220,7 @@ const hyperdriveKindResolvers: Record< isBaseTokenWithdrawalEnabled: true, isShareTokenWithdrawalEnabled: true, }, - rewards: { + rewardsMap: { short: ["fetchGyroscopeRewards"], lp: ["fetchGyroscopeRewards"], }, @@ -358,7 +360,7 @@ const hyperdriveKindResolvers: Record< isShareTokenWithdrawalEnabled: true, }, tokenPlaces: 4, - rewards: { + rewardsMap: { short: ["fetchMorphoMwethRewards"], lp: ["fetchMorphoMwethRewards"], }, @@ -381,7 +383,7 @@ const hyperdriveKindResolvers: Record< isShareTokenWithdrawalEnabled: true, }, tokenPlaces: 2, - rewards: { + rewardsMap: { short: ["fetchMorphoMwusdcRewards"], lp: ["fetchMorphoMwusdcRewards"], }, @@ -404,7 +406,7 @@ const hyperdriveKindResolvers: Record< isShareTokenWithdrawalEnabled: true, }, tokenPlaces: 2, - rewards: { + rewardsMap: { short: ["fetchMorphoMweurcRewards"], lp: ["fetchMorphoMweurcRewards"], }, @@ -481,7 +483,7 @@ const hyperdriveKindResolvers: Record< yieldSourceId: "aeroUsdcAero", baseTokenPlaces: 9, // aero lp tokens are super small baseTokenTags: [], - rewards: { + rewardsMap: { short: ["fetchAeroRewards"], lp: ["fetchAeroRewards"], }, @@ -556,7 +558,7 @@ const hyperdriveKindResolvers: Record< baseTokenIconUrl: USDC_ICON_URL, baseTokenPlaces: 2, yieldSourceId: "morphoCbethUsdc", - rewards: { + rewardsMap: { short: ["fetchMorphoCbethUsdcRewards"], lp: ["fetchMorphoCbethUsdcRewards"], }, @@ -579,6 +581,7 @@ export async function getAppConfig({ earliestBlock?: bigint; }): Promise { const tokens: TokenConfig[] = []; + let allRewards: Record = {}; const chainId = publicClient.chain?.id as number; // Get ReadHyperdrive instances from the registry to ensure @@ -599,7 +602,7 @@ export async function getAppConfig({ throw new Error(`Missing resolver for hyperdrive kind: ${kind}.`); } - const { hyperdriveConfig, baseTokenConfig, sharesTokenConfig } = + const { hyperdriveConfig, baseTokenConfig, sharesTokenConfig, rewards } = await hyperdriveResolver(hyperdrive, publicClient, earliestBlock); // Not all hyperdrives have a base or shares token, so only add them if @@ -611,6 +614,13 @@ export async function getAppConfig({ tokens.push(sharesTokenConfig); } + if (rewards) { + allRewards = { + ...allRewards, + ...rewards, + }; + } + return hyperdriveConfig; }), ); @@ -625,7 +635,7 @@ export async function getAppConfig({ yieldSources, chains, zaps, - rewards: {}, + rewards: allRewards, }; return config; diff --git a/packages/hyperdrive-appconfig/src/hyperdrives/HyperdriveConfig.ts b/packages/hyperdrive-appconfig/src/hyperdrives/HyperdriveConfig.ts index d717307b7..d05458f6b 100644 --- a/packages/hyperdrive-appconfig/src/hyperdrives/HyperdriveConfig.ts +++ b/packages/hyperdrive-appconfig/src/hyperdrives/HyperdriveConfig.ts @@ -1,5 +1,5 @@ import { PoolConfig } from "@delvtech/hyperdrive-viem"; -import { RewardFunctionKey } from "src/rewards/rewards"; +import { RewardResolverKey } from "src/rewards/rewards"; import { YieldSourceId } from "src/yieldSources/types"; import { Address } from "viem"; @@ -42,9 +42,9 @@ export interface HyperdriveConfig { }; rewards?: { - long?: RewardFunctionKey[]; - short?: RewardFunctionKey[]; - lp?: RewardFunctionKey[]; + long?: RewardResolverKey[]; + short?: RewardResolverKey[]; + lp?: RewardResolverKey[]; }; poolConfig: PoolConfig; diff --git a/packages/hyperdrive-appconfig/src/hyperdrives/aero/getAeroHyperdrive.ts b/packages/hyperdrive-appconfig/src/hyperdrives/aero/getAeroHyperdrive.ts index a2b0dab0a..716c6bdc8 100644 --- a/packages/hyperdrive-appconfig/src/hyperdrives/aero/getAeroHyperdrive.ts +++ b/packages/hyperdrive-appconfig/src/hyperdrives/aero/getAeroHyperdrive.ts @@ -1,8 +1,12 @@ import { ReadHyperdrive } from "@delvtech/hyperdrive-viem"; +import { HyperdriveConfigResolverResult } from "src/appconfig/HyperdriveConfigResolver"; import { HyperdriveConfig } from "src/hyperdrives/HyperdriveConfig"; import { formatHyperdriveName } from "src/hyperdrives/formatHyperdriveName"; +import { + HyperdriveRewardsMap, + parseHyperdriveRewardsMap, +} from "src/hyperdrives/rewards"; import { getTokenConfig } from "src/tokens/getTokenConfig"; -import { TokenConfig } from "src/tokens/types"; import { YieldSourceId } from "src/yieldSources/types"; import { yieldSources } from "src/yieldSources/yieldSources"; @@ -12,18 +16,15 @@ export async function getAeroLpHyperdrive({ baseTokenTags, baseTokenIconUrl, baseTokenPlaces, - rewards, + rewardsMap, }: { hyperdrive: ReadHyperdrive; yieldSourceId: YieldSourceId; baseTokenTags: string[]; baseTokenIconUrl: string; baseTokenPlaces: number; - rewards?: HyperdriveConfig["rewards"]; -}): Promise<{ - baseTokenConfig: TokenConfig; - hyperdriveConfig: HyperdriveConfig; -}> { + rewardsMap?: HyperdriveRewardsMap; +}): Promise { const version = await hyperdrive.getVersion(); const poolConfig = await hyperdrive.getPoolConfig(); @@ -65,12 +66,13 @@ export async function getAeroLpHyperdrive({ poolConfig, }; - if (rewards) { - hyperdriveConfig.rewards = rewards; - } + const rewards = rewardsMap + ? parseHyperdriveRewardsMap(hyperdrive.address, rewardsMap) + : undefined; return { baseTokenConfig, hyperdriveConfig, + rewards, }; } diff --git a/packages/hyperdrive-appconfig/src/hyperdrives/custom/getCustomHyperdrive.ts b/packages/hyperdrive-appconfig/src/hyperdrives/custom/getCustomHyperdrive.ts index 3c657ff90..4cdbe993c 100644 --- a/packages/hyperdrive-appconfig/src/hyperdrives/custom/getCustomHyperdrive.ts +++ b/packages/hyperdrive-appconfig/src/hyperdrives/custom/getCustomHyperdrive.ts @@ -1,8 +1,12 @@ import { ReadHyperdrive } from "@delvtech/hyperdrive-viem"; +import { HyperdriveConfigResolverResult } from "src/appconfig/HyperdriveConfigResolver"; import { HyperdriveConfig } from "src/hyperdrives/HyperdriveConfig"; import { formatHyperdriveName } from "src/hyperdrives/formatHyperdriveName"; +import { + HyperdriveRewardsMap, + parseHyperdriveRewardsMap, +} from "src/hyperdrives/rewards"; import { getTokenConfig } from "src/tokens/getTokenConfig"; -import { TokenConfig } from "src/tokens/types"; import { yieldSources } from "src/yieldSources/yieldSources"; type DepositOptions = HyperdriveConfig["depositOptions"]; @@ -19,7 +23,7 @@ interface GetHyperdriveConfigParams { tokenPlaces: number; sharesTokenTags?: string[]; baseTokenTags?: string[]; - rewards?: HyperdriveConfig["rewards"]; + rewardsMap?: HyperdriveRewardsMap; } export async function getCustomHyperdrive({ @@ -33,12 +37,8 @@ export async function getCustomHyperdrive({ tokenPlaces, sharesTokenTags = [], baseTokenTags = [], - rewards, -}: GetHyperdriveConfigParams): Promise<{ - sharesTokenConfig: TokenConfig; - baseTokenConfig: TokenConfig; - hyperdriveConfig: HyperdriveConfig; -}> { + rewardsMap, +}: GetHyperdriveConfigParams): Promise { const version = await hyperdrive.getVersion(); const poolConfig = await hyperdrive.getPoolConfig(); const sharesToken = await hyperdrive.getSharesToken(); @@ -84,13 +84,14 @@ export async function getCustomHyperdrive({ poolConfig, }; - if (rewards) { - hyperdriveConfig.rewards = rewards; - } + const rewards = rewardsMap + ? parseHyperdriveRewardsMap(hyperdrive.address, rewardsMap) + : {}; return { sharesTokenConfig, baseTokenConfig, hyperdriveConfig, + rewards, }; } diff --git a/packages/hyperdrive-appconfig/src/hyperdrives/morpho/getMorphoHyperdrive.ts b/packages/hyperdrive-appconfig/src/hyperdrives/morpho/getMorphoHyperdrive.ts index d25b57db6..1d7d36142 100644 --- a/packages/hyperdrive-appconfig/src/hyperdrives/morpho/getMorphoHyperdrive.ts +++ b/packages/hyperdrive-appconfig/src/hyperdrives/morpho/getMorphoHyperdrive.ts @@ -1,9 +1,13 @@ import { ReadHyperdrive } from "@delvtech/hyperdrive-viem"; import retry from "p-retry"; +import { HyperdriveConfigResolverResult } from "src/appconfig/HyperdriveConfigResolver"; import { HyperdriveConfig } from "src/hyperdrives/HyperdriveConfig"; import { formatHyperdriveName } from "src/hyperdrives/formatHyperdriveName"; +import { + HyperdriveRewardsMap, + parseHyperdriveRewardsMap, +} from "src/hyperdrives/rewards"; import { getTokenConfig } from "src/tokens/getTokenConfig"; -import { TokenConfig } from "src/tokens/types"; import { YieldSourceId } from "src/yieldSources/types"; import { yieldSources } from "src/yieldSources/yieldSources"; @@ -13,18 +17,15 @@ export async function getMorphoHyperdrive({ baseTokenTags, baseTokenIconUrl, baseTokenPlaces, - rewards, + rewardsMap, }: { hyperdrive: ReadHyperdrive; yieldSourceId: YieldSourceId; baseTokenTags: string[]; baseTokenIconUrl: string; baseTokenPlaces: number; - rewards?: HyperdriveConfig["rewards"]; -}): Promise<{ - baseTokenConfig: TokenConfig; - hyperdriveConfig: HyperdriveConfig; -}> { + rewardsMap?: HyperdriveRewardsMap; +}): Promise { const version = await hyperdrive.getVersion(); const poolConfig = await hyperdrive.getPoolConfig(); @@ -78,12 +79,13 @@ export async function getMorphoHyperdrive({ poolConfig, }; - if (rewards) { - hyperdriveConfig.rewards = rewards; - } + const rewards = rewardsMap + ? parseHyperdriveRewardsMap(hyperdrive.address, rewardsMap) + : undefined; return { baseTokenConfig, hyperdriveConfig, + rewards, }; } diff --git a/packages/hyperdrive-appconfig/src/hyperdrives/rewards.ts b/packages/hyperdrive-appconfig/src/hyperdrives/rewards.ts new file mode 100644 index 000000000..d7b14a390 --- /dev/null +++ b/packages/hyperdrive-appconfig/src/hyperdrives/rewards.ts @@ -0,0 +1,49 @@ +import { RewardResolverKey } from "src/rewards/rewards"; +import { Address } from "viem"; + +export type LongRewardKey = `hyperdrive-long/${Address}`; +export type ShortRewardKey = `hyperdrive-short/${Address}`; +export type LpRewardKey = `hyperdrive-lp/${Address}`; + +export type AnyRewardKey = LongRewardKey | ShortRewardKey | LpRewardKey; + +export function makeLongRewardKey(hyperdriveAddress: Address): LongRewardKey { + return `hyperdrive-long/${hyperdriveAddress}`; +} +export function makeShortRewardKey(hyperdriveAddress: Address): ShortRewardKey { + return `hyperdrive-short/${hyperdriveAddress}`; +} + +export function makeLpRewardKey(hyperdriveAddress: Address): LpRewardKey { + return `hyperdrive-lp/${hyperdriveAddress}`; +} + +export interface HyperdriveRewardsMap { + long?: RewardResolverKey[]; + short?: RewardResolverKey[]; + lp?: RewardResolverKey[]; +} + +export function parseHyperdriveRewardsMap( + hyperdriveAddress: Address, + rewardsMap: { + long?: RewardResolverKey[]; + short?: RewardResolverKey[]; + lp?: RewardResolverKey[]; + }, +): Record { + const rewards: Record = {}; + rewardsMap?.long?.forEach((reward) => { + const key = makeLongRewardKey(hyperdriveAddress); + rewards[key] = [...(rewards[key] || []), reward]; + }); + rewardsMap?.short?.forEach((reward) => { + const key = makeShortRewardKey(hyperdriveAddress); + rewards[key] = [...(rewards[key] || []), reward]; + }); + rewardsMap?.lp?.forEach((reward) => { + const key = makeLpRewardKey(hyperdriveAddress); + rewards[key] = [...(rewards[key] || []), reward]; + }); + return rewards; +} diff --git a/packages/hyperdrive-appconfig/src/rewards/rewards.ts b/packages/hyperdrive-appconfig/src/rewards/rewards.ts index 84c1ba9f2..e68d76183 100644 --- a/packages/hyperdrive-appconfig/src/rewards/rewards.ts +++ b/packages/hyperdrive-appconfig/src/rewards/rewards.ts @@ -20,4 +20,4 @@ export const rewardFunctions = { fetchGyroscopeRewards, } as const; -export type RewardFunctionKey = keyof typeof rewardFunctions; +export type RewardResolverKey = keyof typeof rewardFunctions; diff --git a/packages/hyperdrive-appconfig/src/rewards/selectors.ts b/packages/hyperdrive-appconfig/src/rewards/selectors.ts index 1008ac129..b7fbbbe33 100644 --- a/packages/hyperdrive-appconfig/src/rewards/selectors.ts +++ b/packages/hyperdrive-appconfig/src/rewards/selectors.ts @@ -1,5 +1,5 @@ import { AppConfig } from "src/appconfig/AppConfig"; -import { RewardFunctionKey, rewardFunctions } from "src/rewards/rewards"; +import { RewardResolverKey, rewardFunctions } from "src/rewards/rewards"; import { RewardsResolver } from "src/rewards/types"; import { YieldSourceId } from "src/yieldSources/types"; @@ -26,7 +26,7 @@ export function getRewardsFn({ export function getRewardsFn2({ rewardFn, }: { - rewardFn: RewardFunctionKey; + rewardFn: RewardResolverKey; }): RewardsResolver | undefined { return rewardFunctions[rewardFn]; } diff --git a/packages/hyperdrive-appconfig/src/yieldSources/types.ts b/packages/hyperdrive-appconfig/src/yieldSources/types.ts index 1dd2e93a0..2c8ab1f94 100644 --- a/packages/hyperdrive-appconfig/src/yieldSources/types.ts +++ b/packages/hyperdrive-appconfig/src/yieldSources/types.ts @@ -1,6 +1,6 @@ import { ChainId } from "src/chains/chains"; import { ProtocolId } from "src/protocols"; -import { RewardFunctionKey } from "src/rewards/rewards"; +import { RewardResolverKey } from "src/rewards/rewards"; /** * The comprehensive list of all yield source ids. To add a new yield source, @@ -50,5 +50,5 @@ export interface YieldSourceConfig { /** * @deprecated rewards has moved to HyperdriveConfig */ - rewardsFn?: RewardFunctionKey; + rewardsFn?: RewardResolverKey; }