@merkl/api 0.17.6 → 0.17.8

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.
Files changed (28) hide show
  1. package/dist/src/backgroundJobs/jobs/opportunityUpdater.js +2 -0
  2. package/dist/src/jobs/etl/update-dynamic-data.js +103 -101
  3. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/hardcoded.js +3 -0
  4. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.d.ts +2 -1
  5. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.js +2 -0
  6. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/processorMapping.js +2 -0
  7. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/xU308Processor.d.ts +37 -0
  8. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/xU308Processor.js +49 -0
  9. package/dist/src/libs/positions/clamm/index.js +1 -1
  10. package/dist/src/modules/v4/campaign/campaign.controller.js +1 -1
  11. package/dist/src/modules/v4/campaign/campaign.repository.d.ts +67 -2
  12. package/dist/src/modules/v4/campaign/campaign.repository.js +46 -6
  13. package/dist/src/modules/v4/campaign/campaign.service.d.ts +55 -2
  14. package/dist/src/modules/v4/campaign/campaign.service.js +5 -2
  15. package/dist/src/modules/v4/claims/claims.controller.js +1 -1
  16. package/dist/src/modules/v4/interaction/interaction.service.d.ts +1 -1
  17. package/dist/src/modules/v4/interaction/interaction.service.js +3 -3
  18. package/dist/src/modules/v4/merklRoot/merklRoot.service.js +1 -1
  19. package/dist/src/modules/v4/opportunity/subservices/getEulerMetadata.service.js +4 -1
  20. package/dist/src/modules/v4/protocol/protocol.service.js +1 -1
  21. package/dist/src/modules/v4/reward/reward.service.js +1 -1
  22. package/dist/src/modules/v4/user/user.model.js +1 -1
  23. package/dist/tsconfig.package.tsbuildinfo +1 -1
  24. package/package.json +2 -2
  25. package/dist/src/modules/v4/chain/index.d.ts +0 -4
  26. package/dist/src/modules/v4/chain/index.js +0 -8
  27. package/dist/src/modules/v4/chainInteraction/index.d.ts +0 -1
  28. package/dist/src/modules/v4/chainInteraction/index.js +0 -1
