@merkl/api 0.17.7 → 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.
@@ -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);
@@ -31,7 +32,7 @@ async function updateDynamicData(liveCampaigns, campaignType) {
31
32
  for (const data of dynamicData) {
32
33
  if (!!data) {
33
34
  // Main Parameter OVERRIDING
34
- if (data.campaignType === CampaignTypesEnum.SILO && data.campaignParameters.whitelist?.length === 1)
35
+ if (data.campaignType === CampaignEnum.SILO && data.campaignParameters.whitelist?.length === 1)
35
36
  data.mainParameter = `${data.mainParameter}-${data.campaignParameters.whitelist[0]}`;
36
37
  if (!oppMap[`${data.campaignType}_${data.mainParameter}`])
37
38
  oppMap[`${data.campaignType}_${data.mainParameter}`] = {};
@@ -57,25 +58,9 @@ async function updateDynamicData(liveCampaigns, campaignType) {
57
58
  }
58
59
  }
59
60
  // ─── Get And Transform Live Campaigns Into A Map ─────────────────────────────
60
- const getLiveCampaignsByType = async (chainId) => {
61
- const liveCampaigns = (await CampaignService.getLiveCampaigns({ computeChainId: chainId })).map(c => {
62
- return {
63
- amount: c.amount,
64
- campaignId: c.campaignId,
65
- mainParameter: c.Opportunity.identifier,
66
- campaignParameters: c.params,
67
- campaignSubType: c.subType,
68
- campaignType: c.type,
69
- chainId: c.distributionChainId,
70
- computeChainId: c.computeChainId,
71
- creator: c.creatorAddress,
72
- endTimestamp: c.endTimestamp,
73
- rewardToken: c.rewardTokenId,
74
- startTimestamp: c.startTimestamp,
75
- };
76
- });
61
+ const buildMapByType = async (campaignsToUpdate) => {
77
62
  const campaignTypeToCampaigns = new Map();
78
- for (const campaign of liveCampaigns) {
63
+ for (const campaign of campaignsToUpdate) {
79
64
  const type = campaign.campaignType;
80
65
  let campaigns = campaignTypeToCampaigns.get(campaign.campaignType);
81
66
  if (!campaigns)
@@ -87,22 +72,43 @@ const getLiveCampaignsByType = async (chainId) => {
87
72
  return campaignTypeToCampaigns;
88
73
  };
89
74
  // ─── Main function / entry point ─────────────────────────────────────────────
90
- const main = async () => {
75
+ const updateCampaigns = async (campaignsToUpdate) => {
91
76
  // 1. Get a map of campaigns by campaign type
92
- const liveCampaigns = await getLiveCampaignsByType(chainId);
77
+ const campaignTypeToCampaigns = await buildMapByType(campaignsToUpdate);
93
78
  // 2. Call updateDynamicData with each entries of the map (process by campaign type)
94
- for (const [type, campaigns] of liveCampaigns.entries()) {
79
+ for (const [campaignType, campaigns] of campaignTypeToCampaigns.entries()) {
80
+ log.info(`updating dynamic data for ${campaigns.length} campaigns of type ${CampaignEnum[campaignType]}`);
95
81
  try {
96
- await updateDynamicData(campaigns, type);
82
+ await updateDynamicData(campaigns, campaignType);
97
83
  }
98
84
  catch (err) {
99
- console.error(`Failed to update dynamic data for campaign type ${type}`, err);
85
+ console.error(`Failed to update dynamic data for campaign type ${CampaignEnum[campaignType]}`, err);
100
86
  }
101
87
  }
102
- // 3. Update status of opportunities
103
- // 3.1 Get current live opportunities
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
104
110
  const liveOpportunities = await OpportunityService.findLiveWithCampaigns(chainId);
105
- // 3.2 For each currently live opportunities, infer its updated status by looping through its campaigns
111
+ // 2. For each currently live opportunities, infer its updated status by looping through its campaigns
106
112
  const now = moment().unix();
107
113
  for (const opportunity of liveOpportunities) {
108
114
  let status = "NONE";
@@ -117,16 +123,12 @@ const main = async () => {
117
123
  }
118
124
  await OpportunityService.updateStatus(opportunity.id, status);
119
125
  }
120
- // 4. Compute opportunity ids of liveCampaigns
121
- const opportunities = new Set();
122
- for (const [type, campaigns] of liveCampaigns.entries()) {
123
- for (const campaign of campaigns) {
124
- const opportunityId = OpportunityService.hashId({ chainId, identifier: campaign.mainParameter, type });
125
- opportunities.add(opportunityId);
126
- }
127
- }
128
- // 5. Update the status of the liveCampaigns opportunities
129
- await OpportunityService.updateMany(Array.from(opportunities), { status: "LIVE" });
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" });
130
132
  };
131
133
  try {
132
134
  await main();
@@ -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);