@merkl/api 0.15.49 → 0.16.1
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/dist/src/backgroundJobs/jobs/campaignsCacheUpdater.d.ts +4 -1
- package/dist/src/backgroundJobs/jobs/campaignsCacheUpdater.js +12 -8
- package/dist/src/constants.d.ts +13 -259
- package/dist/src/eden/index.d.ts +65 -10
- package/dist/src/index.d.ts +13 -2
- package/dist/src/jobs/etl/dynamic-data.d.ts +1 -1
- package/dist/src/jobs/etl/dynamic-data.js +4 -145
- package/dist/src/modules/v4/enso/enso.service.d.ts +5 -1
- package/dist/src/modules/v4/interaction/interaction.controller.d.ts +5 -1
- package/dist/src/modules/v4/protocol/protocol.controller.d.ts +8 -1
- package/dist/src/modules/v4/protocol/protocol.model.d.ts +5 -5
- package/dist/src/modules/v4/protocol/protocol.service.d.ts +2 -2
- package/dist/src/modules/v4/protocol/protocol.service.js +1 -0
- package/dist/src/modules/v4/router.d.ts +13 -2
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
@@ -1,22 +1,7 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import { AprService, CampaignService, OpportunityService } from "../../modules/v4";
|
4
|
-
import { CacheService } from "../../modules/v4/cache";
|
5
|
-
import { TTLPresets } from "../../modules/v4/cache/cache.model";
|
6
|
-
import { OpportunityRepository } from "../../modules/v4/opportunity/opportunity.repository";
|
7
|
-
import { RewardService } from "../../modules/v4/reward";
|
8
|
-
import { TvlService } from "../../modules/v4/tvl";
|
9
|
-
import { engineDbClient } from "../../utils/prisma";
|
10
|
-
import { Campaign, ChainId, NETWORK_LABELS, isSupportedChain, } from "@sdk";
|
11
|
-
import moment from "moment";
|
12
|
-
import { campaignsDynamicData } from "../../libs/campaigns/campaignsDynamicData";
|
13
|
-
import { merklChainData } from "../../libs/merklChainData";
|
14
|
-
import { staticCampaignWithCache } from "../../libs/staticCampaigns";
|
1
|
+
import { campaignCacheUpdate } from "../../backgroundJobs/jobs/campaignsCacheUpdater";
|
2
|
+
import { ChainId, isSupportedChain } from "@sdk";
|
15
3
|
import { InvalidParameter, UnsupportedNetwork } from "../../utils/error";
|
16
|
-
|
17
|
-
import { log } from "../../utils/logger";
|
18
|
-
import { ALL_CAMPAIGNS_FOR_CHAIN_AFTER } from "../../utils/queries/allCampaigns";
|
19
|
-
let campaignTypes = process.env.CAMPAIGN_TYPES ? JSON.parse(process.env.CAMPAIGN_TYPES) : [];
|
4
|
+
const campaignTypes = process.env.CAMPAIGN_TYPES ? JSON.parse(process.env.CAMPAIGN_TYPES) : [];
|
20
5
|
const highCampaignsChains = [ChainId.ARBITRUM, ChainId.POLYGON, ChainId.BLAST, ChainId.BASE];
|
21
6
|
export const main = async () => {
|
22
7
|
const rawChainId = process.env.CHAIN_ID;
|
@@ -29,133 +14,7 @@ export const main = async () => {
|
|
29
14
|
else {
|
30
15
|
throw new InvalidParameter("Invalid chainId provided");
|
31
16
|
}
|
32
|
-
|
33
|
-
try {
|
34
|
-
await Redis.safeSet(`MerklChainData_${chainId}`, await merklChainData(chainId));
|
35
|
-
}
|
36
|
-
catch (error) {
|
37
|
-
log.error(`❌ update merklChainData cache failed for ${NETWORK_LABELS[chainId]}`, error);
|
38
|
-
success = false;
|
39
|
-
}
|
40
|
-
log.local(`🔁 updating ${NETWORK_LABELS[chainId]} Campaigns cache`);
|
41
|
-
let campaignsAfter = moment().subtract(3, "months").unix();
|
42
|
-
if (highCampaignsChains.includes(chainId)) {
|
43
|
-
campaignsAfter = moment().subtract(1, "months").unix();
|
44
|
-
}
|
45
|
-
const TWO_WEEKS_AGO = moment().subtract(2, "weeks").unix();
|
46
|
-
try {
|
47
|
-
const dynamicData = {};
|
48
|
-
let staticData = (await engineDbClient.$queryRaw(ALL_CAMPAIGNS_FOR_CHAIN_AFTER(chainId, campaignsAfter)));
|
49
|
-
log.local(`Data length before filtering: ${staticData.length}`);
|
50
|
-
const mainParameters = {};
|
51
|
-
staticData = staticData.filter(campaign => {
|
52
|
-
if (campaign.endTimestamp < TWO_WEEKS_AGO && campaign.campaignType === Campaign.CLAMM) {
|
53
|
-
campaign.campaignParameters.forwarders = [];
|
54
|
-
}
|
55
|
-
mainParameters[campaign.mainParameter] = true;
|
56
|
-
return true;
|
57
|
-
});
|
58
|
-
log.local(`Data length after filtering: ${staticData.length}`);
|
59
|
-
if (!!staticData) {
|
60
|
-
// Build list of existing campaign types for this chain
|
61
|
-
campaignTypes = !!campaignTypes.length
|
62
|
-
? campaignTypes
|
63
|
-
: !staticData
|
64
|
-
? []
|
65
|
-
: staticData
|
66
|
-
.map(campaign => campaign.campaignType)
|
67
|
-
.reduce((prev, campaignType) => {
|
68
|
-
if (!prev.includes(campaignType))
|
69
|
-
prev.push(campaignType);
|
70
|
-
return prev;
|
71
|
-
}, []);
|
72
|
-
// Fetch dynamic data for all these types
|
73
|
-
const promisesPerType = campaignTypes.map(async (campaignType) => {
|
74
|
-
const campaigns = staticData.filter(campaign => campaign.campaignType === campaignType);
|
75
|
-
await executeSimple(chainId, campaignsDynamicData(chainId, campaigns, campaignType)).then(r => {
|
76
|
-
for (const d of r) {
|
77
|
-
if (!!d) {
|
78
|
-
// Main Parameter OVERRIDING
|
79
|
-
if (d.campaignType === Campaign.SILO && d.campaignParameters.whitelist?.length === 1) {
|
80
|
-
d.mainParameter = `${d.mainParameter}-${d.campaignParameters.whitelist[0]}`;
|
81
|
-
}
|
82
|
-
if (!dynamicData[`${d.campaignType}_${d.mainParameter}`])
|
83
|
-
dynamicData[`${d.campaignType}_${d.mainParameter}`] = {};
|
84
|
-
dynamicData[`${d.campaignType}_${d.mainParameter}`][d.campaignId] = d;
|
85
|
-
}
|
86
|
-
}
|
87
|
-
});
|
88
|
-
});
|
89
|
-
await Promise.all(promisesPerType);
|
90
|
-
}
|
91
|
-
if (!!dynamicData && Object.keys(dynamicData).length > 0) {
|
92
|
-
await Redis.safeSet(`Campaigns_${chainId}`, dynamicData);
|
93
|
-
// Set live or future campaigns
|
94
|
-
const liveDynamicData = {};
|
95
|
-
for (const [type_mainParameter, value] of Object.entries(dynamicData)) {
|
96
|
-
const liveDynamicData = {};
|
97
|
-
for (const [campaignId, data] of Object.entries(value)) {
|
98
|
-
if (data.endTimestamp > moment().unix()) {
|
99
|
-
if (!liveDynamicData[type_mainParameter]) {
|
100
|
-
liveDynamicData[type_mainParameter] = {};
|
101
|
-
}
|
102
|
-
liveDynamicData[type_mainParameter][campaignId] = data;
|
103
|
-
}
|
104
|
-
}
|
105
|
-
}
|
106
|
-
await Redis.safeSet(`LiveCampaigns_${chainId}`, liveDynamicData);
|
107
|
-
const merklChainData = await Redis.get("MerklChainData", chainId);
|
108
|
-
await Redis.safeSet(`CampaignsOldFormat_${chainId}`, campaignsToOldFormat(dynamicData, merklChainData));
|
109
|
-
await Redis.safeSet(`LiveCampaignsOldFormat_${chainId}`, campaignsToOldFormat(liveDynamicData, merklChainData));
|
110
|
-
log.info(`✅ ${NETWORK_LABELS[chainId]} caches updated successfully`);
|
111
|
-
for (const entry of Object.entries(liveDynamicData)) {
|
112
|
-
await CampaignService.fill(Object.values(entry[1]).map(({ campaignId, chainId }) => ({
|
113
|
-
campaignId,
|
114
|
-
distributionChain: chainId,
|
115
|
-
})));
|
116
|
-
const [type, mainParameter] = entry[0].split("_");
|
117
|
-
const apr = AprService.extractFromDynamicData(+type, Object.values(entry[1]));
|
118
|
-
const tvl = TvlService.extractFromDynamicData(+type, Object.values(entry[1]));
|
119
|
-
const dailyRewards = await RewardService.extractDailyRewardsRecordFromDynamicData(+type, Object.values(entry[1]));
|
120
|
-
const opportunityId = OpportunityService.hashId({
|
121
|
-
chainId,
|
122
|
-
identifier: mainParameter,
|
123
|
-
type: CampaignService.getTypeFromV3(+type),
|
124
|
-
});
|
125
|
-
await OpportunityRepository.updateRecords(opportunityId, apr, tvl, dailyRewards);
|
126
|
-
}
|
127
|
-
await OpportunityService.updateMetadata(chainId);
|
128
|
-
// ─── Refresh Cache For GET /opportunities ────
|
129
|
-
await CacheService.set(TTLPresets.MIN_5, OpportunityService.getMany, { items: 50, page: 0 });
|
130
|
-
log.info(`✅ ${NETWORK_LABELS[chainId]} DB records updated successfully`);
|
131
|
-
}
|
132
|
-
else {
|
133
|
-
if (chainId === ChainId.CORE || chainId === ChainId.THUNDERCORE) {
|
134
|
-
log.info(`⚠️ no campaigns found for ${NETWORK_LABELS[chainId]}, setting empty cache`);
|
135
|
-
for (const key of [
|
136
|
-
"Campaigns",
|
137
|
-
"LiveCampaigns",
|
138
|
-
"CampaignsOldFormat",
|
139
|
-
"LiveCampaignsOldFormat",
|
140
|
-
]) {
|
141
|
-
await Redis.safeSet(`${key}_${chainId}`, {});
|
142
|
-
}
|
143
|
-
log.info(`✅ ${NETWORK_LABELS[chainId]} caches updated - empty cache`);
|
144
|
-
}
|
145
|
-
}
|
146
|
-
}
|
147
|
-
catch (error) {
|
148
|
-
log.error(`❌ update Campaigns cache failed for ${NETWORK_LABELS[chainId]}`, error);
|
149
|
-
success = false;
|
150
|
-
}
|
151
|
-
// This is independant of campaigns cache update, so not in the if condition
|
152
|
-
try {
|
153
|
-
await staticCampaignWithCache(chainId);
|
154
|
-
}
|
155
|
-
catch (error) {
|
156
|
-
log.error(`❌ update Campaigns cache failed for ${NETWORK_LABELS[chainId]}`, error);
|
157
|
-
}
|
158
|
-
return { success };
|
17
|
+
return campaignCacheUpdate(rawChainId, campaignTypes, highCampaignsChains);
|
159
18
|
};
|
160
19
|
main()
|
161
20
|
.then(success => (success ? process.exit(0) : process.exit(1)))
|
@@ -12,7 +12,11 @@ export declare abstract class EnsoService {
|
|
12
12
|
id: string;
|
13
13
|
tags: string[];
|
14
14
|
icon: string;
|
15
|
-
} & {
|
15
|
+
} & {
|
16
|
+
dailyRewards?: number | undefined;
|
17
|
+
numberOfLiveCampaigns?: number | undefined;
|
18
|
+
opportunityLiveTags?: string[] | undefined;
|
19
|
+
})[]>;
|
16
20
|
static getTokens(chainId: number, slug: EnsoSlug, identifier?: string): Promise<{
|
17
21
|
type: "base" | "defi";
|
18
22
|
chainId: number;
|
@@ -47,7 +47,11 @@ export declare const InteractionController: Elysia<"/interaction", false, {
|
|
47
47
|
id: string;
|
48
48
|
tags: string[];
|
49
49
|
icon: string;
|
50
|
-
} & {
|
50
|
+
} & {
|
51
|
+
dailyRewards?: number | undefined;
|
52
|
+
numberOfLiveCampaigns?: number | undefined;
|
53
|
+
opportunityLiveTags?: string[] | undefined;
|
54
|
+
})[];
|
51
55
|
};
|
52
56
|
};
|
53
57
|
};
|
@@ -34,7 +34,11 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
|
|
34
34
|
id: string;
|
35
35
|
tags: string[];
|
36
36
|
icon: string;
|
37
|
-
} & {
|
37
|
+
} & {
|
38
|
+
dailyRewards?: number | undefined;
|
39
|
+
numberOfLiveCampaigns?: number | undefined;
|
40
|
+
opportunityLiveTags?: string[] | undefined;
|
41
|
+
})[];
|
38
42
|
};
|
39
43
|
};
|
40
44
|
};
|
@@ -71,6 +75,9 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
|
|
71
75
|
id: string;
|
72
76
|
tags: string[];
|
73
77
|
icon: string;
|
78
|
+
dailyRewards?: number | undefined;
|
79
|
+
numberOfLiveCampaigns?: number | undefined;
|
80
|
+
opportunityLiveTags?: string[] | undefined;
|
74
81
|
} | null;
|
75
82
|
};
|
76
83
|
};
|
@@ -4,11 +4,11 @@ import type { Resource } from "../prisma";
|
|
4
4
|
* @description Target description of rewards campaigns
|
5
5
|
* @see {@link Resource}
|
6
6
|
*/
|
7
|
-
export type Protocol = Resource<"Protocol"
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
}
|
7
|
+
export type Protocol = Resource<"Protocol", undefined, {
|
8
|
+
dailyRewards?: number;
|
9
|
+
numberOfLiveCampaigns?: number;
|
10
|
+
opportunityLiveTags?: string[];
|
11
|
+
}>;
|
12
12
|
declare const protocolTypes: readonly ["ambient", "arthswap", "baseswap", "camelot", "crust", "fenix", "horiza", "izumi", "kim", "pancakeswap-v3", "quickswap-algebra", "quickswap-uni", "ramses", "retro", "stryke", "stryke-pcs", "stryke-sushi", "sushiswap-v3", "swapr", "thruster", "uniswap-v3", "voltage", "zero", "koi", "supswap-v3", "zkswap", "thirdtrade", "uniswapv4", "uniswap-v2", "velodrome", "aerodrome", "balancer", "curve", "cross_curve", "curveNPool", "aura", "akron", "beefy", "dragonswap", "poolside", "koi", "syncswap-v3", "neptune", "zkSwapThreePool", "syncswap", "rfx", "radiant", "aave", "euler", "gearbox", "compound", "sturdy", "frax", "ionic", "moonwell", "fluid", "silo", "morpho", "coumpound", "dolomite", "badger", "ajna", "layerbank", "ion", "venus", "woofi", "reactor_fusion", "eigenlayer", "vest", "zerolend", "hyperdrive", "gamma", "oku", "hourglass", "veda"];
|
13
13
|
export type ProtocolId = (typeof protocolTypes)[number];
|
14
14
|
export declare const ProtocolResourceDto: import("@sinclair/typebox").TObject<{
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { AMM as AMMV3 } from "@sdk";
|
2
|
-
import type { CreateProtocolModel,
|
2
|
+
import type { CreateProtocolModel, GetProtocolsQueryModel, Protocol, ProtocolId, UpdateProtocolModel } from "./protocol.model";
|
3
3
|
export declare abstract class ProtocolService {
|
4
4
|
static getIdFromAmmV3(amm: AMMV3): ProtocolId;
|
5
|
-
static findMany(query: GetProtocolsQueryModel): Promise<
|
5
|
+
static findMany(query: GetProtocolsQueryModel): Promise<Protocol["model"][]>;
|
6
6
|
static countMany(query: GetProtocolsQueryModel): Promise<number>;
|
7
7
|
static getFromId(id: ProtocolId | string): Promise<Protocol["model"] | null>;
|
8
8
|
static getFromName(name: string): Promise<Protocol["model"] | null>;
|
@@ -44,6 +44,7 @@ export class ProtocolService {
|
|
44
44
|
...protocol,
|
45
45
|
dailyRewards: MainOpportunities.reduce((sum, opportunity) => sum + opportunity.dailyRewards, 0),
|
46
46
|
numberOfLiveCampaigns: MainOpportunities.reduce((sum, opportunity) => sum + opportunity.Campaigns.length, 0),
|
47
|
+
opportunityLiveTags: [...new Set(MainOpportunities.flatMap(opportunity => opportunity.action))], // ensure uniqness of tags
|
47
48
|
}));
|
48
49
|
return enrichedProtocols;
|
49
50
|
}
|
@@ -1160,7 +1160,11 @@ export declare const v4: Elysia<"/v4", false, {
|
|
1160
1160
|
id: string;
|
1161
1161
|
tags: string[];
|
1162
1162
|
icon: string;
|
1163
|
-
} & {
|
1163
|
+
} & {
|
1164
|
+
dailyRewards?: number | undefined;
|
1165
|
+
numberOfLiveCampaigns?: number | undefined;
|
1166
|
+
opportunityLiveTags?: string[] | undefined;
|
1167
|
+
})[];
|
1164
1168
|
};
|
1165
1169
|
};
|
1166
1170
|
};
|
@@ -1197,6 +1201,9 @@ export declare const v4: Elysia<"/v4", false, {
|
|
1197
1201
|
id: string;
|
1198
1202
|
tags: string[];
|
1199
1203
|
icon: string;
|
1204
|
+
dailyRewards?: number | undefined;
|
1205
|
+
numberOfLiveCampaigns?: number | undefined;
|
1206
|
+
opportunityLiveTags?: string[] | undefined;
|
1200
1207
|
} | null;
|
1201
1208
|
};
|
1202
1209
|
};
|
@@ -2738,7 +2745,11 @@ export declare const v4: Elysia<"/v4", false, {
|
|
2738
2745
|
id: string;
|
2739
2746
|
tags: string[];
|
2740
2747
|
icon: string;
|
2741
|
-
} & {
|
2748
|
+
} & {
|
2749
|
+
dailyRewards?: number | undefined;
|
2750
|
+
numberOfLiveCampaigns?: number | undefined;
|
2751
|
+
opportunityLiveTags?: string[] | undefined;
|
2752
|
+
})[];
|
2742
2753
|
};
|
2743
2754
|
};
|
2744
2755
|
};
|