@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/aaveV3/merkl.js
CHANGED
|
@@ -11,6 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.getMerkleCampaigns = exports.formatAaveAsset = exports.getAaveUnderlyingSymbol = void 0;
|
|
13
13
|
const moneymarket_1 = require("../moneymarket");
|
|
14
|
+
const merkl_1 = require("../services/merkl");
|
|
14
15
|
const utils_1 = require("../services/utils");
|
|
15
16
|
const types_1 = require("../types");
|
|
16
17
|
const getAaveUnderlyingSymbol = (_symbol = '') => {
|
|
@@ -40,14 +41,10 @@ const formatAaveAsset = (_symbol) => {
|
|
|
40
41
|
exports.formatAaveAsset = formatAaveAsset;
|
|
41
42
|
const getMerkleCampaigns = (chainId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
42
43
|
try {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
signal: AbortSignal.timeout(utils_1.LONGER_TIMEOUT),
|
|
44
|
+
const opportunities = yield (0, merkl_1.fetchAllMerklOpportunities)({
|
|
45
|
+
mainProtocolId: 'aave',
|
|
46
|
+
status: types_1.OpportunityStatus.LIVE,
|
|
47
47
|
});
|
|
48
|
-
if (!res.ok)
|
|
49
|
-
throw new Error('Failed to fetch Merkle campaigns');
|
|
50
|
-
const opportunities = yield res.json();
|
|
51
48
|
const relevantOpportunities = opportunities
|
|
52
49
|
.filter((o) => o.chainId === chainId)
|
|
53
50
|
.filter((o) => o.status === types_1.OpportunityStatus.LIVE);
|
package/cjs/aaveV4/merkl.js
CHANGED
|
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.attachAaveV4MerklIncentives = exports.getAaveV4MerkleCampaigns = exports.buildAaveV4MerklRewardMap = void 0;
|
|
13
13
|
const moneymarket_1 = require("../moneymarket");
|
|
14
|
-
const
|
|
14
|
+
const merkl_1 = require("../services/merkl");
|
|
15
15
|
const types_1 = require("../types");
|
|
16
16
|
/**
|
|
17
17
|
* Merkl tags Aave V4 reward campaigns by scope via the `type` field:
|
|
@@ -67,12 +67,11 @@ const buildAaveV4MerklRewardMap = (opportunities, chainId) => {
|
|
|
67
67
|
exports.buildAaveV4MerklRewardMap = buildAaveV4MerklRewardMap;
|
|
68
68
|
const getAaveV4MerkleCampaigns = (chainId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
69
|
try {
|
|
70
|
-
const
|
|
71
|
-
|
|
70
|
+
const opportunities = yield (0, merkl_1.fetchAllMerklOpportunities)({
|
|
71
|
+
mainProtocolId: 'aave',
|
|
72
|
+
type: 'AAVE_V4_HUB_SUPPLY,AAVE_V4_HUB_BORROW,AAVE_V4_SPOKE_SUPPLY,AAVE_V4_SPOKE_BORROW',
|
|
73
|
+
status: types_1.OpportunityStatus.LIVE,
|
|
72
74
|
});
|
|
73
|
-
if (!res.ok)
|
|
74
|
-
throw new Error('Failed to fetch Aave V4 Merkle campaigns');
|
|
75
|
-
const opportunities = yield res.json();
|
|
76
75
|
return (0, exports.buildAaveV4MerklRewardMap)(opportunities, chainId);
|
|
77
76
|
}
|
|
78
77
|
catch (e) {
|
package/cjs/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/cjs/claiming/aaveV3.js
CHANGED
|
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.getUnclaimedRewardsForAllMarkets = getUnclaimedRewardsForAllMarkets;
|
|
16
|
+
exports.getMerklUnclaimedRewards = getMerklUnclaimedRewards;
|
|
16
17
|
exports.getMeritUnclaimedRewards = getMeritUnclaimedRewards;
|
|
17
18
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
18
19
|
const claiming_1 = require("../types/claiming");
|
|
@@ -95,7 +96,7 @@ function getUnclaimedRewardsForAllMarkets(provider, network, walletAddress, mark
|
|
|
95
96
|
return mapAaveRewardsToClaimableTokens(Object.values(totalUnclaimedPerRewardToken), marketAddress, walletAddress);
|
|
96
97
|
});
|
|
97
98
|
}
|
|
98
|
-
function
|
|
99
|
+
function getMerklUnclaimedRewards(account, network) {
|
|
99
100
|
return __awaiter(this, void 0, void 0, function* () {
|
|
100
101
|
let data;
|
|
101
102
|
try {
|
|
@@ -103,7 +104,7 @@ function getMeritUnclaimedRewards(account, network) {
|
|
|
103
104
|
data = yield res.json();
|
|
104
105
|
}
|
|
105
106
|
catch (error) {
|
|
106
|
-
console.error('External API Failure:
|
|
107
|
+
console.error('External API Failure: Merkl rewards', error);
|
|
107
108
|
data = [];
|
|
108
109
|
}
|
|
109
110
|
const claimableTokens = [];
|
|
@@ -121,12 +122,12 @@ function getMeritUnclaimedRewards(account, network) {
|
|
|
121
122
|
return;
|
|
122
123
|
const unclaimed = (0, utils_1.getEthAmountForDecimals)(unclaimedAmount, token.decimals);
|
|
123
124
|
claimableTokens.push({
|
|
124
|
-
claimType: claiming_1.ClaimType.
|
|
125
|
+
claimType: claiming_1.ClaimType.MERKL_REWARDS,
|
|
125
126
|
amount: unclaimed,
|
|
126
127
|
symbol: token.symbol,
|
|
127
128
|
tokenAddress: token.address,
|
|
128
129
|
walletAddress: account,
|
|
129
|
-
label: '
|
|
130
|
+
label: 'Merkl Rewards',
|
|
130
131
|
underlyingSymbol: (0, aaveHelpers_1.getAaveUnderlyingSymbol)(token.symbol),
|
|
131
132
|
additionalClaimFields: {
|
|
132
133
|
accumulated: amount,
|
|
@@ -140,3 +141,11 @@ function getMeritUnclaimedRewards(account, network) {
|
|
|
140
141
|
return claimableTokens;
|
|
141
142
|
});
|
|
142
143
|
}
|
|
144
|
+
function getMeritUnclaimedRewards(account, network) {
|
|
145
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
146
|
+
const rewards = yield getMerklUnclaimedRewards(account, network);
|
|
147
|
+
return rewards
|
|
148
|
+
.filter(reward => reward.symbol.startsWith('a'))
|
|
149
|
+
.map(reward => (Object.assign(Object.assign({}, reward), { claimType: claiming_1.ClaimType.AAVE_MERIT_REWARDS, label: 'AAVE Merit Rewards' })));
|
|
150
|
+
});
|
|
151
|
+
}
|
package/cjs/compoundV3/merkl.js
CHANGED
|
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
12
12
|
exports.attachCompoundV3MerklIncentives = exports.getCompoundV3MerklOpportunities = void 0;
|
|
13
13
|
const tokens_1 = require("@defisaver/tokens");
|
|
14
14
|
const moneymarket_1 = require("../moneymarket");
|
|
15
|
+
const merkl_1 = require("../services/merkl");
|
|
15
16
|
const utils_1 = require("../services/utils");
|
|
16
17
|
const types_1 = require("../types");
|
|
17
18
|
/**
|
|
@@ -24,13 +25,10 @@ const types_1 = require("../types");
|
|
|
24
25
|
*/
|
|
25
26
|
const getCompoundV3MerklOpportunities = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
27
|
try {
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
return yield (0, merkl_1.fetchAllMerklOpportunities)({
|
|
29
|
+
mainProtocolId: 'compound-v3',
|
|
30
|
+
status: types_1.OpportunityStatus.LIVE,
|
|
29
31
|
});
|
|
30
|
-
if (!res.ok)
|
|
31
|
-
throw new Error('Failed to fetch Compound V3 Merkl campaigns');
|
|
32
|
-
const data = yield res.json();
|
|
33
|
-
return Array.isArray(data) ? data : [];
|
|
34
32
|
}
|
|
35
33
|
catch (e) {
|
|
36
34
|
console.error('Failed to fetch Compound V3 Merkl campaigns', e);
|
package/cjs/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/cjs/fluid/index.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports._getUserPositionsPortfolio = exports.getUserPositions = exports._getUserPositions = exports.getAllUserEarnPositionsWithFTokens = exports._getAllUserEarnPositionsWithFTokens = exports.getFluidDepositData = exports._getFluidDepositData = exports.getFluidTokenData = exports._getFluidTokenData = exports.getAllFluidMarketDataChunked = exports._getAllFluidMarketDataChunked = exports.getFluidPositionWithMarket = exports._getFluidPositionWithMarket = exports.getFluidPosition = exports._getFluidPosition = exports.getFluidVaultIdsForUser = exports._getFluidVaultIdsForUser = exports.getFluidMarketData = exports._getFluidMarketData = exports.EMPTY_FLUID_DATA = exports.EMPTY_USED_ASSET = exports.attachFluidMerklIncentives = exports.getFluidMerklCampaigns = exports.buildFluidMerklRewardMap = exports.
|
|
15
|
+
exports._getUserPositionsPortfolio = exports.getUserPositions = exports._getUserPositions = exports.getAllUserEarnPositionsWithFTokens = exports._getAllUserEarnPositionsWithFTokens = exports.getFluidDepositData = exports._getFluidDepositData = exports.getFluidTokenData = exports._getFluidTokenData = exports.getAllFluidMarketDataChunked = exports._getAllFluidMarketDataChunked = exports.getFluidPositionWithMarket = exports._getFluidPositionWithMarket = exports.getFluidPosition = exports._getFluidPosition = exports.getFluidVaultIdsForUser = exports._getFluidVaultIdsForUser = exports.getFluidMarketData = exports._getFluidMarketData = exports.EMPTY_FLUID_DATA = exports.EMPTY_USED_ASSET = exports.attachFluidMerklIncentives = exports.getFluidMerklCampaigns = exports.buildFluidMerklRewardMap = exports.FluidMerklOpportunityType = void 0;
|
|
16
16
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
17
17
|
const tokens_1 = require("@defisaver/tokens");
|
|
18
18
|
const common_1 = require("../types/common");
|
|
@@ -27,7 +27,7 @@ const staking_1 = require("../staking");
|
|
|
27
27
|
const viem_1 = require("../services/viem");
|
|
28
28
|
const merkl_1 = require("./merkl");
|
|
29
29
|
var merkl_2 = require("./merkl");
|
|
30
|
-
Object.defineProperty(exports, "
|
|
30
|
+
Object.defineProperty(exports, "FluidMerklOpportunityType", { enumerable: true, get: function () { return merkl_2.FluidMerklOpportunityType; } });
|
|
31
31
|
Object.defineProperty(exports, "buildFluidMerklRewardMap", { enumerable: true, get: function () { return merkl_2.buildFluidMerklRewardMap; } });
|
|
32
32
|
Object.defineProperty(exports, "getFluidMerklCampaigns", { enumerable: true, get: function () { return merkl_2.getFluidMerklCampaigns; } });
|
|
33
33
|
Object.defineProperty(exports, "attachFluidMerklIncentives", { enumerable: true, get: function () { return merkl_2.attachFluidMerklIncentives; } });
|
|
@@ -922,6 +922,8 @@ exports.EMPTY_FLUID_DATA = {
|
|
|
922
922
|
minRatio: '0',
|
|
923
923
|
netApy: '0',
|
|
924
924
|
incentiveUsd: '0',
|
|
925
|
+
merklSupplyIncentives: [],
|
|
926
|
+
merklBorrowIncentives: [],
|
|
925
927
|
totalInterestUsd: '0',
|
|
926
928
|
isSubscribedToAutomation: false,
|
|
927
929
|
automationResubscribeRequired: false,
|
|
@@ -1391,8 +1393,12 @@ const _getUserPositionsPortfolio = (provider, network, user) => __awaiter(void 0
|
|
|
1391
1393
|
tokens.push('ETH');
|
|
1392
1394
|
if (!tokens.includes('WBTC'))
|
|
1393
1395
|
tokens.push('WBTC');
|
|
1394
|
-
const tokenPrices = yield
|
|
1395
|
-
|
|
1396
|
+
const [tokenPrices, merklCampaigns] = yield Promise.all([
|
|
1397
|
+
getTokensPricesForPortfolio(tokens, provider, network),
|
|
1398
|
+
(0, merkl_1.getFluidMerklCampaigns)(network),
|
|
1399
|
+
]);
|
|
1400
|
+
const parsedMarketData = (yield Promise.all(data[1].map((vaultData) => __awaiter(void 0, void 0, void 0, function* () { return parseMarketData(provider, vaultData, network, tokenPrices); }))))
|
|
1401
|
+
.map(marketData => (marketData ? (0, merkl_1.attachFluidMerklIncentives)(marketData, merklCampaigns) : marketData));
|
|
1396
1402
|
const userData = data[0].map((position, i) => (parsedMarketData[i] && Object.assign({}, parseUserData(position, parsedMarketData[i]))));
|
|
1397
1403
|
return parsedMarketData.map((market, i) => ({
|
|
1398
1404
|
marketData: market,
|
package/cjs/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/cjs/fluid/merkl.js
CHANGED
|
@@ -8,10 +8,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.attachFluidMerklIncentives = exports.getFluidMerklCampaigns = exports.buildFluidMerklRewardMap = exports.
|
|
15
|
+
exports.attachFluidMerklIncentives = exports.getFluidMerklCampaigns = exports.buildFluidMerklRewardMap = exports.FluidMerklOpportunityType = void 0;
|
|
16
|
+
const memoizee_1 = __importDefault(require("memoizee"));
|
|
13
17
|
const moneymarket_1 = require("../moneymarket");
|
|
14
|
-
const
|
|
18
|
+
const merkl_1 = require("../services/merkl");
|
|
15
19
|
const types_1 = require("../types");
|
|
16
20
|
/**
|
|
17
21
|
* Merkl tags Fluid vault-scoped reward campaigns via the opportunity `type` field:
|
|
@@ -27,7 +31,11 @@ const types_1 = require("../types");
|
|
|
27
31
|
* ids apply unconditionally, mirroring Aave V3. Whitelist-gated campaigns only accrue to
|
|
28
32
|
* whitelisted addresses, so they are skipped rather than advertised to every user.
|
|
29
33
|
*/
|
|
30
|
-
|
|
34
|
+
var FluidMerklOpportunityType;
|
|
35
|
+
(function (FluidMerklOpportunityType) {
|
|
36
|
+
FluidMerklOpportunityType["Collateral"] = "FLUIDVAULT_COLLATERAL";
|
|
37
|
+
FluidMerklOpportunityType["Borrow"] = "FLUIDVAULT_BORROW";
|
|
38
|
+
})(FluidMerklOpportunityType || (exports.FluidMerklOpportunityType = FluidMerklOpportunityType = {}));
|
|
31
39
|
// '0x' + 20-byte vault address; conditional campaigns append a marker after it
|
|
32
40
|
const VAULT_ADDRESS_LENGTH = 42;
|
|
33
41
|
const buildMerklIncentive = (opportunity) => {
|
|
@@ -37,6 +45,7 @@ const buildMerklIncentive = (opportunity) => {
|
|
|
37
45
|
apy: (0, moneymarket_1.aprToApy)(opportunity.apr),
|
|
38
46
|
token,
|
|
39
47
|
incentiveKind: types_1.IncentiveKind.Reward,
|
|
48
|
+
source: types_1.IncentiveSource.Merkl,
|
|
40
49
|
description: `Eligible for ${token} rewards through Merkl.${opportunity.description ? `\n${opportunity.description}` : ''}`,
|
|
41
50
|
eligibilityId: opportunity.identifier,
|
|
42
51
|
};
|
|
@@ -46,7 +55,7 @@ const buildFluidMerklRewardMap = (opportunities, chainId) => {
|
|
|
46
55
|
opportunities
|
|
47
56
|
.filter((o) => o.chainId === chainId)
|
|
48
57
|
.filter((o) => o.status === types_1.OpportunityStatus.LIVE)
|
|
49
|
-
.filter((o) =>
|
|
58
|
+
.filter((o) => Object.values(FluidMerklOpportunityType).includes(o.type))
|
|
50
59
|
.filter((o) => { var _a; return !((_a = o.identifier) === null || _a === void 0 ? void 0 : _a.includes('WHITELIST')); })
|
|
51
60
|
.forEach((o) => {
|
|
52
61
|
var _a;
|
|
@@ -55,32 +64,29 @@ const buildFluidMerklRewardMap = (opportunities, chainId) => {
|
|
|
55
64
|
return;
|
|
56
65
|
if (!result[vaultAddress])
|
|
57
66
|
result[vaultAddress] = { supply: [], borrow: [] };
|
|
58
|
-
result[vaultAddress][o.type ===
|
|
67
|
+
result[vaultAddress][o.type === FluidMerklOpportunityType.Borrow ? 'borrow' : 'supply'].push(buildMerklIncentive(o));
|
|
59
68
|
});
|
|
60
69
|
return result;
|
|
61
70
|
};
|
|
62
71
|
exports.buildFluidMerklRewardMap = buildFluidMerklRewardMap;
|
|
63
72
|
/**
|
|
64
73
|
* Fetches live vault-scoped Fluid campaigns for the chain, keyed by vault address. Never throws —
|
|
65
|
-
* on any failure it returns an empty map, so Merkl being down can't break market data.
|
|
66
|
-
* is narrowed by `type=` and capped at `items=100` because Merkl paginates at 20 items by default.
|
|
74
|
+
* on any failure it returns an empty map, so Merkl being down can't break market data.
|
|
67
75
|
*/
|
|
68
|
-
|
|
76
|
+
exports.getFluidMerklCampaigns = (0, memoizee_1.default)((chainId) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
77
|
try {
|
|
70
|
-
const
|
|
71
|
-
|
|
78
|
+
const opportunities = yield (0, merkl_1.fetchAllMerklOpportunities)({
|
|
79
|
+
mainProtocolId: 'fluid',
|
|
80
|
+
type: Object.values(FluidMerklOpportunityType).join(','),
|
|
81
|
+
status: types_1.OpportunityStatus.LIVE,
|
|
72
82
|
});
|
|
73
|
-
|
|
74
|
-
throw new Error('Failed to fetch Fluid Merkl campaigns');
|
|
75
|
-
const opportunities = yield res.json();
|
|
76
|
-
return (0, exports.buildFluidMerklRewardMap)(Array.isArray(opportunities) ? opportunities : [], chainId);
|
|
83
|
+
return (0, exports.buildFluidMerklRewardMap)(opportunities, chainId);
|
|
77
84
|
}
|
|
78
85
|
catch (e) {
|
|
79
86
|
console.error('Failed to fetch Fluid Merkl campaigns', e);
|
|
80
87
|
return {};
|
|
81
88
|
}
|
|
82
|
-
});
|
|
83
|
-
exports.getFluidMerklCampaigns = getFluidMerklCampaigns;
|
|
89
|
+
}), { promise: true, maxAge: 60 * 1000 });
|
|
84
90
|
/**
|
|
85
91
|
* Appends the vault's Merkl campaigns to its assets' incentive arrays — supply rewards on every
|
|
86
92
|
* 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;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.mergeUsedAssets = exports.EMPTY_USED_ASSET = exports.mergeAssetData = exports.parseDexBorrowData = exports.parseDexSupplyData = exports.getFluidAggregatedData = void 0;
|
|
6
|
+
exports.mergeUsedAssets = exports.EMPTY_USED_ASSET = exports.mergeAssetData = exports.parseDexBorrowData = exports.parseDexSupplyData = exports.getFluidAggregatedData = exports.getUniqueFluidMerklIncentives = void 0;
|
|
7
7
|
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
8
8
|
const tokens_1 = require("@defisaver/tokens");
|
|
9
9
|
const types_1 = require("../../types");
|
|
@@ -11,13 +11,38 @@ const moneymarket_1 = require("../../moneymarket");
|
|
|
11
11
|
const staking_1 = require("../../staking");
|
|
12
12
|
const common_1 = require("../../types/common");
|
|
13
13
|
const utils_1 = require("../../services/utils");
|
|
14
|
-
const
|
|
14
|
+
const getUniqueFluidMerklIncentives = (assetsData, side) => {
|
|
15
|
+
const field = side === common_1.IncentiveSide.Supply ? 'supplyIncentives' : 'borrowIncentives';
|
|
16
|
+
const incentives = Object.values(assetsData)
|
|
17
|
+
.flatMap(asset => asset[field])
|
|
18
|
+
.filter(incentive => incentive.source === types_1.IncentiveSource.Merkl);
|
|
19
|
+
return [...new Map(incentives.map(incentive => [
|
|
20
|
+
[incentive.eligibilityId, incentive.token, incentive.apy, incentive.description].join('|'),
|
|
21
|
+
incentive,
|
|
22
|
+
])).values()];
|
|
23
|
+
};
|
|
24
|
+
exports.getUniqueFluidMerklIncentives = getUniqueFluidMerklIncentives;
|
|
25
|
+
const getMerklIncentiveInterest = (incentives, principal, usedAssets) => incentives.reduce((total, { apy, eligibilityId }) => {
|
|
26
|
+
const eligibilityCheck = eligibilityId ? staking_1.EligibilityMapping[eligibilityId] : null;
|
|
27
|
+
const { isEligible, eligibleUSDAmount } = eligibilityCheck
|
|
28
|
+
? eligibilityCheck(usedAssets, undefined)
|
|
29
|
+
: { isEligible: true, eligibleUSDAmount: principal };
|
|
30
|
+
const incentiveInterest = isEligible ? (0, staking_1.calculateInterestEarned)(eligibleUSDAmount, apy, 'year', true) : 0;
|
|
31
|
+
return new decimal_js_1.default(total).add(incentiveInterest).toString();
|
|
32
|
+
}, '0');
|
|
33
|
+
const calculateNetApyDex = ({ marketData, assetsData, usedAssets, suppliedUsd, borrowedUsd, }) => {
|
|
15
34
|
const { borrowRate, supplyRate, incentiveBorrowRate, incentiveSupplyRate, tradingBorrowRate, tradingSupplyRate, } = marketData;
|
|
16
35
|
const totalBorrowRate = new decimal_js_1.default(borrowRate).minus(tradingBorrowRate || '0').toString();
|
|
17
36
|
const totalSupplyRate = new decimal_js_1.default(supplyRate).add(tradingSupplyRate || '0').toString();
|
|
18
37
|
const borrowIncentive = new decimal_js_1.default(incentiveBorrowRate || '0').mul(borrowedUsd).div(100).toString();
|
|
19
38
|
const supplyIncentive = new decimal_js_1.default(incentiveSupplyRate || '0').mul(suppliedUsd).div(100).toString();
|
|
20
|
-
const
|
|
39
|
+
const merklSupplyIncentive = getMerklIncentiveInterest((0, exports.getUniqueFluidMerklIncentives)(assetsData, common_1.IncentiveSide.Supply), suppliedUsd, usedAssets);
|
|
40
|
+
const merklBorrowIncentive = getMerklIncentiveInterest((0, exports.getUniqueFluidMerklIncentives)(assetsData, common_1.IncentiveSide.Borrow), borrowedUsd, usedAssets);
|
|
41
|
+
const incentiveUsd = new decimal_js_1.default(supplyIncentive)
|
|
42
|
+
.minus(borrowIncentive)
|
|
43
|
+
.add(merklSupplyIncentive)
|
|
44
|
+
.add(merklBorrowIncentive)
|
|
45
|
+
.toString();
|
|
21
46
|
const borrowInterest = new decimal_js_1.default(totalBorrowRate).mul(borrowedUsd).div(100).toString();
|
|
22
47
|
const supplyInterest = new decimal_js_1.default(totalSupplyRate).mul(suppliedUsd).div(100).toString();
|
|
23
48
|
const totalInterestUsd = new decimal_js_1.default(supplyInterest).add(incentiveUsd).minus(borrowInterest).toString();
|
|
@@ -38,7 +63,15 @@ const getFluidAggregatedData = ({ usedAssets, assetsData, marketData, }, supplyS
|
|
|
38
63
|
? (0, moneymarket_1.getAssetsTotal)(usedAssets, ({ isBorrowed }) => isBorrowed, ({ borrowedUsd }) => borrowedUsd)
|
|
39
64
|
: new decimal_js_1.default(marketData.debtSharePrice).mul(borrowShares).toString();
|
|
40
65
|
const isDex = [types_1.FluidVaultType.T2, types_1.FluidVaultType.T3, types_1.FluidVaultType.T4].includes(marketData.vaultType);
|
|
41
|
-
|
|
66
|
+
payload.merklSupplyIncentives = (0, exports.getUniqueFluidMerklIncentives)(assetsData, common_1.IncentiveSide.Supply);
|
|
67
|
+
payload.merklBorrowIncentives = (0, exports.getUniqueFluidMerklIncentives)(assetsData, common_1.IncentiveSide.Borrow);
|
|
68
|
+
const { netApy, incentiveUsd, totalInterestUsd } = isDex ? calculateNetApyDex({
|
|
69
|
+
marketData,
|
|
70
|
+
assetsData,
|
|
71
|
+
usedAssets,
|
|
72
|
+
suppliedUsd: payload.suppliedUsd,
|
|
73
|
+
borrowedUsd: payload.borrowedUsd,
|
|
74
|
+
}) : (0, staking_1.calculateNetApy)({ usedAssets, assetsData: assetsData });
|
|
42
75
|
payload.netApy = netApy;
|
|
43
76
|
payload.incentiveUsd = incentiveUsd;
|
|
44
77
|
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/cjs/morphoBlue/index.js
CHANGED
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.getMorphoBlueAccountBalances = exports._getMorphoBlueAccountBalances = exports.getMorphoEarnDataWithMarketInfo = exports.getMorphoBluePositionDataWithMarketInfo = exports.addMorphoBlueRewardsToMarketInfo = exports.addMorphoBlueMerklRewardsToMarketInfo = exports.getMorphoBlueMerklOpportunities = exports.addMorphoBlueMerklOpportunitiesToMarketInfo = exports.
|
|
15
|
+
exports.getMorphoBlueAccountBalances = exports._getMorphoBlueAccountBalances = exports.getMorphoEarnDataWithMarketInfo = exports.getMorphoBluePositionDataWithMarketInfo = exports.addMorphoBlueRewardsToMarketInfo = exports.addMorphoBlueMerklRewardsToMarketInfo = exports.getMorphoBlueMerklOpportunities = exports.addMorphoBlueMerklOpportunitiesToMarketInfo = exports.MorphoBlueMerklOpportunityType = void 0;
|
|
16
16
|
exports._getMorphoBlueMarketData = _getMorphoBlueMarketData;
|
|
17
17
|
exports._getMorphoBluePortfolioMarketData = _getMorphoBluePortfolioMarketData;
|
|
18
18
|
exports.getMorphoBlueMarketData = getMorphoBlueMarketData;
|
|
@@ -33,7 +33,7 @@ const priceService_1 = require("../services/priceService");
|
|
|
33
33
|
const viem_1 = require("../services/viem");
|
|
34
34
|
const merkl_1 = require("./merkl");
|
|
35
35
|
var merkl_2 = require("./merkl");
|
|
36
|
-
Object.defineProperty(exports, "
|
|
36
|
+
Object.defineProperty(exports, "MorphoBlueMerklOpportunityType", { enumerable: true, get: function () { return merkl_2.MorphoBlueMerklOpportunityType; } });
|
|
37
37
|
Object.defineProperty(exports, "addMorphoBlueMerklOpportunitiesToMarketInfo", { enumerable: true, get: function () { return merkl_2.addMorphoBlueMerklOpportunitiesToMarketInfo; } });
|
|
38
38
|
Object.defineProperty(exports, "getMorphoBlueMerklOpportunities", { enumerable: true, get: function () { return merkl_2.getMorphoBlueMerklOpportunities; } });
|
|
39
39
|
Object.defineProperty(exports, "addMorphoBlueMerklRewardsToMarketInfo", { enumerable: true, get: function () { return merkl_2.addMorphoBlueMerklRewardsToMarketInfo; } });
|
|
@@ -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/cjs/morphoBlue/merkl.js
CHANGED
|
@@ -9,9 +9,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.addMorphoBlueMerklRewardsToMarketInfo = exports.getMorphoBlueMerklOpportunities = exports.addMorphoBlueMerklOpportunitiesToMarketInfo = exports.
|
|
12
|
+
exports.addMorphoBlueMerklRewardsToMarketInfo = exports.getMorphoBlueMerklOpportunities = exports.addMorphoBlueMerklOpportunitiesToMarketInfo = exports.MorphoBlueMerklOpportunityType = void 0;
|
|
13
13
|
const moneymarket_1 = require("../moneymarket");
|
|
14
|
-
const
|
|
14
|
+
const merkl_1 = require("../services/merkl");
|
|
15
15
|
const types_1 = require("../types");
|
|
16
16
|
/**
|
|
17
17
|
* Merkl tags Morpho Blue market-level reward campaigns via the opportunity `type` field:
|
|
@@ -26,7 +26,12 @@ const types_1 = require("../types");
|
|
|
26
26
|
* identifier (e.g. `0x54cf…c46WHITELIST_CAMPAIGN`); their rewards only accrue to whitelisted
|
|
27
27
|
* addresses, so they are skipped rather than advertised to every user.
|
|
28
28
|
*/
|
|
29
|
-
|
|
29
|
+
var MorphoBlueMerklOpportunityType;
|
|
30
|
+
(function (MorphoBlueMerklOpportunityType) {
|
|
31
|
+
MorphoBlueMerklOpportunityType["Supply"] = "MORPHOSUPPLY";
|
|
32
|
+
MorphoBlueMerklOpportunityType["Collateral"] = "MORPHOCOLLATERAL";
|
|
33
|
+
MorphoBlueMerklOpportunityType["Borrow"] = "MORPHOBORROW";
|
|
34
|
+
})(MorphoBlueMerklOpportunityType || (exports.MorphoBlueMerklOpportunityType = MorphoBlueMerklOpportunityType = {}));
|
|
30
35
|
const MERKL_DESCRIPTION_MARKER = 'through Merkl';
|
|
31
36
|
// '0x' + first 20 bytes of the market id
|
|
32
37
|
const MARKET_ID_PREFIX_LENGTH = 42;
|
|
@@ -57,7 +62,7 @@ const addMorphoBlueMerklOpportunitiesToMarketInfo = (marketInfo, selectedMarket,
|
|
|
57
62
|
var _a;
|
|
58
63
|
return o.chainId === chainId
|
|
59
64
|
&& o.status === types_1.OpportunityStatus.LIVE
|
|
60
|
-
&&
|
|
65
|
+
&& Object.values(MorphoBlueMerklOpportunityType).includes(o.type)
|
|
61
66
|
// a suffixed identifier marks a whitelist-gated campaign — skip those
|
|
62
67
|
&& ((_a = o.identifier) === null || _a === void 0 ? void 0 : _a.length) === MARKET_ID_PREFIX_LENGTH
|
|
63
68
|
&& o.identifier.toLowerCase() === marketIdPrefix;
|
|
@@ -65,27 +70,23 @@ const addMorphoBlueMerklOpportunitiesToMarketInfo = (marketInfo, selectedMarket,
|
|
|
65
70
|
if (!relevant.length)
|
|
66
71
|
return marketInfo;
|
|
67
72
|
const incentivesByType = (type) => relevant.filter((o) => o.type === type).map(buildMerklIncentive);
|
|
68
|
-
const collateralSupply = incentivesByType(
|
|
69
|
-
const loanSupply = incentivesByType(
|
|
70
|
-
const loanBorrow = incentivesByType(
|
|
73
|
+
const collateralSupply = incentivesByType(MorphoBlueMerklOpportunityType.Collateral);
|
|
74
|
+
const loanSupply = incentivesByType(MorphoBlueMerklOpportunityType.Supply);
|
|
75
|
+
const loanBorrow = incentivesByType(MorphoBlueMerklOpportunityType.Borrow);
|
|
71
76
|
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] }) }) });
|
|
72
77
|
};
|
|
73
78
|
exports.addMorphoBlueMerklOpportunitiesToMarketInfo = addMorphoBlueMerklOpportunitiesToMarketInfo;
|
|
74
79
|
/**
|
|
75
80
|
* Fetches live market-scoped Morpho Blue campaigns for all chains. Never throws — on any failure
|
|
76
|
-
* it returns an empty list, so Merkl being down can't break market data.
|
|
77
|
-
* `type=` and capped at `items=100` because Merkl paginates at 20 items by default — an
|
|
78
|
-
* unfiltered protocol query would silently drop campaigns once Morpho has enough opportunities.
|
|
81
|
+
* it returns an empty list, so Merkl being down can't break market data.
|
|
79
82
|
*/
|
|
80
83
|
const getMorphoBlueMerklOpportunities = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
81
84
|
try {
|
|
82
|
-
|
|
83
|
-
|
|
85
|
+
return yield (0, merkl_1.fetchAllMerklOpportunities)({
|
|
86
|
+
mainProtocolId: 'morpho',
|
|
87
|
+
type: Object.values(MorphoBlueMerklOpportunityType).join(','),
|
|
88
|
+
status: types_1.OpportunityStatus.LIVE,
|
|
84
89
|
});
|
|
85
|
-
if (!res.ok)
|
|
86
|
-
throw new Error('Failed to fetch Morpho Blue Merkl campaigns');
|
|
87
|
-
const data = yield res.json();
|
|
88
|
-
return Array.isArray(data) ? data : [];
|
|
89
90
|
}
|
|
90
91
|
catch (e) {
|
|
91
92
|
console.error('Failed to fetch Morpho Blue Merkl campaigns', e);
|
package/cjs/portfolio/index.js
CHANGED
|
@@ -134,7 +134,7 @@ function getPortfolioData(provider_1, network_1, defaultProvider_1, addresses_1)
|
|
|
134
134
|
},
|
|
135
135
|
};
|
|
136
136
|
rewardsData[address.toLowerCase()] = {
|
|
137
|
-
|
|
137
|
+
merkl: {},
|
|
138
138
|
aaveV3: {},
|
|
139
139
|
compV3: {},
|
|
140
140
|
spark: {},
|
|
@@ -355,12 +355,12 @@ function getPortfolioData(provider_1, network_1, defaultProvider_1, addresses_1)
|
|
|
355
355
|
}))).flat(),
|
|
356
356
|
...addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
|
|
357
357
|
try {
|
|
358
|
-
const
|
|
359
|
-
rewardsData[address.toLowerCase()].
|
|
358
|
+
const merklData = yield (0, aaveV3_2.getMerklUnclaimedRewards)(address, network);
|
|
359
|
+
rewardsData[address.toLowerCase()].merkl = { error: '', data: merklData };
|
|
360
360
|
}
|
|
361
361
|
catch (error) {
|
|
362
|
-
console.error(`Error fetching
|
|
363
|
-
rewardsData[address.toLowerCase()].
|
|
362
|
+
console.error(`Error fetching Merkl rewards data for address ${address}:`, error);
|
|
363
|
+
rewardsData[address.toLowerCase()].merkl = { error: `Error fetching Merkl rewards data for address ${address}`, data: null };
|
|
364
364
|
}
|
|
365
365
|
})),
|
|
366
366
|
...aaveV3Markets.map(market => addresses.map((address) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { MerklOpportunity } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Fetches every page matching the query. Merkl returns 20 opportunities by default, so omitting
|
|
4
|
+
* `items` and advancing `page` avoids imposing a client-side maximum on the result set.
|
|
5
|
+
*/
|
|
6
|
+
export declare const fetchAllMerklOpportunities: (query: Record<string, string>) => Promise<MerklOpportunity[]>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.fetchAllMerklOpportunities = void 0;
|
|
13
|
+
const utils_1 = require("./utils");
|
|
14
|
+
const MERKL_OPPORTUNITIES_URL = 'https://fe.defisaver.com/api/merkl/opportunities';
|
|
15
|
+
/**
|
|
16
|
+
* Fetches every page matching the query. Merkl returns 20 opportunities by default, so omitting
|
|
17
|
+
* `items` and advancing `page` avoids imposing a client-side maximum on the result set.
|
|
18
|
+
*/
|
|
19
|
+
const fetchAllMerklOpportunities = (query) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
const opportunities = [];
|
|
21
|
+
let page = 0;
|
|
22
|
+
let pageOpportunities;
|
|
23
|
+
do {
|
|
24
|
+
const searchParams = new URLSearchParams(Object.assign(Object.assign({}, query), { page: page.toString() }));
|
|
25
|
+
const res = yield fetch(`${MERKL_OPPORTUNITIES_URL}?${searchParams}`, {
|
|
26
|
+
signal: AbortSignal.timeout(utils_1.LONGER_TIMEOUT),
|
|
27
|
+
});
|
|
28
|
+
if (!res.ok)
|
|
29
|
+
throw new Error(`Failed to fetch Merkl opportunities page ${page}`);
|
|
30
|
+
const data = yield res.json(); // eslint-disable-line no-await-in-loop
|
|
31
|
+
if (!Array.isArray(data))
|
|
32
|
+
throw new Error(`Invalid Merkl opportunities response on page ${page}`);
|
|
33
|
+
pageOpportunities = data;
|
|
34
|
+
opportunities.push(...pageOpportunities);
|
|
35
|
+
page += 1;
|
|
36
|
+
} while (pageOpportunities.length > 0);
|
|
37
|
+
return opportunities;
|
|
38
|
+
});
|
|
39
|
+
exports.fetchAllMerklOpportunities = fetchAllMerklOpportunities;
|