Skip to content

Commit

Permalink
Show miles in Reward tab (#1779)
Browse files Browse the repository at this point in the history
* Add hypervue to static assets

* Add miles to knownTokenConfigs, update token url

* Bump up retries

* Display miles in useClaimableRewards

* Fix filter
  • Loading branch information
DannyDelott authored Feb 10, 2025
1 parent 2f415fc commit d7b6ff7
Show file tree
Hide file tree
Showing 9 changed files with 680 additions and 591 deletions.
9 changes: 9 additions & 0 deletions apps/hyperdrive-trading/src/public/hypervue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 26 additions & 16 deletions apps/hyperdrive-trading/src/ui/rewards/hooks/useClaimableRewards.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { parseFixed } from "@delvtech/fixed-point-wasm";
import { MerklApi } from "@merkl/api";
import { useQuery } from "@tanstack/react-query";
import { makeQueryKey2 } from "src/base/makeQueryKey";
import {
HyperdriveRewardsApi,
Reward,
} from "src/rewards/generated/HyperdriveRewardsApi";
import { useAppConfigForConnectedChain } from "src/ui/appconfig/useAppConfigForConnectedChain";
import { Address, Hash } from "viem";
import { base, gnosis, linea, mainnet } from "viem/chains";
import { usePublicClient } from "wagmi";
Expand All @@ -20,21 +20,20 @@ export function useClaimableRewards({
} {
const publicClient = usePublicClient();
const queryEnabled = !!account && !!publicClient;
const appConfig = useAppConfigForConnectedChain();
const chainIds = Object.keys(appConfig.chains).map(Number);
const { data: rewards, status: rewardsStatus } = useQuery({
queryKey: makeQueryKey2({
namespace: "rewards",
queryId: "unclaimedRewards",
params: { account, chainIds },
params: { account },
}),
enabled: queryEnabled,
queryFn: queryEnabled
? async () => {
const hyperdriveRewards = await fetchHyperdriveRewardApi(account);
// TODO: Add mile rewards
// const mileRewards = await fetchMileRewards(account, chainIds);
const allRewards = [...hyperdriveRewards];

const mileRewards = await fetchMileRewards(account);
const allRewards = [...hyperdriveRewards, ...mileRewards];

return allRewards;
}
: undefined,
Expand All @@ -55,12 +54,17 @@ async function fetchHyperdriveRewardApi(account: Address): Promise<Reward[]> {
});

try {
const response = await rewardsApi.get.rewardsStubDetail(account);
return response.rewards;
const response = await rewardsApi.get.rewardsUserDetail(account);
// TODO: Remove this once claimbableAmount is no longer formatted server side
return response.rewards.map((r) => ({
...r,
claimableAmount: parseFixed(r.claimableAmount).bigint.toString(),
}));
} catch (error: any) {
// This throws a 404 if the account does not have any rewards, which
// is fine, just return an empty array and display no rewards
if (error.error.error === "No rewards found for this address") {
console.log("No rewards found for this address");
return [];
}
// There are no other well-known errors we can catch, so re-throw
Expand All @@ -86,10 +90,9 @@ const MerklDistributorsByChain: Record<number, Address> = {
[linea.id]: "0x3Ef3D8bA38EBe18DB133cEc108f4D14CE00Dd9Ae",
};

async function fetchMileRewards(
account: Address,
chainIds: number[],
): Promise<Reward[]> {
async function fetchMileRewards(account: Address): Promise<Reward[]> {
const chainIds = [mainnet.id, gnosis.id, linea.id, base.id];

// Request miles earned on each chain. We have to call this once per chain
// since the merkl api is buggy, despite accepting an array of chain ids. If
// this gets fixed, we can remove the Promise.all and simplify this logic.
Expand All @@ -110,11 +113,18 @@ async function fetchMileRewards(
}),
)
)
.filter(({ data }) => data?.length)
.filter(
({ data }) =>
data?.length &&
// since we only request a single chain id, we can just grab the first
// data item
data[0].rewards.find(
(d) => d.token.symbol === "Miles" && !!Number(d.amount),
),
)
.map(({ data, chainId }) => {
// since we only use a single chain id, we can just grab the first data item
const rewards = data![0].rewards.find(
(d) => d.token.symbol === "Miles" && !!Number(d.pending),
(d) => d.token.symbol === "Miles" && !!Number(d.amount),
);
return {
chainId,
Expand Down
1 change: 0 additions & 1 deletion apps/hyperdrive-trading/src/ui/rewards/queryKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ interface RewardsQueryKeys {
*/
unclaimedRewards: {
account: Address | undefined;
chainIds: number[];
};

// TODO: We may not need these as these queries are just list wrappers around
Expand Down
552 changes: 288 additions & 264 deletions packages/hyperdrive-appconfig/src/generated/all.appconfig.ts

Large diffs are not rendered by default.

274 changes: 143 additions & 131 deletions packages/hyperdrive-appconfig/src/generated/mainnet.appconfig.ts

Large diffs are not rendered by default.

364 changes: 188 additions & 176 deletions packages/hyperdrive-appconfig/src/generated/testnet.appconfig.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export async function getMorphoHyperdrive({
{
// sometimes this fails to find the block due to alchemy blips, retry a
// few times in this case
retries: 5,
retries: 15,
onFailedAttempt: () => {
console.log("Retrying getInitializationBlock...");
},
Expand Down
25 changes: 24 additions & 1 deletion packages/hyperdrive-appconfig/src/rewards/knownTokenConfigs.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { rewardsMainnetFork } from "src/chains/cloudChain";
import { HyperVueMilesIconUrl } from "src/rewards/resolvers/hypervueMiles";
import {
AERO_ICON_URL,
MORPHO_ICON_URL,
WELL_ICON_URL,
} from "src/tokens/tokenIconsUrls";
import { TokenConfig } from "src/tokens/types";
import { base, mainnet } from "viem/chains";
import { base, gnosis, mainnet } from "viem/chains";

/**
* Yield sources may offer rewards in tokens that are not part of Hyperdrive.
Expand All @@ -15,6 +16,28 @@ import { base, mainnet } from "viem/chains";
*/

export const knownTokenConfigs2: TokenConfig[] = [
{
address: "0x79385D4B4c531bBbDa25C4cFB749781Bd9E23039",
chainId: gnosis.id,
decimals: 18,
name: "Miles",
symbol: "MILES",
places: 4,
iconUrl: HyperVueMilesIconUrl,
tags: [],
priceOracle: "defillama",
},
{
address: "0x79385D4B4c531bBbDa25C4cFB749781Bd9E23039",
chainId: rewardsMainnetFork.id,
decimals: 18,
name: "Miles",
symbol: "MILES",
places: 4,
iconUrl: HyperVueMilesIconUrl,
tags: [],
priceOracle: "defillama",
},
{
address: "0xA88594D404727625A9437C3f886C7643872296AE",
chainId: base.id,
Expand Down

Large diffs are not rendered by default.

0 comments on commit d7b6ff7

Please sign in to comment.