@@ -53,8 +53,10 @@ export const opportunityUpdater = (app) => {
53
53
  await Redis.safeSet("Opportunities", opportunities);
54
54
  await Redis.safeSet("OpportunitiesWithTest", opportunitiesWithTest);
55
55
  log.info("✅ opportunity cache updated successfully");
56
+ await OpportunityConvertorService.logKeyAndTTLV3Opportunities(true, false, undefined, undefined);
56
57
  await OpportunityConvertorService.setV3Opportunities(true, false, undefined, undefined);
57
58
  log.info("✅ opportunity v3 cache updated successfully");
59
+ await OpportunityConvertorService.logKeyAndTTLV3Opportunities(true, true, undefined, undefined);
58
60
  await OpportunityConvertorService.setV3Opportunities(true, true, undefined, undefined);
59
61
  log.info("✅ opportunity v3 test cache updated successfully");
60
62
  return new Response(JSON.stringify({
@@ -6,7 +6,8 @@ import { OpportunityRepository } from "../../modules/v4/opportunity/opportunity.
6
6
  import { RewardService } from "../../modules/v4/reward";
7
7
  import { TvlService } from "../../modules/v4/tvl";
8
8
  import { executeSimple } from "../../utils/execute";
9
- import { Campaign as CampaignTypesEnum } from "@sdk";
9
+ import { log } from "../../utils/logger";
10
+ import { Campaign as CampaignEnum } from "@sdk";
10
11
  import moment from "moment";
11
12
  // ─── Required Env Variables ──────────────────────────────────────────────────
12
13
  const chainId = Number(process.env.CHAIN_ID);
@@ -14,74 +15,52 @@ if (!chainId)
14
15
  throw new Error("Environment variable CHAIN_ID is required.");
15
16
  // ─── Update Dynamic Data (APR / TVL / Daily Rewards) ─────────────────────────
16
17
  async function updateDynamicData(liveCampaigns, campaignType) {
17
- try {
18
- // Input: list of campaigns of same type
19
- // Output: for each campaign, APR, TVL, Daily Rewards
20
- // Constraint: needs to use multicalls to reduce RPC calls and speed
21
- // - Needs to be robust to a single campaign's call failing
22
- // - Needs to be quite easy for the engine team to setup new campaign types
23
- // abstract GenericDynamicDataComputer
24
- // compute(chainId, type, campaigns) => { apr, tvl, dailyRewards } with breakdowns
25
- // UNISWAP V4
26
- // Round 1 - (chainId, type, campaigns) -> tokens of the pools
27
- // Round 2 - (chainId, type, campaigns, output of previous round) -> balance in tokens of forwarders
28
- // Round 3 - ...
29
- // Round Final - (chainId, type, campaigns, output of previous round) -> { apr, tvl, dailyRewards }
30
- const dynamicData = await executeSimple(chainId, campaignsDynamicData(chainId, liveCampaigns, campaignType));
31
- const oppMap = {};
32
- for (const data of dynamicData) {
33
- if (!!data) {
34
- // Main Parameter OVERRIDING
35
- if (data.campaignType === CampaignTypesEnum.SILO && data.campaignParameters.whitelist?.length === 1)
36
- data.mainParameter = `${data.mainParameter}-${data.campaignParameters.whitelist[0]}`;
37
- if (!oppMap[`${data.campaignType}_${data.mainParameter}`])
38
- oppMap[`${data.campaignType}_${data.mainParameter}`] = {};
39
- oppMap[`${data.campaignType}_${data.mainParameter}`][data.campaignId] = data;
40
- }
41
- }
42
- for (const entry of Object.entries(oppMap)) {
43
- const [type, mainParameter] = entry[0].split("_");
44
- try {
45
- const apr = AprService.extractFromDynamicData(+type, Object.values(entry[1]));
46
- const tvl = TvlService.extractFromDynamicData(+type, Object.values(entry[1]));
47
- const dailyRewards = await RewardService.extractDailyRewardsRecordFromDynamicData(+type, Object.values(entry[1]));
48
- const opportunityId = OpportunityService.hashId({
49
- chainId,
50
- identifier: mainParameter,
51
- type: type,
52
- });
53
- await OpportunityRepository.updateRecords(opportunityId, apr, tvl, dailyRewards);
54
- }
55
- catch (err) {
56
- console.log(mainParameter);
57
- console.error(err);
58
- }
18
+ // Input: list of campaigns of same type
19
+ // Output: for each campaign, APR, TVL, Daily Rewards
20
+ // Constraint: needs to use multicalls to reduce RPC calls and speed
21
+ // - Needs to be robust to a single campaign's call failing
22
+ // - Needs to be quite easy for the engine team to setup new campaign types
23
+ // abstract GenericDynamicDataComputer
24
+ // compute(chainId, type, campaigns) => { apr, tvl, dailyRewards } with breakdowns
25
+ // UNISWAP V4
26
+ // Round 1 - (chainId, type, campaigns) -> tokens of the pools
27
+ // Round 2 - (chainId, type, campaigns, output of previous round) -> balance in tokens of forwarders
28
+ // Round 3 - ...
29
+ // Round Final - (chainId, type, campaigns, output of previous round) -> { apr, tvl, dailyRewards }
30
+ const dynamicData = await executeSimple(chainId, campaignsDynamicData(chainId, liveCampaigns, campaignType));
31
+ const oppMap = {};
32
+ for (const data of dynamicData) {
33
+ if (!!data) {
34
+ // Main Parameter OVERRIDING
35
+ if (data.campaignType === CampaignEnum.SILO && data.campaignParameters.whitelist?.length === 1)
36
+ data.mainParameter = `${data.mainParameter}-${data.campaignParameters.whitelist[0]}`;
37
+ if (!oppMap[`${data.campaignType}_${data.mainParameter}`])
38
+ oppMap[`${data.campaignType}_${data.mainParameter}`] = {};
39
+ oppMap[`${data.campaignType}_${data.mainParameter}`][data.campaignId] = data;
59
40
  }
60
41
  }
61
- catch (err) {
62
- console.error(err);
42
+ for (const entry of Object.entries(oppMap)) {
43
+ const [type, mainParameter] = entry[0].split("_");
44
+ try {
45
+ const apr = AprService.extractFromDynamicData(+type, Object.values(entry[1]));
46
+ const tvl = TvlService.extractFromDynamicData(+type, Object.values(entry[1]));
47
+ const dailyRewards = await RewardService.extractDailyRewardsRecordFromDynamicData(+type, Object.values(entry[1]));
48
+ const opportunityId = OpportunityService.hashId({
49
+ chainId,
50
+ identifier: mainParameter,
51
+ type: type,
52
+ });
53
+ await OpportunityRepository.updateRecords(opportunityId, apr, tvl, dailyRewards);
54
+ }
55
+ catch (err) {
56
+ console.error(err);
57
+ }
63
58
  }
64
59
  }
65
60
  // ─── Get And Transform Live Campaigns Into A Map ─────────────────────────────
66
- const getLiveCampaignsByType = async (chainId) => {
67
- const liveCampaigns = (await CampaignService.getLiveCampaigns({ computeChainId: chainId })).map(c => {
68
- return {
69
- amount: c.amount,
70
- campaignId: c.campaignId,
71
- mainParameter: c.Opportunity.identifier,
72
- campaignParameters: c.params,
73
- campaignSubType: c.subType,
74
- campaignType: c.type,
75
- chainId: c.distributionChainId,
76
- computeChainId: c.computeChainId,
77
- creator: c.creatorAddress,
78
- endTimestamp: c.endTimestamp,
79
- rewardToken: c.rewardTokenId,
80
- startTimestamp: c.startTimestamp,
81
- };
82
- });
61
+ const buildMapByType = async (campaignsToUpdate) => {
83
62
  const campaignTypeToCampaigns = new Map();
84
- for (const campaign of liveCampaigns) {
63
+ for (const campaign of campaignsToUpdate) {
85
64
  const type = campaign.campaignType;
86
65
  let campaigns = campaignTypeToCampaigns.get(campaign.campaignType);
87
66
  if (!campaigns)
@@ -93,46 +72,69 @@ const getLiveCampaignsByType = async (chainId) => {
93
72
  return campaignTypeToCampaigns;
94
73
  };
95
74
  // ─── Main function / entry point ─────────────────────────────────────────────
96
- const main = async () => {
97
- try {
98
- // 1. Get a map of campaigns by campaign type
99
- const liveCampaigns = await getLiveCampaignsByType(chainId);
100
- // 2. Call updateDynamicData with each entries of the map (process by campaign type)
101
- for (const [type, campaigns] of liveCampaigns.entries())
102
- await updateDynamicData(campaigns, type);
103
- // 3. Update status of opportunities
104
- // 3.1 Get current live opportunities
105
- const liveOpportunities = await OpportunityService.findLiveWithCampaigns(chainId);
106
- // 3.2 For each currently live opportunities, infer its updated status by looping through its campaigns
107
- const now = moment().unix();
108
- for (const opportunity of liveOpportunities) {
109
- let status = "NONE";
110
- const campaigns = opportunity.campaigns;
111
- for (const campaign of campaigns) {
112
- if (status !== "LIVE" && campaign.endTimestamp < now)
113
- status = "PAST";
114
- else if (campaign.startTimestamp < now && campaign.endTimestamp > now)
115
- status = "LIVE";
116
- else if (status !== "LIVE" && campaign.startTimestamp > now)
117
- status = "SOON";
118
- }
119
- await OpportunityService.updateStatus(opportunity.id, status);
75
+ const updateCampaigns = async (campaignsToUpdate) => {
76
+ // 1. Get a map of campaigns by campaign type
77
+ const campaignTypeToCampaigns = await buildMapByType(campaignsToUpdate);
78
+ // 2. Call updateDynamicData with each entries of the map (process by campaign type)
79
+ for (const [campaignType, campaigns] of campaignTypeToCampaigns.entries()) {
80
+ log.info(`updating dynamic data for ${campaigns.length} campaigns of type ${CampaignEnum[campaignType]}`);
81
+ try {
82
+ await updateDynamicData(campaigns, campaignType);
120
83
  }
121
- // 4. Compute the opportunity ids of the liveCampaigns
122
- const opportunities = new Set();
123
- for (const [type, campaigns] of liveCampaigns.entries()) {
124
- for (const campaign of campaigns) {
125
- const opportunityId = OpportunityService.hashId({ chainId, identifier: campaign.mainParameter, type });
126
- opportunities.add(opportunityId);
127
- }
84
+ catch (err) {
85
+ console.error(`Failed to update dynamic data for campaign type ${CampaignEnum[campaignType]}`, err);
128
86
  }
129
- // 5. Update the status of the liveCampaigns opportunities
130
- await OpportunityService.updateMany(Array.from(opportunities), { status: "LIVE" });
131
- process.exit(0);
132
87
  }
133
- catch (err) {
134
- console.error(err);
135
- process.exit(1);
88
+ };
89
+ const main = async () => {
90
+ const liveCampaigns = (await CampaignService.getLiveCampaigns({ computeChainId: chainId })).map(c => {
91
+ return {
92
+ amount: c.amount,
93
+ campaignId: c.campaignId,
94
+ mainParameter: c.Opportunity.identifier,
95
+ campaignParameters: c.params,
96
+ campaignSubType: c.subType,
97
+ campaignType: CampaignEnum[c.type],
98
+ chainId: c.distributionChainId,
99
+ computeChainId: c.computeChainId,
100
+ creator: c.creatorAddress,
101
+ endTimestamp: Number(c.endTimestamp),
102
+ rewardToken: c.rewardTokenId,
103
+ startTimestamp: Number(c.startTimestamp),
104
+ index: 0,
105
+ };
106
+ });
107
+ await updateCampaigns(liveCampaigns);
108
+ // Update status of opportunities
109
+ // 1. Get current live opportunities
110
+ const liveOpportunities = await OpportunityService.findLiveWithCampaigns(chainId);
111
+ // 2. For each currently live opportunities, infer its updated status by looping through its campaigns
112
+ const now = moment().unix();
113
+ for (const opportunity of liveOpportunities) {
114
+ let status = "NONE";
115
+ const campaigns = opportunity.campaigns;
116
+ for (const campaign of campaigns) {
117
+ if (status !== "LIVE" && campaign.endTimestamp < now)
118
+ status = "PAST";
119
+ else if (campaign.startTimestamp < now && campaign.endTimestamp > now)
120
+ status = "LIVE";
121
+ else if (status !== "LIVE" && campaign.startTimestamp > now)
122
+ status = "SOON";
123
+ }
124
+ await OpportunityService.updateStatus(opportunity.id, status);
136
125
  }
126
+ // 3. Update the status of the opportunities associated to future campaigns
127
+ const futureOpportunityIds = (await CampaignService.getFutureCampaigns({ computeChainId: chainId })).map(c => c.Opportunity.id);
128
+ await OpportunityService.updateMany(futureOpportunityIds, { status: "SOON" });
129
+ // 4. Update the status of the opportunities associated to live campaigns
130
+ const liveOpportunityIds = (await CampaignService.getLiveCampaigns({ computeChainId: chainId })).map(c => c.Opportunity.id);
131
+ await OpportunityService.updateMany(liveOpportunityIds, { status: "LIVE" });
137
132
  };
138
- await main();
133
+ try {
134
+ await main();
135
+ process.exit(0);
136
+ }
137
+ catch (err) {
138
+ console.error(err);
139
+ process.exit(1);
140
+ }
@@ -20,6 +20,9 @@ const chainAddressToType = {
20
20
  [ChainId.BOB]: {
21
21
  "0x9998e05030Aee3Af9AD3df35A34F5C51e1628779": tokenType.veda,
22
22
  },
23
+ [ChainId.ETHERLINK]: {
24
+ "0x79052Ab3C166D4899a1e0DD033aC3b379AF0B1fD": tokenType.xU308,
25
+ },
23
26
  };
24
27
  export function getTypeFromAddressChain(chain, token) {
25
28
  if (!!chainAddressToType[chain] && !!chainAddressToType[chain][token]) {
@@ -89,7 +89,8 @@ export declare enum tokenType {
89
89
  hourglass = "hourglass",
90
90
  katana = "katana",
91
91
  balancerV3 = "balancerV3",
92
- hanji_liquidity_vault_token = "hanji_liquidity_vault_token"
92
+ hanji_liquidity_vault_token = "hanji_liquidity_vault_token",
93
+ xU308 = "xU308"
93
94
  }
94
95
  export declare const tokenTypeToProtocol: {
95
96
  [key in tokenType]: {
@@ -91,6 +91,7 @@ export var tokenType;
91
91
  tokenType["katana"] = "katana";
92
92
  tokenType["balancerV3"] = "balancerV3";
93
93
  tokenType["hanji_liquidity_vault_token"] = "hanji_liquidity_vault_token";
94
+ tokenType["xU308"] = "xU308";
94
95
  })(tokenType || (tokenType = {}));
95
96
  export const tokenTypeToProtocol = {
96
97
  [tokenType.aave_borrowing]: { protocol: "Aave", action: OpportunityAction.BORROW },
@@ -182,4 +183,5 @@ export const tokenTypeToProtocol = {
182
183
  [tokenType.katana]: { protocol: "Katana", action: OpportunityAction.POOL },
183
184
  [tokenType.balancerV3]: { protocol: "Balancer", action: OpportunityAction.POOL },
184
185
  [tokenType.hanji_liquidity_vault_token]: { protocol: "Hanji", action: OpportunityAction.POOL },
186
+ [tokenType.xU308]: { protocol: "Uranium", action: OpportunityAction.HOLD },
185
187
  };
@@ -42,6 +42,7 @@ import { ZkSwapThreePoolProcessor } from "./ZkSwapThreePoolProcessor";
42
42
  import { CurveNPoolProcessor } from "./curveNPoolProcessor";
43
43
  import { CurveProcessor } from "./curveProcessor";
44
44
  import { StakedCurveProcessor } from "./stakedCurveProcessor";
45
+ import { xU308Processor } from "./xU308Processor";
45
46
  export const processorMapping = {
46
47
  [tokenType.uniswapv2]: UniswapProcessor,
47
48
  [tokenType.balancerGauge]: BalancerGaugeProcessor,
@@ -132,4 +133,5 @@ export const processorMapping = {
132
133
  [tokenType.katana]: UniswapProcessor,
133
134
  [tokenType.balancerV3]: BalancerV3PoolProcessor,
134
135
  [tokenType.hanji_liquidity_vault_token]: HanjiVaultProcessor,
136
+ [tokenType.xU308]: xU308Processor,
135
137
  };
@@ -0,0 +1,37 @@
1
+ import type { Pricer } from "../../../../../utils/pricer";
2
+ import { type Campaign, type CampaignParameters } from "@sdk";
3
+ import { GenericProcessor, type dataType, type mandatoryCallKeys } from "../GenericProcessor";
4
+ import type { tokenType } from "../helpers/tokenType";
5
+ type callType = {
6
+ key: keyof dataRawxU308;
7
+ call: string;
8
+ target: keyof callKeysxU308;
9
+ metaData?: keyof callKeysxU308;
10
+ };
11
+ type callKeysxU308 = mandatoryCallKeys & {
12
+ pool: string;
13
+ token0: string;
14
+ token1: string;
15
+ symbolToken0: string;
16
+ symbolToken1: string;
17
+ decimalsToken0: string;
18
+ decimalsToken1: string;
19
+ balanceToken0: string;
20
+ balanceToken1: string;
21
+ totalAssets: string;
22
+ };
23
+ type dataRawxU308 = callKeysxU308 & {};
24
+ type dataTypexU308 = dataType & {
25
+ pool: string;
26
+ };
27
+ export declare class xU308Processor extends GenericProcessor<callKeysxU308, dataRawxU308, dataTypexU308> {
28
+ rounds: {
29
+ round1: callType[];
30
+ round2: callType[];
31
+ round3: callType[];
32
+ round4: callType[];
33
+ };
34
+ processingRound2(typeInfo: dataRawxU308): void;
35
+ processingRound5(_index: number, type: tokenType, typeInfo: dataRawxU308, _calls: string[], campaign: CampaignParameters<Campaign.ERC20> | CampaignParameters<Campaign.EULER>, pricer: Pricer): Promise<dataTypexU308>;
36
+ }
37
+ export {};
@@ -0,0 +1,49 @@
1
+ import { generateCardName } from "../../../../../utils/generateCardName";
2
+ import { BN2Number } from "@sdk";
3
+ import { GenericProcessor } from "../GenericProcessor";
4
+ export class xU308Processor extends GenericProcessor {
5
+ rounds = {
6
+ round1: [],
7
+ round2: [
8
+ { key: "token0", call: "token0", target: "pool" },
9
+ { key: "token1", call: "token1", target: "pool" },
10
+ ],
11
+ round3: [
12
+ { key: "symbolToken0", call: "symbol", target: "token0" },
13
+ { key: "symbolToken1", call: "symbol", target: "token1" },
14
+ { key: "decimalsToken0", call: "decimals", target: "token0" },
15
+ { key: "decimalsToken1", call: "decimals", target: "token1" },
16
+ { key: "balanceToken0", call: "balanceOf", target: "token0", metaData: "pool" },
17
+ { key: "balanceToken1", call: "balanceOf", target: "token1", metaData: "pool" },
18
+ ],
19
+ round4: [{ key: "totalSupply", call: "totalSupply", target: "tokenAddress" }],
20
+ };
21
+ // override computeRound1(): void {}
22
+ processingRound2(typeInfo) {
23
+ typeInfo.pool = "0xB387D0A73619791420De4a1e5e710023Cb0f49c0";
24
+ }
25
+ async processingRound5(_index, type, typeInfo, _calls, campaign, pricer) {
26
+ const { whitelistedSupplyTargetToken, totalSupply, blacklistedSupply } = this.handleWhiteListBlacklistRound5(typeInfo, campaign);
27
+ let priceTargetToken = 0;
28
+ if (typeInfo.token0 !== typeInfo.tokenAddress) {
29
+ const priceToken0 = (await pricer.get({ symbol: typeInfo.symbolToken0 })) ?? 0;
30
+ priceTargetToken =
31
+ (priceToken0 * BN2Number(typeInfo.balanceToken0, Number(typeInfo.decimalsToken0))) /
32
+ BN2Number(typeInfo.balanceToken1, Number(typeInfo.decimalsToken1));
33
+ }
34
+ const priceToken1 = (await pricer.get({ symbol: typeInfo.symbolToken1 })) ?? 0;
35
+ priceTargetToken =
36
+ (priceToken1 * BN2Number(typeInfo.balanceToken1, Number(typeInfo.decimalsToken1))) /
37
+ BN2Number(typeInfo.balanceToken0, Number(typeInfo.decimalsToken0));
38
+ const tvl = priceTargetToken * totalSupply;
39
+ return {
40
+ ...typeInfo,
41
+ tvl,
42
+ whitelistedSupplyTargetToken,
43
+ blacklistedSupply,
44
+ priceTargetToken,
45
+ totalSupply,
46
+ cardName: generateCardName(type, typeInfo, campaign),
47
+ };
48
+ }
49
+ }
@@ -1,6 +1,6 @@
1
1
  import { CacheService } from "../../../modules/v4/cache";
2
2
  import { TTLPresets } from "../../../modules/v4/cache/cache.model";
3
- import { ChainInteractionService } from "../../../modules/v4/chainInteraction";
3
+ import { ChainInteractionService } from "../../../modules/v4/chainInteraction/chainInteraction.service";
4
4
  import { ALM, AMMAlgorithmMapping, BN2Number, NETWORK_LABELS, NFTManagerAddress, NonFungiblePositionManagerInterface, PoolInterface, PoolState, SqrtPrice, YEAR, getAmountsForLiquidity, getSupportedNFPWrapperMapping, getTickAtSqrtRatio, spNFTInterface, } from "@sdk";
5
5
  import { BigNumber, Contract, utils } from "ethers";
6
6
  import JSBI from "jsbi";
@@ -1,9 +1,9 @@
1
1
  import { NotFoundError } from "../../../errors";
2
2
  import { BackOfficeGuard } from "../../../guards/BackOffice.guard";
3
3
  import { AuthorizationHeadersDto, EngineGuard } from "../../../guards/Engine.guard";
4
+ import { ChainUniqueDto } from "../chain/chain.model";
4
5
  import Elysia, { t } from "elysia";
5
6
  import { throwOnUnsupportedChainId } from "src/utils/throw";
6
- import { ChainUniqueDto } from "../chain";
7
7
  import { CampaignResourceDto, CreateCampaignDto, GetCampaignQueryDto, UpdateCampaignDto, UpdateMetaDataCampaignDto, } from "./campaign.model";
8
8
  import { CampaignService } from "./campaign.service";
9
9
  // ─── Campaigns Controller ────────────────────────────────────────────────────
@@ -71,8 +71,29 @@ export declare abstract class CampaignRepository {
71
71
  * A campaign is considered past if the current timestamp is greater than the campaign's end timestamp.
72
72
  *
73
73
  * @returns A promise that resolves to an array of past campaigns.
74
+ *
75
+ * @dev Excludes test campaigns
74
76
  */
75
- static getPastCampaigns(chainId?: number): Promise<{
77
+ static getPastCampaigns(query?: {
78
+ computeChainId?: number;
79
+ type?: string;
80
+ }): Promise<({
81
+ Opportunity: {
82
+ name: string;
83
+ type: string;
84
+ id: string;
85
+ status: import("../../../../database/api/.generated").$Enums.Status;
86
+ tags: string[];
87
+ identifier: string;
88
+ chainId: number;
89
+ action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
90
+ depositUrl: string | null;
91
+ mainProtocolId: string | null;
92
+ tvl: number;
93
+ apr: number;
94
+ dailyRewards: number;
95
+ };
96
+ } & {
76
97
  type: string;
77
98
  id: string;
78
99
  params: Prisma.JsonValue;
@@ -86,12 +107,56 @@ export declare abstract class CampaignRepository {
86
107
  amount: string;
87
108
  opportunityId: string;
88
109
  creatorAddress: string;
89
- }[]>;
110
+ })[]>;
111
+ /**
112
+ * Retrieves all past campaigns from the database.
113
+ * A campaign is considered past if the current timestamp is greater than the campaign's end timestamp.
114
+ *
115
+ * @returns A promise that resolves to an array of past campaigns.
116
+ *
117
+ * @dev Excludes test campaigns
118
+ */
119
+ static getFutureCampaigns(query?: {
120
+ computeChainId?: number;
121
+ type?: string;
122
+ }): Promise<({
123
+ Opportunity: {
124
+ name: string;
125
+ type: string;
126
+ id: string;
127
+ status: import("../../../../database/api/.generated").$Enums.Status;
128
+ tags: string[];
129
+ identifier: string;
130
+ chainId: number;
131
+ action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
132
+ depositUrl: string | null;
133
+ mainProtocolId: string | null;
134
+ tvl: number;
135
+ apr: number;
136
+ dailyRewards: number;
137
+ };
138
+ } & {
139
+ type: string;
140
+ id: string;
141
+ params: Prisma.JsonValue;
142
+ subType: number | null;
143
+ startTimestamp: bigint;
144
+ endTimestamp: bigint;
145
+ computeChainId: number;
146
+ distributionChainId: number;
147
+ campaignId: string;
148
+ rewardTokenId: string;
149
+ amount: string;
150
+ opportunityId: string;
151
+ creatorAddress: string;
152
+ })[]>;
90
153
  /**
91
154
  * Retrieves all live campaigns from the database.
92
155
  * A campaign is considered live if the current timestamp is between the campaign's start and end timestamps.
93
156
  *
94
157
  * @returns A promise that resolves to an array of live campaigns.
158
+ *
159
+ * @dev Excludes test campaigns
95
160
  */
96
161
  static getLiveCampaigns(query?: {
97
162
  computeChainId?: number;
@@ -54,15 +54,50 @@ export class CampaignRepository {
54
54
  * A campaign is considered past if the current timestamp is greater than the campaign's end timestamp.
55
55
  *
56
56
  * @returns A promise that resolves to an array of past campaigns.
57
+ *
58
+ * @dev Excludes test campaigns
57
59
  */
58
- static async getPastCampaigns(chainId) {
60
+ static async getPastCampaigns(query) {
59
61
  const now = moment().unix();
62
+ const where = {
63
+ ...query,
64
+ endTimestamp: {
65
+ lt: now,
66
+ },
67
+ RewardToken: {
68
+ isTest: false,
69
+ },
70
+ };
60
71
  return await apiDbClient.campaign.findMany({
61
- where: {
62
- computeChainId: chainId,
63
- endTimestamp: {
64
- lt: now,
65
- },
72
+ where,
73
+ include: {
74
+ Opportunity: true,
75
+ },
76
+ });
77
+ }
78
+ /**
79
+ * Retrieves all past campaigns from the database.
80
+ * A campaign is considered past if the current timestamp is greater than the campaign's end timestamp.
81
+ *
82
+ * @returns A promise that resolves to an array of past campaigns.
83
+ *
84
+ * @dev Excludes test campaigns
85
+ */
86
+ static async getFutureCampaigns(query) {
87
+ const now = moment().unix();
88
+ const where = {
89
+ ...query,
90
+ startTimestamp: {
91
+ gt: now,
92
+ },
93
+ RewardToken: {
94
+ isTest: false,
95
+ },
96
+ };
97
+ return await apiDbClient.campaign.findMany({
98
+ where,
99
+ include: {
100
+ Opportunity: true,
66
101
  },
67
102
  });
68
103
  }
@@ -71,6 +106,8 @@ export class CampaignRepository {
71
106
  * A campaign is considered live if the current timestamp is between the campaign's start and end timestamps.
72
107
  *
73
108
  * @returns A promise that resolves to an array of live campaigns.
109
+ *
110
+ * @dev Excludes test campaigns
74
111
  */
75
112
  static async getLiveCampaigns(query) {
76
113
  const now = moment().unix();
@@ -78,6 +115,9 @@ export class CampaignRepository {
78
115
  ...query,
79
116
  endTimestamp: { gte: now },
80
117
  startTimestamp: { lte: now },
118
+ RewardToken: {
119
+ isTest: false,
120
+ },
81
121
  };
82
122
  return await apiDbClient.campaign.findMany({
83
123
  where,
@@ -4,7 +4,26 @@ import { CampaignRepository } from "./campaign.repository";
4
4
  export declare abstract class CampaignService {
5
5
  static hashId(campaign: CampaignUnique): string;
6
6
  static splitIdOrThrow(chainAndCampaignId: `${number}-${string}` | string): CampaignUnique;
7
- static getPastCampaigns(chainId?: number): Promise<{
7
+ static getPastCampaigns(query?: {
8
+ computeChainId?: number;
9
+ type?: string;
10
+ }): Promise<({
11
+ Opportunity: {
12
+ name: string;
13
+ type: string;
14
+ id: string;
15
+ status: import("../../../../database/api/.generated").$Enums.Status;
16
+ tags: string[];
17
+ identifier: string;
18
+ chainId: number;
19
+ action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
20
+ depositUrl: string | null;
21
+ mainProtocolId: string | null;
22
+ tvl: number;
23
+ apr: number;
24
+ dailyRewards: number;
25
+ };
26
+ } & {
8
27
  type: string;
9
28
  id: string;
10
29
  params: import("database/api/.generated/runtime/library").JsonValue;
@@ -18,7 +37,41 @@ export declare abstract class CampaignService {
18
37
  amount: string;
19
38
  opportunityId: string;
20
39
  creatorAddress: string;
21
- }[]>;
40
+ })[]>;
41
+ static getFutureCampaigns(query?: {
42
+ computeChainId?: number;
43
+ type?: string;
44
+ }): Promise<({
45
+ Opportunity: {
46
+ name: string;
47
+ type: string;
48
+ id: string;
49
+ status: import("../../../../database/api/.generated").$Enums.Status;
50
+ tags: string[];
51
+ identifier: string;
52
+ chainId: number;
53
+ action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
54
+ depositUrl: string | null;
55
+ mainProtocolId: string | null;
56
+ tvl: number;
57
+ apr: number;
58
+ dailyRewards: number;
59
+ };
60
+ } & {
61
+ type: string;
62
+ id: string;
63
+ params: import("database/api/.generated/runtime/library").JsonValue;
64
+ subType: number | null;
65
+ startTimestamp: bigint;
66
+ endTimestamp: bigint;
67
+ computeChainId: number;
68
+ distributionChainId: number;
69
+ campaignId: string;
70
+ rewardTokenId: string;
71
+ amount: string;
72
+ opportunityId: string;
73
+ creatorAddress: string;
74
+ })[]>;
22
75
  static getLiveCampaigns(query?: {
23
76
  computeChainId?: number;
24
77
  type?: string;
@@ -21,8 +21,11 @@ export class CampaignService {
21
21
  const [chainId, campaignId] = chainAndCampaignId.split("-");
22
22
  return { distributionChain: +chainId, campaignId };
23
23
  }
24
- static async getPastCampaigns(chainId) {
25
- return await CampaignRepository.getPastCampaigns(chainId);
24
+ static async getPastCampaigns(query) {
25
+ return await CampaignRepository.getPastCampaigns(query);
26
+ }
27
+ static async getFutureCampaigns(query) {
28
+ return await CampaignRepository.getFutureCampaigns(query);
26
29
  }
27
30
  static async getLiveCampaigns(query) {
28
31
  return await CampaignRepository.getLiveCampaigns(query);