Skip to content

Commit 2cfdb89

Browse files
committed
fix: better merkle apr fetching
1 parent 5c44b98 commit 2cfdb89

File tree

2 files changed

+105
-44
lines changed

2 files changed

+105
-44
lines changed

src/gearboxRewards/api.ts

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import {
2525
MerkleXYZApi,
2626
MerkleXYZUserRewardsResponse,
2727
MerkleXYZV4CampaignsResponse,
28+
MerkleXYZV4RewardCampaignResponse,
29+
MerklXYZV4RewardCampaign,
2830
} from "./merklAPI";
2931

3032
export interface GearboxExtraMerkleLmReward {
@@ -142,19 +144,59 @@ export class GearboxRewardsApi {
142144
c => c.status === "LIVE" && c.chainId === chainId,
143145
);
144146

147+
const aprIdsList = currentActiveCampaigns
148+
.map(c =>
149+
// apr token for campaigns with a single reward is obvious
150+
c.aprRecord.breakdowns.length > 1
151+
? c.aprRecord.breakdowns.map(b => {
152+
return {
153+
campaignId: c.id,
154+
aprId: b.identifier,
155+
};
156+
})
157+
: [],
158+
)
159+
.flat(1);
160+
161+
const aprIdsResponse = await Promise.allSettled(
162+
aprIdsList.map(id =>
163+
axios.get<MerkleXYZV4RewardCampaignResponse>(
164+
MerkleXYZApi.getGearboxRewardCampaignUrl(id.aprId),
165+
),
166+
),
167+
);
168+
169+
const aprCampaignByAPRId = aprIdsResponse.reduce<
170+
Record<Address, Array<MerklXYZV4RewardCampaign> | undefined>
171+
>((acc, r, i) => {
172+
const id = aprIdsList[i].aprId;
173+
acc[id] = r.status === "fulfilled" ? r.value.data : undefined;
174+
175+
return acc;
176+
}, {});
177+
145178
const r = currentActiveCampaigns.reduce<
146179
Record<Address, Array<ExtraRewardApy>>
147180
>((acc, campaign) => {
148181
const rewardSource = (
149182
campaign.tokens[0]?.address || campaign.identifier
150183
).toLowerCase() as Address;
151184

152-
const allRewards = campaign.rewardsRecord.breakdowns
185+
const allRewards = campaign.aprRecord.breakdowns
153186
.map((r, i) => {
154-
const tokenLc = r.token.address.toLowerCase() as Address;
155-
const { symbol = r.token.symbol } = tokensList[tokenLc] || {};
187+
const apy = r.value;
188+
189+
const { rewardToken } = aprCampaignByAPRId[r.identifier]?.[0] || {};
190+
const tokenRewardsRecord =
191+
campaign.rewardsRecord.breakdowns[i]?.token;
192+
193+
const { address = tokenRewardsRecord?.address || "" } =
194+
rewardToken || {};
156195

157-
const apy = campaign.aprRecord.breakdowns[i]?.value || 0;
196+
const tokenLc = address.toLowerCase() as Address;
197+
const {
198+
symbol = rewardToken?.symbol || tokenRewardsRecord?.symbol || "",
199+
} = tokensList[tokenLc] || {};
158200

159201
const apyObject: ExtraRewardApy = {
160202
token: rewardSource,

src/gearboxRewards/merklAPI.ts

Lines changed: 59 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ export interface MerkleXYZUserRewards {
2929

3030
export type MerkleXYZUserRewardsResponse = Record<string, MerkleXYZUserRewards>;
3131

32+
interface MerkleXYZChain {
33+
id: number;
34+
name: string;
35+
icon: string;
36+
}
37+
38+
interface MerkleXYZToken {
39+
id: string;
40+
name: string;
41+
chainId: number;
42+
address: Address;
43+
decimals: number;
44+
icon: string;
45+
verified: boolean;
46+
isTest: boolean;
47+
price: number | null;
48+
symbol: string;
49+
}
50+
3251
export interface MerklXYZV4Campaign {
3352
chainId: number;
3453
type: string;
@@ -41,23 +60,8 @@ export interface MerklXYZV4Campaign {
4160
dailyRewards: number;
4261
tags: Array<string>;
4362
id: string;
44-
tokens: Array<{
45-
id: string;
46-
name: string;
47-
chainId: number;
48-
address: Address;
49-
decimals: number;
50-
icon: string;
51-
verified: boolean;
52-
isTest: boolean;
53-
price: number | null;
54-
symbol: string;
55-
}>;
56-
chain: {
57-
id: number;
58-
name: string;
59-
icon: string;
60-
};
63+
tokens: Array<MerkleXYZToken>;
64+
chain: MerkleXYZChain;
6165
aprRecord: {
6266
cumulated: number;
6367
timestamp: string;
@@ -80,19 +84,7 @@ export interface MerklXYZV4Campaign {
8084
total: number;
8185
timestamp: string;
8286
breakdowns: Array<{
83-
token: {
84-
id: string;
85-
name: string;
86-
chainId: number;
87-
address: Address;
88-
decimals: 18;
89-
symbol: string;
90-
displaySymbol: string;
91-
icon: string;
92-
verified: boolean;
93-
isTest: boolean;
94-
price: number;
95-
};
87+
token: MerkleXYZToken;
9688
amount: string;
9789
id: number;
9890
value: number;
@@ -103,17 +95,42 @@ export interface MerklXYZV4Campaign {
10395
}
10496
export type MerkleXYZV4CampaignsResponse = Array<MerklXYZV4Campaign>;
10597

106-
interface Campaign {
107-
amountDecimal: string;
108-
campaignId: string;
109-
campaignType: number;
110-
endTimestamp: number;
111-
rewardToken: string;
112-
rewardTokenSymbol: string;
113-
startTimestamp: number;
98+
export interface MerklXYZV4RewardCampaign {
99+
id: string;
100+
computeChainId: number;
101+
distributionChainId: number;
102+
campaignId: Address;
103+
rewardTokenId: string;
104+
amount: string;
105+
opportunityId: string;
106+
startTimestamp: string;
107+
endTimestamp: string;
108+
creatorAddress: Address;
109+
params: {
110+
url: string;
111+
duration: number;
112+
blacklist: Array<Address>;
113+
whitelist: Array<Address>;
114+
forwarders: Array<Address>;
115+
targetToken: Address;
116+
symbolRewardToken: string;
117+
symbolTargetToken: string;
118+
decimalsRewardToken: number;
119+
decimalsTargetToken: number;
120+
};
121+
chain: MerkleXYZChain;
122+
rewardToken: MerkleXYZToken;
123+
distributionChain: MerkleXYZChain;
124+
campaignStatus: {
125+
campaignId: string;
126+
computedUntil: string;
127+
processingStarted: string;
128+
status: "SUCCESS";
129+
error: string;
130+
details: string;
131+
};
114132
}
115-
116-
export type MerkleXYZRewardsCampaignsResponse = Array<Campaign>;
133+
export type MerkleXYZV4RewardCampaignResponse = Array<MerklXYZV4RewardCampaign>;
117134

118135
// https://api.merkl.xyz/v3/campaignsForMainParameter?chainId=1&mainParameter=0xE2037090f896A858E3168B978668F22026AC52e7
119136

@@ -125,4 +142,6 @@ export class MerkleXYZApi {
125142

126143
static getGearboxCampaignsUrl = () =>
127144
"https://api.merkl.xyz/v4/opportunities?name=gearbox";
145+
static getGearboxRewardCampaignUrl = (campaignId: Address) =>
146+
`https://api.merkl.xyz/v4/campaigns?campaignId=${campaignId}`;
128147
}

0 commit comments

Comments
 (0)