@defisaver/positions-sdk 2.1.142-dev → 2.1.143
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/aaveV3/merkl.js +4 -7
- package/cjs/aaveV4/merkl.js +5 -6
- package/cjs/claiming/aaveV3.d.ts +2 -1
- package/cjs/claiming/aaveV3.js +13 -4
- package/cjs/compoundV3/merkl.js +4 -6
- package/cjs/fluid/index.d.ts +9 -1
- package/cjs/fluid/index.js +10 -4
- package/cjs/fluid/merkl.d.ts +7 -4
- package/cjs/fluid/merkl.js +22 -16
- package/cjs/helpers/fluidHelpers/index.d.ts +3 -1
- package/cjs/helpers/fluidHelpers/index.js +37 -4
- package/cjs/morphoBlue/index.d.ts +1 -1
- package/cjs/morphoBlue/index.js +2 -2
- package/cjs/morphoBlue/merkl.d.ts +6 -4
- package/cjs/morphoBlue/merkl.js +17 -16
- package/cjs/portfolio/index.js +5 -5
- package/cjs/services/merkl.d.ts +6 -0
- package/cjs/services/merkl.js +39 -0
- package/cjs/types/claiming.d.ts +12 -1
- package/cjs/types/claiming.js +2 -0
- package/cjs/types/common.d.ts +4 -0
- package/cjs/types/common.js +5 -1
- package/cjs/types/fluid.d.ts +2 -0
- package/esm/aaveV3/merkl.js +5 -8
- package/esm/aaveV4/merkl.js +5 -6
- package/esm/claiming/aaveV3.d.ts +2 -1
- package/esm/claiming/aaveV3.js +12 -4
- package/esm/compoundV3/merkl.js +5 -7
- package/esm/fluid/index.d.ts +9 -1
- package/esm/fluid/index.js +9 -3
- package/esm/fluid/merkl.d.ts +7 -4
- package/esm/fluid/merkl.js +19 -15
- package/esm/helpers/fluidHelpers/index.d.ts +3 -1
- package/esm/helpers/fluidHelpers/index.js +38 -6
- package/esm/morphoBlue/index.d.ts +1 -1
- package/esm/morphoBlue/index.js +1 -1
- package/esm/morphoBlue/merkl.d.ts +6 -4
- package/esm/morphoBlue/merkl.js +16 -15
- package/esm/portfolio/index.js +6 -6
- package/esm/services/merkl.d.ts +6 -0
- package/esm/services/merkl.js +35 -0
- package/esm/types/claiming.d.ts +12 -1
- package/esm/types/claiming.js +2 -0
- package/esm/types/common.d.ts +4 -0
- package/esm/types/common.js +4 -0
- package/esm/types/fluid.d.ts +2 -0
- package/package.json +1 -1
- package/src/aaveV3/merkl.ts +5 -8
- package/src/aaveV4/merkl.ts +5 -5
- package/src/claiming/aaveV3.ts +19 -7
- package/src/compoundV3/merkl.ts +5 -6
- package/src/fluid/index.ts +9 -3
- package/src/fluid/merkl.ts +18 -13
- package/src/helpers/fluidHelpers/index.ts +68 -6
- package/src/morphoBlue/index.ts +1 -1
- package/src/morphoBlue/merkl.ts +16 -15
- package/src/portfolio/index.ts +6 -6
- package/src/services/merkl.ts +31 -0
- package/src/types/claiming.ts +13 -0
- package/src/types/common.ts +5 -0
- package/src/types/fluid.ts +3 -1
package/cjs/types/claiming.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export declare enum ClaimType {
|
|
|
4
4
|
AAVE_REWARDS = "AAVE_REWARDS",
|
|
5
5
|
/** Merit rewards from AAVE (various tokens) */
|
|
6
6
|
AAVE_MERIT_REWARDS = "AAVE_MERIT_REWARDS",
|
|
7
|
+
/** Rewards distributed through Merkl across supported protocols */
|
|
8
|
+
MERKL_REWARDS = "MERKL_REWARDS",
|
|
7
9
|
/** Rewards from Compound V3 (only in COMP) */
|
|
8
10
|
COMPOUND_V3_COMP = "COMPOUND_V3_COMP",
|
|
9
11
|
/** Rewards from Spark (wstETH only for now) */
|
|
@@ -43,6 +45,15 @@ export type AaveMeritRewardsClaimableToken = _ClaimableTokenPartial & {
|
|
|
43
45
|
unclaimed: string;
|
|
44
46
|
};
|
|
45
47
|
};
|
|
48
|
+
export type MerklRewardsClaimableToken = _ClaimableTokenPartial & {
|
|
49
|
+
claimType: ClaimType.MERKL_REWARDS;
|
|
50
|
+
additionalClaimFields: {
|
|
51
|
+
accumulated: string;
|
|
52
|
+
proof: string[];
|
|
53
|
+
decimals: string;
|
|
54
|
+
unclaimed: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
46
57
|
export type SparkRewardsClaimableToken = _ClaimableTokenPartial & {
|
|
47
58
|
claimType: ClaimType.SPARK_REWARDS;
|
|
48
59
|
additionalClaimFields: {
|
|
@@ -91,5 +102,5 @@ export type UniswapAirdropClaimableToken = _ClaimableTokenPartial & {
|
|
|
91
102
|
proof: string[];
|
|
92
103
|
};
|
|
93
104
|
};
|
|
94
|
-
export type ClaimableToken = AaveRewardsClaimableToken | AaveMeritRewardsClaimableToken | CompoundV3CompClaimableToken | SparkRewardsClaimableToken | KingRewardsClaimableToken | SparkAirdropClaimableToken | SparkWstEthRewardsClaimableToken | EthenaAirdropClaimableToken;
|
|
105
|
+
export type ClaimableToken = AaveRewardsClaimableToken | AaveMeritRewardsClaimableToken | MerklRewardsClaimableToken | CompoundV3CompClaimableToken | SparkRewardsClaimableToken | KingRewardsClaimableToken | SparkAirdropClaimableToken | SparkWstEthRewardsClaimableToken | EthenaAirdropClaimableToken;
|
|
95
106
|
export {};
|
package/cjs/types/claiming.js
CHANGED
|
@@ -7,6 +7,8 @@ var ClaimType;
|
|
|
7
7
|
ClaimType["AAVE_REWARDS"] = "AAVE_REWARDS";
|
|
8
8
|
/** Merit rewards from AAVE (various tokens) */
|
|
9
9
|
ClaimType["AAVE_MERIT_REWARDS"] = "AAVE_MERIT_REWARDS";
|
|
10
|
+
/** Rewards distributed through Merkl across supported protocols */
|
|
11
|
+
ClaimType["MERKL_REWARDS"] = "MERKL_REWARDS";
|
|
10
12
|
/** Rewards from Compound V3 (only in COMP) */
|
|
11
13
|
ClaimType["COMPOUND_V3_COMP"] = "COMPOUND_V3_COMP";
|
|
12
14
|
/** Rewards from Spark (wstETH only for now) */
|
package/cjs/types/common.d.ts
CHANGED
|
@@ -6,6 +6,9 @@ export declare enum IncentiveSide {
|
|
|
6
6
|
Supply = "supply",
|
|
7
7
|
Borrow = "borrow"
|
|
8
8
|
}
|
|
9
|
+
export declare enum IncentiveSource {
|
|
10
|
+
Merkl = "merkl"
|
|
11
|
+
}
|
|
9
12
|
export declare enum IncentiveEligibilityId {
|
|
10
13
|
AaveV3EthenaLiquidLeverage = "0x0dC599DBB180E64E42b87332FDeC3a551445ea44BORROW_BL",
|
|
11
14
|
AaveV3ArbitrumEthSupply = "0x5d16261c6715a653248269861bbacf68a9774cde",
|
|
@@ -25,6 +28,7 @@ export interface IncentiveData {
|
|
|
25
28
|
token: string;
|
|
26
29
|
apy: string;
|
|
27
30
|
incentiveKind?: IncentiveKind;
|
|
31
|
+
source?: IncentiveSource;
|
|
28
32
|
description?: string;
|
|
29
33
|
eligibilityId?: IncentiveEligibilityId;
|
|
30
34
|
}
|
package/cjs/types/common.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NetworkNumber = exports.LeverageType = exports.IncentiveEligibilityId = exports.IncentiveSide = exports.IncentiveKind = void 0;
|
|
3
|
+
exports.NetworkNumber = exports.LeverageType = exports.IncentiveEligibilityId = exports.IncentiveSource = exports.IncentiveSide = exports.IncentiveKind = void 0;
|
|
4
4
|
var IncentiveKind;
|
|
5
5
|
(function (IncentiveKind) {
|
|
6
6
|
IncentiveKind["Staking"] = "staking";
|
|
@@ -11,6 +11,10 @@ var IncentiveSide;
|
|
|
11
11
|
IncentiveSide["Supply"] = "supply";
|
|
12
12
|
IncentiveSide["Borrow"] = "borrow";
|
|
13
13
|
})(IncentiveSide || (exports.IncentiveSide = IncentiveSide = {}));
|
|
14
|
+
var IncentiveSource;
|
|
15
|
+
(function (IncentiveSource) {
|
|
16
|
+
IncentiveSource["Merkl"] = "merkl";
|
|
17
|
+
})(IncentiveSource || (exports.IncentiveSource = IncentiveSource = {}));
|
|
14
18
|
var IncentiveEligibilityId;
|
|
15
19
|
(function (IncentiveEligibilityId) {
|
|
16
20
|
IncentiveEligibilityId["AaveV3EthenaLiquidLeverage"] = "0x0dC599DBB180E64E42b87332FDeC3a551445ea44BORROW_BL";
|
package/cjs/types/fluid.d.ts
CHANGED
|
@@ -319,6 +319,8 @@ export interface FluidAggregatedVaultData {
|
|
|
319
319
|
leftToBorrowUsd: string;
|
|
320
320
|
netApy: string;
|
|
321
321
|
incentiveUsd: string;
|
|
322
|
+
merklSupplyIncentives: IncentiveData[];
|
|
323
|
+
merklBorrowIncentives: IncentiveData[];
|
|
322
324
|
ratio: string;
|
|
323
325
|
collRatio: string;
|
|
324
326
|
minRatio: string;
|
package/esm/aaveV3/merkl.js
CHANGED
|
@@ -8,7 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { aprToApy } from '../moneymarket';
|
|
11
|
-
import {
|
|
11
|
+
import { fetchAllMerklOpportunities } from '../services/merkl';
|
|
12
|
+
import { wethToEth } from '../services/utils';
|
|
12
13
|
import { OpportunityAction, OpportunityStatus, } from '../types';
|
|
13
14
|
export const getAaveUnderlyingSymbol = (_symbol = '') => {
|
|
14
15
|
let symbol = _symbol
|
|
@@ -35,14 +36,10 @@ export const formatAaveAsset = (_symbol) => {
|
|
|
35
36
|
};
|
|
36
37
|
export const getMerkleCampaigns = (chainId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
37
38
|
try {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
signal: AbortSignal.timeout(LONGER_TIMEOUT),
|
|
39
|
+
const opportunities = yield fetchAllMerklOpportunities({
|
|
40
|
+
mainProtocolId: 'aave',
|
|
41
|
+
status: OpportunityStatus.LIVE,
|
|
42
42
|
});
|
|
43
|
-
if (!res.ok)
|
|
44
|
-
throw new Error('Failed to fetch Merkle campaigns');
|
|
45
|
-
const opportunities = yield res.json();
|
|
46
43
|
const relevantOpportunities = opportunities
|
|
47
44
|
.filter((o) => o.chainId === chainId)
|
|
48
45
|
.filter((o) => o.status === OpportunityStatus.LIVE);
|
package/esm/aaveV4/merkl.js
CHANGED
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { aprToApy } from '../moneymarket';
|
|
11
|
-
import {
|
|
11
|
+
import { fetchAllMerklOpportunities } from '../services/merkl';
|
|
12
12
|
import { IncentiveKind, IncentiveSide, OpportunityAction, OpportunityStatus, } from '../types';
|
|
13
13
|
/**
|
|
14
14
|
* Merkl tags Aave V4 reward campaigns by scope via the `type` field:
|
|
@@ -63,12 +63,11 @@ export const buildAaveV4MerklRewardMap = (opportunities, chainId) => {
|
|
|
63
63
|
};
|
|
64
64
|
export const getAaveV4MerkleCampaigns = (chainId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
65
|
try {
|
|
66
|
-
const
|
|
67
|
-
|
|
66
|
+
const opportunities = yield fetchAllMerklOpportunities({
|
|
67
|
+
mainProtocolId: 'aave',
|
|
68
|
+
type: 'AAVE_V4_HUB_SUPPLY,AAVE_V4_HUB_BORROW,AAVE_V4_SPOKE_SUPPLY,AAVE_V4_SPOKE_BORROW',
|
|
69
|
+
status: OpportunityStatus.LIVE,
|
|
68
70
|
});
|
|
69
|
-
if (!res.ok)
|
|
70
|
-
throw new Error('Failed to fetch Aave V4 Merkle campaigns');
|
|
71
|
-
const opportunities = yield res.json();
|
|
72
71
|
return buildAaveV4MerklRewardMap(opportunities, chainId);
|
|
73
72
|
}
|
|
74
73
|
catch (e) {
|
package/esm/claiming/aaveV3.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Client } from 'viem';
|
|
2
2
|
import { EthAddress, NetworkNumber } from '../types';
|
|
3
|
-
import { ClaimableToken } from '../types/claiming';
|
|
3
|
+
import { ClaimableToken, MerklRewardsClaimableToken } from '../types/claiming';
|
|
4
4
|
export declare function getUnclaimedRewardsForAllMarkets(provider: Client, network: NetworkNumber, walletAddress: EthAddress, marketAddress: EthAddress): Promise<ClaimableToken[]>;
|
|
5
|
+
export declare function getMerklUnclaimedRewards(account: EthAddress, network: NetworkNumber): Promise<MerklRewardsClaimableToken[]>;
|
|
5
6
|
export declare function getMeritUnclaimedRewards(account: EthAddress, network: NetworkNumber): Promise<ClaimableToken[]>;
|
package/esm/claiming/aaveV3.js
CHANGED
|
@@ -88,7 +88,7 @@ export function getUnclaimedRewardsForAllMarkets(provider, network, walletAddres
|
|
|
88
88
|
return mapAaveRewardsToClaimableTokens(Object.values(totalUnclaimedPerRewardToken), marketAddress, walletAddress);
|
|
89
89
|
});
|
|
90
90
|
}
|
|
91
|
-
export function
|
|
91
|
+
export function getMerklUnclaimedRewards(account, network) {
|
|
92
92
|
return __awaiter(this, void 0, void 0, function* () {
|
|
93
93
|
let data;
|
|
94
94
|
try {
|
|
@@ -96,7 +96,7 @@ export function getMeritUnclaimedRewards(account, network) {
|
|
|
96
96
|
data = yield res.json();
|
|
97
97
|
}
|
|
98
98
|
catch (error) {
|
|
99
|
-
console.error('External API Failure:
|
|
99
|
+
console.error('External API Failure: Merkl rewards', error);
|
|
100
100
|
data = [];
|
|
101
101
|
}
|
|
102
102
|
const claimableTokens = [];
|
|
@@ -114,12 +114,12 @@ export function getMeritUnclaimedRewards(account, network) {
|
|
|
114
114
|
return;
|
|
115
115
|
const unclaimed = getEthAmountForDecimals(unclaimedAmount, token.decimals);
|
|
116
116
|
claimableTokens.push({
|
|
117
|
-
claimType: ClaimType.
|
|
117
|
+
claimType: ClaimType.MERKL_REWARDS,
|
|
118
118
|
amount: unclaimed,
|
|
119
119
|
symbol: token.symbol,
|
|
120
120
|
tokenAddress: token.address,
|
|
121
121
|
walletAddress: account,
|
|
122
|
-
label: '
|
|
122
|
+
label: 'Merkl Rewards',
|
|
123
123
|
underlyingSymbol: getAaveUnderlyingSymbol(token.symbol),
|
|
124
124
|
additionalClaimFields: {
|
|
125
125
|
accumulated: amount,
|
|
@@ -133,3 +133,11 @@ export function getMeritUnclaimedRewards(account, network) {
|
|
|
133
133
|
return claimableTokens;
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
|
+
export function getMeritUnclaimedRewards(account, network) {
|
|
137
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
138
|
+
const rewards = yield getMerklUnclaimedRewards(account, network);
|
|
139
|
+
return rewards
|
|
140
|
+
.filter(reward => reward.symbol.startsWith('a'))
|
|
141
|
+
.map(reward => (Object.assign(Object.assign({}, reward), { claimType: ClaimType.AAVE_MERIT_REWARDS, label: 'AAVE Merit Rewards' })));
|
|
142
|
+
});
|
|
143
|
+
}
|
package/esm/compoundV3/merkl.js
CHANGED
|
@@ -9,7 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { getAssetInfoByAddress } from '@defisaver/tokens';
|
|
11
11
|
import { aprToApy } from '../moneymarket';
|
|
12
|
-
import {
|
|
12
|
+
import { fetchAllMerklOpportunities } from '../services/merkl';
|
|
13
|
+
import { compareAddresses, wethToEth } from '../services/utils';
|
|
13
14
|
import { IncentiveKind, OpportunityAction, OpportunityStatus, } from '../types';
|
|
14
15
|
/**
|
|
15
16
|
* Merkl tags Compound V3 reward campaigns with COMPOUND_V3_* opportunity types (e.g.
|
|
@@ -21,13 +22,10 @@ import { IncentiveKind, OpportunityAction, OpportunityStatus, } from '../types';
|
|
|
21
22
|
*/
|
|
22
23
|
export const getCompoundV3MerklOpportunities = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
24
|
try {
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
return yield fetchAllMerklOpportunities({
|
|
26
|
+
mainProtocolId: 'compound-v3',
|
|
27
|
+
status: OpportunityStatus.LIVE,
|
|
26
28
|
});
|
|
27
|
-
if (!res.ok)
|
|
28
|
-
throw new Error('Failed to fetch Compound V3 Merkl campaigns');
|
|
29
|
-
const data = yield res.json();
|
|
30
|
-
return Array.isArray(data) ? data : [];
|
|
31
29
|
}
|
|
32
30
|
catch (e) {
|
|
33
31
|
console.error('Failed to fetch Compound V3 Merkl campaigns', e);
|
package/esm/fluid/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Client, PublicClient } from 'viem';
|
|
2
2
|
import { EthAddress, EthereumProvider, NetworkNumber } from '../types/common';
|
|
3
3
|
import { FluidAssetsData, FluidMarketData, FluidMarketInfo, FluidUsedAssets, FluidVaultData, InnerFluidMarketData } from '../types';
|
|
4
|
-
export {
|
|
4
|
+
export { FluidMerklOpportunityType, buildFluidMerklRewardMap, getFluidMerklCampaigns, attachFluidMerklIncentives, } from './merkl';
|
|
5
5
|
export declare const EMPTY_USED_ASSET: {
|
|
6
6
|
isSupplied: boolean;
|
|
7
7
|
isBorrowed: boolean;
|
|
@@ -22,6 +22,8 @@ export declare const EMPTY_FLUID_DATA: {
|
|
|
22
22
|
minRatio: string;
|
|
23
23
|
netApy: string;
|
|
24
24
|
incentiveUsd: string;
|
|
25
|
+
merklSupplyIncentives: never[];
|
|
26
|
+
merklBorrowIncentives: never[];
|
|
25
27
|
totalInterestUsd: string;
|
|
26
28
|
isSubscribedToAutomation: boolean;
|
|
27
29
|
automationResubscribeRequired: boolean;
|
|
@@ -127,6 +129,8 @@ export declare const _getUserPositions: (provider: PublicClient, network: Networ
|
|
|
127
129
|
leftToBorrowUsd: string;
|
|
128
130
|
netApy: string;
|
|
129
131
|
incentiveUsd: string;
|
|
132
|
+
merklSupplyIncentives: import("../types").IncentiveData[];
|
|
133
|
+
merklBorrowIncentives: import("../types").IncentiveData[];
|
|
130
134
|
ratio: string;
|
|
131
135
|
collRatio: string;
|
|
132
136
|
minRatio: string;
|
|
@@ -159,6 +163,8 @@ export declare const getUserPositions: (provider: EthereumProvider, network: Net
|
|
|
159
163
|
leftToBorrowUsd: string;
|
|
160
164
|
netApy: string;
|
|
161
165
|
incentiveUsd: string;
|
|
166
|
+
merklSupplyIncentives: import("../types").IncentiveData[];
|
|
167
|
+
merklBorrowIncentives: import("../types").IncentiveData[];
|
|
162
168
|
ratio: string;
|
|
163
169
|
collRatio: string;
|
|
164
170
|
minRatio: string;
|
|
@@ -191,6 +197,8 @@ export declare const _getUserPositionsPortfolio: (provider: PublicClient, networ
|
|
|
191
197
|
leftToBorrowUsd: string;
|
|
192
198
|
netApy: string;
|
|
193
199
|
incentiveUsd: string;
|
|
200
|
+
merklSupplyIncentives: import("../types").IncentiveData[];
|
|
201
|
+
merklBorrowIncentives: import("../types").IncentiveData[];
|
|
194
202
|
ratio: string;
|
|
195
203
|
collRatio: string;
|
|
196
204
|
minRatio: string;
|
package/esm/fluid/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import { getChainlinkAssetAddress, getSyrupUSDTChainLinkPriceCalls, getSyrupUSDT
|
|
|
20
20
|
import { getStakingApy, STAKING_ASSETS } from '../staking';
|
|
21
21
|
import { getViemProvider } from '../services/viem';
|
|
22
22
|
import { attachFluidMerklIncentives, getFluidMerklCampaigns } from './merkl';
|
|
23
|
-
export {
|
|
23
|
+
export { FluidMerklOpportunityType, buildFluidMerklRewardMap, getFluidMerklCampaigns, attachFluidMerklIncentives, } from './merkl';
|
|
24
24
|
export const EMPTY_USED_ASSET = {
|
|
25
25
|
isSupplied: false,
|
|
26
26
|
isBorrowed: false,
|
|
@@ -912,6 +912,8 @@ export const EMPTY_FLUID_DATA = {
|
|
|
912
912
|
minRatio: '0',
|
|
913
913
|
netApy: '0',
|
|
914
914
|
incentiveUsd: '0',
|
|
915
|
+
merklSupplyIncentives: [],
|
|
916
|
+
merklBorrowIncentives: [],
|
|
915
917
|
totalInterestUsd: '0',
|
|
916
918
|
isSubscribedToAutomation: false,
|
|
917
919
|
automationResubscribeRequired: false,
|
|
@@ -1363,8 +1365,12 @@ export const _getUserPositionsPortfolio = (provider, network, user) => __awaiter
|
|
|
1363
1365
|
tokens.push('ETH');
|
|
1364
1366
|
if (!tokens.includes('WBTC'))
|
|
1365
1367
|
tokens.push('WBTC');
|
|
1366
|
-
const tokenPrices = yield
|
|
1367
|
-
|
|
1368
|
+
const [tokenPrices, merklCampaigns] = yield Promise.all([
|
|
1369
|
+
getTokensPricesForPortfolio(tokens, provider, network),
|
|
1370
|
+
getFluidMerklCampaigns(network),
|
|
1371
|
+
]);
|
|
1372
|
+
const parsedMarketData = (yield Promise.all(data[1].map((vaultData) => __awaiter(void 0, void 0, void 0, function* () { return parseMarketData(provider, vaultData, network, tokenPrices); }))))
|
|
1373
|
+
.map(marketData => (marketData ? attachFluidMerklIncentives(marketData, merklCampaigns) : marketData));
|
|
1368
1374
|
const userData = data[0].map((position, i) => (parsedMarketData[i] && Object.assign({}, parseUserData(position, parsedMarketData[i]))));
|
|
1369
1375
|
return parsedMarketData.map((market, i) => ({
|
|
1370
1376
|
marketData: market,
|
package/esm/fluid/merkl.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import memoize from 'memoizee';
|
|
1
2
|
import { FluidMarketData, FluidMerklRewardMap, MerklOpportunity, NetworkNumber } from '../types';
|
|
2
3
|
/**
|
|
3
4
|
* Merkl tags Fluid vault-scoped reward campaigns via the opportunity `type` field:
|
|
@@ -13,14 +14,16 @@ import { FluidMarketData, FluidMerklRewardMap, MerklOpportunity, NetworkNumber }
|
|
|
13
14
|
* ids apply unconditionally, mirroring Aave V3. Whitelist-gated campaigns only accrue to
|
|
14
15
|
* whitelisted addresses, so they are skipped rather than advertised to every user.
|
|
15
16
|
*/
|
|
16
|
-
export declare
|
|
17
|
+
export declare enum FluidMerklOpportunityType {
|
|
18
|
+
Collateral = "FLUIDVAULT_COLLATERAL",
|
|
19
|
+
Borrow = "FLUIDVAULT_BORROW"
|
|
20
|
+
}
|
|
17
21
|
export declare const buildFluidMerklRewardMap: (opportunities: MerklOpportunity[], chainId: NetworkNumber) => FluidMerklRewardMap;
|
|
18
22
|
/**
|
|
19
23
|
* Fetches live vault-scoped Fluid campaigns for the chain, keyed by vault address. Never throws —
|
|
20
|
-
* on any failure it returns an empty map, so Merkl being down can't break market data.
|
|
21
|
-
* is narrowed by `type=` and capped at `items=100` because Merkl paginates at 20 items by default.
|
|
24
|
+
* on any failure it returns an empty map, so Merkl being down can't break market data.
|
|
22
25
|
*/
|
|
23
|
-
export declare const getFluidMerklCampaigns: (chainId: NetworkNumber) => Promise<FluidMerklRewardMap
|
|
26
|
+
export declare const getFluidMerklCampaigns: ((chainId: NetworkNumber) => Promise<FluidMerklRewardMap>) & memoize.Memoized<(chainId: NetworkNumber) => Promise<FluidMerklRewardMap>>;
|
|
24
27
|
/**
|
|
25
28
|
* Appends the vault's Merkl campaigns to its assets' incentive arrays — supply rewards on every
|
|
26
29
|
* suppliable asset and borrow rewards on every borrowable one. Smart collateral/debt vaults hold
|
package/esm/fluid/merkl.js
CHANGED
|
@@ -7,9 +7,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
import memoize from 'memoizee';
|
|
10
11
|
import { aprToApy } from '../moneymarket';
|
|
11
|
-
import {
|
|
12
|
-
import { IncentiveKind, OpportunityStatus, } from '../types';
|
|
12
|
+
import { fetchAllMerklOpportunities } from '../services/merkl';
|
|
13
|
+
import { IncentiveKind, IncentiveSource, OpportunityStatus, } from '../types';
|
|
13
14
|
/**
|
|
14
15
|
* Merkl tags Fluid vault-scoped reward campaigns via the opportunity `type` field:
|
|
15
16
|
* - FLUIDVAULT_COLLATERAL → reward for supplying collateral to the vault
|
|
@@ -24,7 +25,11 @@ import { IncentiveKind, OpportunityStatus, } from '../types';
|
|
|
24
25
|
* ids apply unconditionally, mirroring Aave V3. Whitelist-gated campaigns only accrue to
|
|
25
26
|
* whitelisted addresses, so they are skipped rather than advertised to every user.
|
|
26
27
|
*/
|
|
27
|
-
export
|
|
28
|
+
export var FluidMerklOpportunityType;
|
|
29
|
+
(function (FluidMerklOpportunityType) {
|
|
30
|
+
FluidMerklOpportunityType["Collateral"] = "FLUIDVAULT_COLLATERAL";
|
|
31
|
+
FluidMerklOpportunityType["Borrow"] = "FLUIDVAULT_BORROW";
|
|
32
|
+
})(FluidMerklOpportunityType || (FluidMerklOpportunityType = {}));
|
|
28
33
|
// '0x' + 20-byte vault address; conditional campaigns append a marker after it
|
|
29
34
|
const VAULT_ADDRESS_LENGTH = 42;
|
|
30
35
|
const buildMerklIncentive = (opportunity) => {
|
|
@@ -34,6 +39,7 @@ const buildMerklIncentive = (opportunity) => {
|
|
|
34
39
|
apy: aprToApy(opportunity.apr),
|
|
35
40
|
token,
|
|
36
41
|
incentiveKind: IncentiveKind.Reward,
|
|
42
|
+
source: IncentiveSource.Merkl,
|
|
37
43
|
description: `Eligible for ${token} rewards through Merkl.${opportunity.description ? `\n${opportunity.description}` : ''}`,
|
|
38
44
|
eligibilityId: opportunity.identifier,
|
|
39
45
|
};
|
|
@@ -43,7 +49,7 @@ export const buildFluidMerklRewardMap = (opportunities, chainId) => {
|
|
|
43
49
|
opportunities
|
|
44
50
|
.filter((o) => o.chainId === chainId)
|
|
45
51
|
.filter((o) => o.status === OpportunityStatus.LIVE)
|
|
46
|
-
.filter((o) =>
|
|
52
|
+
.filter((o) => Object.values(FluidMerklOpportunityType).includes(o.type))
|
|
47
53
|
.filter((o) => { var _a; return !((_a = o.identifier) === null || _a === void 0 ? void 0 : _a.includes('WHITELIST')); })
|
|
48
54
|
.forEach((o) => {
|
|
49
55
|
var _a;
|
|
@@ -52,30 +58,28 @@ export const buildFluidMerklRewardMap = (opportunities, chainId) => {
|
|
|
52
58
|
return;
|
|
53
59
|
if (!result[vaultAddress])
|
|
54
60
|
result[vaultAddress] = { supply: [], borrow: [] };
|
|
55
|
-
result[vaultAddress][o.type ===
|
|
61
|
+
result[vaultAddress][o.type === FluidMerklOpportunityType.Borrow ? 'borrow' : 'supply'].push(buildMerklIncentive(o));
|
|
56
62
|
});
|
|
57
63
|
return result;
|
|
58
64
|
};
|
|
59
65
|
/**
|
|
60
66
|
* Fetches live vault-scoped Fluid campaigns for the chain, keyed by vault address. Never throws —
|
|
61
|
-
* on any failure it returns an empty map, so Merkl being down can't break market data.
|
|
62
|
-
* is narrowed by `type=` and capped at `items=100` because Merkl paginates at 20 items by default.
|
|
67
|
+
* on any failure it returns an empty map, so Merkl being down can't break market data.
|
|
63
68
|
*/
|
|
64
|
-
export const getFluidMerklCampaigns = (chainId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
+
export const getFluidMerklCampaigns = memoize((chainId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
65
70
|
try {
|
|
66
|
-
const
|
|
67
|
-
|
|
71
|
+
const opportunities = yield fetchAllMerklOpportunities({
|
|
72
|
+
mainProtocolId: 'fluid',
|
|
73
|
+
type: Object.values(FluidMerklOpportunityType).join(','),
|
|
74
|
+
status: OpportunityStatus.LIVE,
|
|
68
75
|
});
|
|
69
|
-
|
|
70
|
-
throw new Error('Failed to fetch Fluid Merkl campaigns');
|
|
71
|
-
const opportunities = yield res.json();
|
|
72
|
-
return buildFluidMerklRewardMap(Array.isArray(opportunities) ? opportunities : [], chainId);
|
|
76
|
+
return buildFluidMerklRewardMap(opportunities, chainId);
|
|
73
77
|
}
|
|
74
78
|
catch (e) {
|
|
75
79
|
console.error('Failed to fetch Fluid Merkl campaigns', e);
|
|
76
80
|
return {};
|
|
77
81
|
}
|
|
78
|
-
});
|
|
82
|
+
}), { promise: true, maxAge: 60 * 1000 });
|
|
79
83
|
/**
|
|
80
84
|
* Appends the vault's Merkl campaigns to its assets' incentive arrays — supply rewards on every
|
|
81
85
|
* suppliable asset and borrow rewards on every borrowable one. Smart collateral/debt vaults hold
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { FluidAggregatedVaultData, FluidAssetData, FluidAssetsData, FluidDexBorrowDataStructOutput, FluidDexSupplyDataStructOutput, FluidUsedAsset, FluidUsedAssets, InnerFluidMarketData } from '../../types';
|
|
1
|
+
import { FluidAggregatedVaultData, FluidAssetData, FluidAssetsData, FluidDexBorrowDataStructOutput, FluidDexSupplyDataStructOutput, FluidUsedAsset, FluidUsedAssets, IncentiveData, InnerFluidMarketData } from '../../types';
|
|
2
|
+
import { IncentiveSide } from '../../types/common';
|
|
3
|
+
export declare const getUniqueFluidMerklIncentives: (assetsData: FluidAssetsData, side: IncentiveSide) => IncentiveData[];
|
|
2
4
|
export declare const getFluidAggregatedData: ({ usedAssets, assetsData, marketData, }: {
|
|
3
5
|
usedAssets: FluidUsedAssets;
|
|
4
6
|
marketData: InnerFluidMarketData;
|
|
@@ -1,17 +1,41 @@
|
|
|
1
1
|
import Dec from 'decimal.js';
|
|
2
2
|
import { assetAmountInEth } from '@defisaver/tokens';
|
|
3
|
-
import { FluidVaultType, } from '../../types';
|
|
3
|
+
import { FluidVaultType, IncentiveSource, } from '../../types';
|
|
4
4
|
import { calcLeverageLiqPrice, getAssetsTotal, getExposure, isLeveragedPos, } from '../../moneymarket';
|
|
5
|
-
import { calculateNetApy } from '../../staking';
|
|
6
|
-
import { LeverageType } from '../../types/common';
|
|
5
|
+
import { calculateInterestEarned, calculateNetApy, EligibilityMapping } from '../../staking';
|
|
6
|
+
import { IncentiveSide, LeverageType } from '../../types/common';
|
|
7
7
|
import { getEthAmountForDecimals } from '../../services/utils';
|
|
8
|
-
const
|
|
8
|
+
export const getUniqueFluidMerklIncentives = (assetsData, side) => {
|
|
9
|
+
const field = side === IncentiveSide.Supply ? 'supplyIncentives' : 'borrowIncentives';
|
|
10
|
+
const incentives = Object.values(assetsData)
|
|
11
|
+
.flatMap(asset => asset[field])
|
|
12
|
+
.filter(incentive => incentive.source === IncentiveSource.Merkl);
|
|
13
|
+
return [...new Map(incentives.map(incentive => [
|
|
14
|
+
[incentive.eligibilityId, incentive.token, incentive.apy, incentive.description].join('|'),
|
|
15
|
+
incentive,
|
|
16
|
+
])).values()];
|
|
17
|
+
};
|
|
18
|
+
const getMerklIncentiveInterest = (incentives, principal, usedAssets) => incentives.reduce((total, { apy, eligibilityId }) => {
|
|
19
|
+
const eligibilityCheck = eligibilityId ? EligibilityMapping[eligibilityId] : null;
|
|
20
|
+
const { isEligible, eligibleUSDAmount } = eligibilityCheck
|
|
21
|
+
? eligibilityCheck(usedAssets, undefined)
|
|
22
|
+
: { isEligible: true, eligibleUSDAmount: principal };
|
|
23
|
+
const incentiveInterest = isEligible ? calculateInterestEarned(eligibleUSDAmount, apy, 'year', true) : 0;
|
|
24
|
+
return new Dec(total).add(incentiveInterest).toString();
|
|
25
|
+
}, '0');
|
|
26
|
+
const calculateNetApyDex = ({ marketData, assetsData, usedAssets, suppliedUsd, borrowedUsd, }) => {
|
|
9
27
|
const { borrowRate, supplyRate, incentiveBorrowRate, incentiveSupplyRate, tradingBorrowRate, tradingSupplyRate, } = marketData;
|
|
10
28
|
const totalBorrowRate = new Dec(borrowRate).minus(tradingBorrowRate || '0').toString();
|
|
11
29
|
const totalSupplyRate = new Dec(supplyRate).add(tradingSupplyRate || '0').toString();
|
|
12
30
|
const borrowIncentive = new Dec(incentiveBorrowRate || '0').mul(borrowedUsd).div(100).toString();
|
|
13
31
|
const supplyIncentive = new Dec(incentiveSupplyRate || '0').mul(suppliedUsd).div(100).toString();
|
|
14
|
-
const
|
|
32
|
+
const merklSupplyIncentive = getMerklIncentiveInterest(getUniqueFluidMerklIncentives(assetsData, IncentiveSide.Supply), suppliedUsd, usedAssets);
|
|
33
|
+
const merklBorrowIncentive = getMerklIncentiveInterest(getUniqueFluidMerklIncentives(assetsData, IncentiveSide.Borrow), borrowedUsd, usedAssets);
|
|
34
|
+
const incentiveUsd = new Dec(supplyIncentive)
|
|
35
|
+
.minus(borrowIncentive)
|
|
36
|
+
.add(merklSupplyIncentive)
|
|
37
|
+
.add(merklBorrowIncentive)
|
|
38
|
+
.toString();
|
|
15
39
|
const borrowInterest = new Dec(totalBorrowRate).mul(borrowedUsd).div(100).toString();
|
|
16
40
|
const supplyInterest = new Dec(totalSupplyRate).mul(suppliedUsd).div(100).toString();
|
|
17
41
|
const totalInterestUsd = new Dec(supplyInterest).add(incentiveUsd).minus(borrowInterest).toString();
|
|
@@ -32,7 +56,15 @@ export const getFluidAggregatedData = ({ usedAssets, assetsData, marketData, },
|
|
|
32
56
|
? getAssetsTotal(usedAssets, ({ isBorrowed }) => isBorrowed, ({ borrowedUsd }) => borrowedUsd)
|
|
33
57
|
: new Dec(marketData.debtSharePrice).mul(borrowShares).toString();
|
|
34
58
|
const isDex = [FluidVaultType.T2, FluidVaultType.T3, FluidVaultType.T4].includes(marketData.vaultType);
|
|
35
|
-
|
|
59
|
+
payload.merklSupplyIncentives = getUniqueFluidMerklIncentives(assetsData, IncentiveSide.Supply);
|
|
60
|
+
payload.merklBorrowIncentives = getUniqueFluidMerklIncentives(assetsData, IncentiveSide.Borrow);
|
|
61
|
+
const { netApy, incentiveUsd, totalInterestUsd } = isDex ? calculateNetApyDex({
|
|
62
|
+
marketData,
|
|
63
|
+
assetsData,
|
|
64
|
+
usedAssets,
|
|
65
|
+
suppliedUsd: payload.suppliedUsd,
|
|
66
|
+
borrowedUsd: payload.borrowedUsd,
|
|
67
|
+
}) : calculateNetApy({ usedAssets, assetsData: assetsData });
|
|
36
68
|
payload.netApy = netApy;
|
|
37
69
|
payload.incentiveUsd = incentiveUsd;
|
|
38
70
|
payload.totalInterestUsd = totalInterestUsd;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Client } from 'viem';
|
|
2
2
|
import { Blockish, EthAddress, EthereumProvider, NetworkNumber, PositionBalances } from '../types/common';
|
|
3
3
|
import { MorphoBlueEarnData, MorphoBlueMarketData, MorphoBlueMarketInfo, MorphoBlueMarketRewards, MorphoBluePositionData } from '../types';
|
|
4
|
-
export {
|
|
4
|
+
export { MorphoBlueMerklOpportunityType, addMorphoBlueMerklOpportunitiesToMarketInfo, getMorphoBlueMerklOpportunities, addMorphoBlueMerklRewardsToMarketInfo, } from './merkl';
|
|
5
5
|
export declare const addMorphoBlueRewardsToMarketInfo: (marketInfo: MorphoBlueMarketInfo, rewards: MorphoBlueMarketRewards) => MorphoBlueMarketInfo;
|
|
6
6
|
export declare function _getMorphoBlueMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo>;
|
|
7
7
|
export declare function _getMorphoBluePortfolioMarketData(provider: Client, network: NetworkNumber, selectedMarket: MorphoBlueMarketData): Promise<MorphoBlueMarketInfo>;
|
package/esm/morphoBlue/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import { getBorrowRate, getMorphoBlueAggregatedPositionData, getRewardsForMarket
|
|
|
18
18
|
import { getChainlinkAssetAddress } from '../services/priceService';
|
|
19
19
|
import { getViemProvider, setViemBlockNumber } from '../services/viem';
|
|
20
20
|
import { addMorphoBlueMerklOpportunitiesToMarketInfo, getMorphoBlueMerklOpportunities } from './merkl';
|
|
21
|
-
export {
|
|
21
|
+
export { MorphoBlueMerklOpportunityType, addMorphoBlueMerklOpportunitiesToMarketInfo, getMorphoBlueMerklOpportunities, addMorphoBlueMerklRewardsToMarketInfo, } from './merkl';
|
|
22
22
|
const HARDCODED_USD_STABLE_PRICE = '100000000'; // $1 with 8 decimals
|
|
23
23
|
const getMorphoRewardIncentives = (apy) => [{
|
|
24
24
|
token: 'MORPHO',
|
|
@@ -12,7 +12,11 @@ import { MerklOpportunity, MorphoBlueMarketData, MorphoBlueMarketInfo, NetworkNu
|
|
|
12
12
|
* identifier (e.g. `0x54cf…c46WHITELIST_CAMPAIGN`); their rewards only accrue to whitelisted
|
|
13
13
|
* addresses, so they are skipped rather than advertised to every user.
|
|
14
14
|
*/
|
|
15
|
-
export declare
|
|
15
|
+
export declare enum MorphoBlueMerklOpportunityType {
|
|
16
|
+
Supply = "MORPHOSUPPLY",
|
|
17
|
+
Collateral = "MORPHOCOLLATERAL",
|
|
18
|
+
Borrow = "MORPHOBORROW"
|
|
19
|
+
}
|
|
16
20
|
/**
|
|
17
21
|
* Appends the given live Merkl campaigns for the market to its `assetsData` incentive arrays
|
|
18
22
|
* (collateral supply / loan supply / loan borrow). Existing Merkl incentives are replaced rather
|
|
@@ -21,9 +25,7 @@ export declare const MORPHO_BLUE_MERKL_OPPORTUNITY_TYPES: readonly ["MORPHOSUPPL
|
|
|
21
25
|
export declare const addMorphoBlueMerklOpportunitiesToMarketInfo: (marketInfo: MorphoBlueMarketInfo, selectedMarket: MorphoBlueMarketData, chainId: NetworkNumber, opportunities: MerklOpportunity[]) => MorphoBlueMarketInfo;
|
|
22
26
|
/**
|
|
23
27
|
* Fetches live market-scoped Morpho Blue campaigns for all chains. Never throws — on any failure
|
|
24
|
-
* it returns an empty list, so Merkl being down can't break market data.
|
|
25
|
-
* `type=` and capped at `items=100` because Merkl paginates at 20 items by default — an
|
|
26
|
-
* unfiltered protocol query would silently drop campaigns once Morpho has enough opportunities.
|
|
28
|
+
* it returns an empty list, so Merkl being down can't break market data.
|
|
27
29
|
*/
|
|
28
30
|
export declare const getMorphoBlueMerklOpportunities: () => Promise<MerklOpportunity[]>;
|
|
29
31
|
/**
|
package/esm/morphoBlue/merkl.js
CHANGED
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { aprToApy } from '../moneymarket';
|
|
11
|
-
import {
|
|
11
|
+
import { fetchAllMerklOpportunities } from '../services/merkl';
|
|
12
12
|
import { IncentiveKind, OpportunityStatus, } from '../types';
|
|
13
13
|
/**
|
|
14
14
|
* Merkl tags Morpho Blue market-level reward campaigns via the opportunity `type` field:
|
|
@@ -23,7 +23,12 @@ import { IncentiveKind, OpportunityStatus, } from '../types';
|
|
|
23
23
|
* identifier (e.g. `0x54cf…c46WHITELIST_CAMPAIGN`); their rewards only accrue to whitelisted
|
|
24
24
|
* addresses, so they are skipped rather than advertised to every user.
|
|
25
25
|
*/
|
|
26
|
-
export
|
|
26
|
+
export var MorphoBlueMerklOpportunityType;
|
|
27
|
+
(function (MorphoBlueMerklOpportunityType) {
|
|
28
|
+
MorphoBlueMerklOpportunityType["Supply"] = "MORPHOSUPPLY";
|
|
29
|
+
MorphoBlueMerklOpportunityType["Collateral"] = "MORPHOCOLLATERAL";
|
|
30
|
+
MorphoBlueMerklOpportunityType["Borrow"] = "MORPHOBORROW";
|
|
31
|
+
})(MorphoBlueMerklOpportunityType || (MorphoBlueMerklOpportunityType = {}));
|
|
27
32
|
const MERKL_DESCRIPTION_MARKER = 'through Merkl';
|
|
28
33
|
// '0x' + first 20 bytes of the market id
|
|
29
34
|
const MARKET_ID_PREFIX_LENGTH = 42;
|
|
@@ -54,7 +59,7 @@ export const addMorphoBlueMerklOpportunitiesToMarketInfo = (marketInfo, selected
|
|
|
54
59
|
var _a;
|
|
55
60
|
return o.chainId === chainId
|
|
56
61
|
&& o.status === OpportunityStatus.LIVE
|
|
57
|
-
&&
|
|
62
|
+
&& Object.values(MorphoBlueMerklOpportunityType).includes(o.type)
|
|
58
63
|
// a suffixed identifier marks a whitelist-gated campaign — skip those
|
|
59
64
|
&& ((_a = o.identifier) === null || _a === void 0 ? void 0 : _a.length) === MARKET_ID_PREFIX_LENGTH
|
|
60
65
|
&& o.identifier.toLowerCase() === marketIdPrefix;
|
|
@@ -62,26 +67,22 @@ export const addMorphoBlueMerklOpportunitiesToMarketInfo = (marketInfo, selected
|
|
|
62
67
|
if (!relevant.length)
|
|
63
68
|
return marketInfo;
|
|
64
69
|
const incentivesByType = (type) => relevant.filter((o) => o.type === type).map(buildMerklIncentive);
|
|
65
|
-
const collateralSupply = incentivesByType(
|
|
66
|
-
const loanSupply = incentivesByType(
|
|
67
|
-
const loanBorrow = incentivesByType(
|
|
70
|
+
const collateralSupply = incentivesByType(MorphoBlueMerklOpportunityType.Collateral);
|
|
71
|
+
const loanSupply = incentivesByType(MorphoBlueMerklOpportunityType.Supply);
|
|
72
|
+
const loanBorrow = incentivesByType(MorphoBlueMerklOpportunityType.Borrow);
|
|
68
73
|
return Object.assign(Object.assign({}, marketInfo), { assetsData: Object.assign(Object.assign({}, marketInfo.assetsData), { [marketInfo.collateralToken]: Object.assign(Object.assign({}, collateralAsset), { supplyIncentives: [...withoutMerklIncentives(collateralAsset.supplyIncentives), ...collateralSupply] }), [marketInfo.loanToken]: Object.assign(Object.assign({}, loanAsset), { supplyIncentives: [...withoutMerklIncentives(loanAsset.supplyIncentives), ...loanSupply], borrowIncentives: [...withoutMerklIncentives(loanAsset.borrowIncentives), ...loanBorrow] }) }) });
|
|
69
74
|
};
|
|
70
75
|
/**
|
|
71
76
|
* Fetches live market-scoped Morpho Blue campaigns for all chains. Never throws — on any failure
|
|
72
|
-
* it returns an empty list, so Merkl being down can't break market data.
|
|
73
|
-
* `type=` and capped at `items=100` because Merkl paginates at 20 items by default — an
|
|
74
|
-
* unfiltered protocol query would silently drop campaigns once Morpho has enough opportunities.
|
|
77
|
+
* it returns an empty list, so Merkl being down can't break market data.
|
|
75
78
|
*/
|
|
76
79
|
export const getMorphoBlueMerklOpportunities = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
77
80
|
try {
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
return yield fetchAllMerklOpportunities({
|
|
82
|
+
mainProtocolId: 'morpho',
|
|
83
|
+
type: Object.values(MorphoBlueMerklOpportunityType).join(','),
|
|
84
|
+
status: OpportunityStatus.LIVE,
|
|
80
85
|
});
|
|
81
|
-
if (!res.ok)
|
|
82
|
-
throw new Error('Failed to fetch Morpho Blue Merkl campaigns');
|
|
83
|
-
const data = yield res.json();
|
|
84
|
-
return Array.isArray(data) ? data : [];
|
|
85
86
|
}
|
|
86
87
|
catch (e) {
|
|
87
88
|
console.error('Failed to fetch Morpho Blue Merkl campaigns', e);
|