@merkl/api 0.16.39 → 0.16.41

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 (72) hide show
  1. package/dist/database/api/.generated/edge.js +2 -2
  2. package/dist/database/api/.generated/index.js +2 -2
  3. package/dist/database/api/.generated/package.json +1 -1
  4. package/dist/database/api/.generated/schema.prisma +4 -0
  5. package/dist/src/eden/index.d.ts +7600 -5065
  6. package/dist/src/entities/opportunity.js +4 -0
  7. package/dist/src/index.d.ts +753 -246
  8. package/dist/src/jobs/etl/update-dynamic-data.d.ts +1 -0
  9. package/dist/src/jobs/etl/update-dynamic-data.js +71 -0
  10. package/dist/src/libs/campaigns/campaignsDynamicData.d.ts +1 -1
  11. package/dist/src/libs/campaigns/campaignsDynamicData.js +22 -0
  12. package/dist/src/modules/v4/airflow/airflow.service.d.ts +3 -0
  13. package/dist/src/modules/v4/airflow/airflow.service.js +20 -0
  14. package/dist/src/modules/v4/campaign/campaign.repository.d.ts +81 -1
  15. package/dist/src/modules/v4/campaign/campaign.repository.js +57 -1
  16. package/dist/src/modules/v4/campaign/campaign.service.d.ts +57 -3
  17. package/dist/src/modules/v4/campaign/campaign.service.js +15 -6
  18. package/dist/src/modules/v4/campaign/index.d.ts +0 -1
  19. package/dist/src/modules/v4/campaign/index.js +0 -1
  20. package/dist/src/modules/v4/chain/chain.controller.d.ts +12 -36
  21. package/dist/src/modules/v4/chain/chain.controller.js +8 -6
  22. package/dist/src/modules/v4/chain/chain.model.d.ts +2 -0
  23. package/dist/src/modules/v4/chain/chain.model.js +2 -0
  24. package/dist/src/modules/v4/chain/chain.repository.d.ts +9 -11
  25. package/dist/src/modules/v4/chain/chain.repository.js +5 -18
  26. package/dist/src/modules/v4/chain/chain.service.d.ts +5 -0
  27. package/dist/src/modules/v4/chain/chain.service.js +4 -1
  28. package/dist/src/modules/v4/chain/index.d.ts +2 -1
  29. package/dist/src/modules/v4/chain/index.js +6 -1
  30. package/dist/src/modules/v4/computedValue/computedValue.repository.d.ts +1 -1
  31. package/dist/src/modules/v4/computedValue/computedValue.service.d.ts +1 -1
  32. package/dist/src/modules/v4/computedValue/index.d.ts +0 -1
  33. package/dist/src/modules/v4/computedValue/index.js +0 -1
  34. package/dist/src/modules/v4/dynamicData/dynamicData.service.js +1 -1
  35. package/dist/src/modules/v4/enso/enso.service.d.ts +1 -12
  36. package/dist/src/modules/v4/interaction/interaction.controller.d.ts +2 -12
  37. package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +703 -134
  38. package/dist/src/modules/v4/opportunity/opportunity.controller.js +2 -4
  39. package/dist/src/modules/v4/opportunity/opportunity.converter.js +1 -1
  40. package/dist/src/modules/v4/opportunity/opportunity.model.js +1 -1
  41. package/dist/src/modules/v4/opportunity/opportunity.repository.js +2 -1
  42. package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +0 -204
  43. package/dist/src/modules/v4/opportunity/opportunity.service.js +6 -4
  44. package/dist/src/modules/v4/opportunity/subservices/getVestMetaData.service.d.ts +1 -1
  45. package/dist/src/modules/v4/opportunity/subservices/getVestMetaData.service.js +1 -1
  46. package/dist/src/modules/v4/protocol/index.d.ts +2 -1
  47. package/dist/src/modules/v4/protocol/index.js +8 -1
  48. package/dist/src/modules/v4/protocol/protocol.controller.d.ts +10 -40
  49. package/dist/src/modules/v4/protocol/protocol.controller.js +11 -9
  50. package/dist/src/modules/v4/protocol/protocol.service.d.ts +7 -7
  51. package/dist/src/modules/v4/protocol/protocol.service.js +10 -10
  52. package/dist/src/modules/v4/reward/index.d.ts +0 -1
  53. package/dist/src/modules/v4/reward/index.js +0 -1
  54. package/dist/src/modules/v4/reward/reward.service.d.ts +5 -5
  55. package/dist/src/modules/v4/reward/reward.service.js +6 -7
  56. package/dist/src/modules/v4/router.d.ts +752 -245
  57. package/dist/src/modules/v4/status/index.d.ts +0 -1
  58. package/dist/src/modules/v4/status/index.js +0 -1
  59. package/dist/src/modules/v4/status/status.controller.d.ts +1 -1
  60. package/dist/src/modules/v4/status/status.repository.d.ts +1 -1
  61. package/dist/src/modules/v4/status/status.service.d.ts +2 -2
  62. package/dist/src/modules/v4/token/token.controller.d.ts +2 -0
  63. package/dist/src/modules/v4/token/token.model.d.ts +1 -0
  64. package/dist/src/modules/v4/token/token.model.js +1 -0
  65. package/dist/src/modules/v4/token/token.repository.js +4 -1
  66. package/dist/src/modules/v4/token/token.service.d.ts +1 -0
  67. package/dist/src/modules/v4/token/token.service.js +10 -0
  68. package/dist/src/routes/v3/campaigns.d.ts +1 -1
  69. package/dist/src/routes/v3/opportunity.js +1 -1
  70. package/dist/src/routes/v3/router.d.ts +1 -1
  71. package/dist/tsconfig.package.tsbuildinfo +1 -1
  72. package/package.json +2 -1
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,71 @@
1
+ import { campaignsDynamicData } from "../../libs/campaigns/campaignsDynamicData";
2
+ import { AprService } from "../../modules/v4/apr";
3
+ import { CampaignService } from "../../modules/v4/campaign";
4
+ import { OpportunityService } from "../../modules/v4/opportunity";
5
+ import { OpportunityRepository } from "../../modules/v4/opportunity/opportunity.repository";
6
+ import { RewardService } from "../../modules/v4/reward";
7
+ import { TvlService } from "../../modules/v4/tvl";
8
+ import { executeSimple } from "../../utils/execute";
9
+ import { Campaign } from "@sdk";
10
+ const chainId = Number(process.env.CHAIN_ID);
11
+ if (!chainId)
12
+ throw new Error("Environment variable CHAIN_ID is required.");
13
+ const campaignType = process.env.CAMPAIGN_TYPE;
14
+ if (!campaignType)
15
+ throw new Error("Environment variable CAMPAIGN_TYPE is required.");
16
+ async function updateDynamicData() {
17
+ const liveCampaigns = (await CampaignService.getLiveCampaigns({ computeChainId: chainId, type: campaignType })).map(c => {
18
+ return {
19
+ amount: c.amount,
20
+ campaignId: c.campaignId,
21
+ mainParameter: c.Opportunity.identifier,
22
+ campaignParameters: c.params,
23
+ campaignSubType: c.subType,
24
+ campaignType,
25
+ chainId: c.distributionChainId,
26
+ computeChainId: c.computeChainId,
27
+ creator: c.creatorAddress,
28
+ endTimestamp: c.endTimestamp,
29
+ rewardToken: c.rewardTokenId,
30
+ startTimestamp: c.startTimestamp,
31
+ };
32
+ });
33
+ const dynamicData = await executeSimple(chainId, campaignsDynamicData(chainId, liveCampaigns, campaignType));
34
+ const oppMap = {};
35
+ for (const data of dynamicData) {
36
+ if (!!data) {
37
+ // Main Parameter OVERRIDING
38
+ if (data.campaignType === Campaign.SILO && data.campaignParameters.whitelist?.length === 1)
39
+ data.mainParameter = `${data.mainParameter}-${data.campaignParameters.whitelist[0]}`;
40
+ if (!oppMap[`${data.campaignType}_${data.mainParameter}`])
41
+ oppMap[`${data.campaignType}_${data.mainParameter}`] = {};
42
+ oppMap[`${data.campaignType}_${data.mainParameter}`][data.campaignId] = data;
43
+ }
44
+ }
45
+ for (const entry of Object.entries(oppMap)) {
46
+ const [type, mainParameter] = entry[0].split("_");
47
+ try {
48
+ const apr = AprService.extractFromDynamicData(+type, Object.values(entry[1]));
49
+ const tvl = TvlService.extractFromDynamicData(+type, Object.values(entry[1]));
50
+ const dailyRewards = await RewardService.extractDailyRewardsRecordFromDynamicData(+type, Object.values(entry[1]));
51
+ const opportunityId = OpportunityService.hashId({
52
+ chainId,
53
+ identifier: mainParameter,
54
+ type: type,
55
+ });
56
+ await OpportunityRepository.updateRecords(opportunityId, apr, tvl, dailyRewards);
57
+ }
58
+ catch (err) {
59
+ console.log(mainParameter);
60
+ console.error(err);
61
+ }
62
+ }
63
+ }
64
+ try {
65
+ await updateDynamicData();
66
+ process.exit(0);
67
+ }
68
+ catch (err) {
69
+ console.error(err);
70
+ process.exit(1);
71
+ }
@@ -1,3 +1,3 @@
1
1
  import { Campaign, type CampaignDynamicData, type CampaignParameters, type MerklChainId } from "@sdk";
2
2
  import type { UncachedResult } from "../../utils/execute";
3
- export declare function campaignsDynamicData<T extends Campaign>(chainId: MerklChainId, campaigns: CampaignParameters<T>[], type: T): Promise<UncachedResult<Partial<CampaignDynamicData<T>[]>>>;
3
+ export declare function campaignsDynamicData<T extends Campaign>(chainId: MerklChainId, campaigns: CampaignParameters<T>[], type: T | string): Promise<UncachedResult<Partial<CampaignDynamicData<T>[]>>>;
@@ -26,67 +26,89 @@ export async function campaignsDynamicData(chainId, campaigns, type) {
26
26
  }
27
27
  catch (_err) { }
28
28
  switch (type) {
29
+ case "ERC20":
29
30
  case Campaign.ERC20: {
30
31
  return ERC20DynamicData(chainId, campaigns);
31
32
  }
33
+ case "ERC20LOGPROCESSOR":
32
34
  case Campaign.ERC20LOGPROCESSOR: {
33
35
  return ERC20DynamicData(chainId, campaigns);
34
36
  }
37
+ case "ERC20REBASELOGPROCESSOR":
35
38
  case Campaign.ERC20REBASELOGPROCESSOR: {
36
39
  return ERC20DynamicData(chainId, campaigns);
37
40
  }
41
+ case "CLAMM":
38
42
  case Campaign.CLAMM: {
39
43
  return CLAMMDynamicData(chainId, campaigns);
40
44
  }
45
+ case "ERC20_SNAPSHOT":
41
46
  case Campaign.ERC20_SNAPSHOT: {
42
47
  return ERC20_SNAPSHOTDynamicData(chainId, campaigns);
43
48
  }
49
+ case "JSON_AIRDROP":
44
50
  case Campaign.JSON_AIRDROP: {
45
51
  return JSON_AIRDROPDynamicData(chainId, campaigns);
46
52
  }
53
+ case "SILO":
47
54
  case Campaign.SILO: {
48
55
  return SILODynamicData(chainId, campaigns);
49
56
  }
57
+ case "RADIANT":
50
58
  case Campaign.RADIANT: {
51
59
  return RadiantDynamicData(chainId, campaigns);
52
60
  }
61
+ case "MORPHO":
53
62
  case Campaign.MORPHO: {
54
63
  return MORPHODynamicData(chainId, campaigns);
55
64
  }
65
+ case "EULER":
56
66
  case Campaign.EULER: {
57
67
  return ERC20DynamicData(chainId, campaigns);
58
68
  }
69
+ case "DOLOMITE":
59
70
  case Campaign.DOLOMITE: {
60
71
  return DolomiteDynamicData(chainId, campaigns);
61
72
  }
73
+ case "BADGER":
62
74
  case Campaign.BADGER: {
63
75
  return BadgerDynamicData(chainId, campaigns);
64
76
  }
77
+ case "AJNA":
65
78
  case Campaign.AJNA: {
66
79
  return AjnaDynamicData(chainId, campaigns);
67
80
  }
81
+ case "COMPOUND":
68
82
  case Campaign.COMPOUND: {
69
83
  return CompoundDynamicData(chainId, campaigns);
70
84
  }
85
+ case "EIGENLAYER":
71
86
  case Campaign.EIGENLAYER: {
72
87
  return EigenLayerDynamicData(chainId, campaigns);
73
88
  }
89
+ case "VEST":
74
90
  case Campaign.VEST: {
75
91
  return VestDynamicData(chainId, campaigns);
76
92
  }
93
+ case "ERC20_FIX_APR":
77
94
  case Campaign.ERC20_FIX_APR: {
78
95
  return ERC20DynamicData(chainId, campaigns);
79
96
  }
97
+ case "HYPERDRIVELOGPROCESSOR":
98
+ case "HYPERDRIVELOGFIXPROCESSOR":
80
99
  case Campaign.HYPERDRIVELOGPROCESSOR:
81
100
  case Campaign.HYPERDRIVELOGFIXPROCESSOR: {
82
101
  return HyperdriveDynamicData(chainId, campaigns);
83
102
  }
103
+ case "AMBIENTPROCESSOR":
84
104
  case Campaign.AMBIENTPROCESSOR: {
85
105
  return AmbientDynamicData(chainId, campaigns);
86
106
  }
107
+ case "UNISWAP_V4":
87
108
  case Campaign.UNISWAP_V4: {
88
109
  return UniswapV4DynamicData(chainId, campaigns);
89
110
  }
111
+ case "ENCOMPASSING":
90
112
  case Campaign.ENCOMPASSING: {
91
113
  return EncompassingDynamicData(chainId, campaigns);
92
114
  }
@@ -0,0 +1,3 @@
1
+ export declare class AirflowService {
2
+ static triggerDAGRun(dagId: string, conf: object): Promise<void>;
3
+ }
@@ -0,0 +1,20 @@
1
+ import { log } from "../../../utils/logger";
2
+ import { withRetry } from "@sdk";
3
+ import { GoogleAuth } from "google-auth-library";
4
+ export class AirflowService {
5
+ static async triggerDAGRun(dagId, conf) {
6
+ const auth = new GoogleAuth({
7
+ scopes: "https://www.googleapis.com/auth/cloud-platform",
8
+ });
9
+ const client = await auth.getClient();
10
+ const reqParams = {
11
+ method: "POST",
12
+ url: `${process.env.AIRFLOW_URL}/api/v1/dags/${dagId}/dagRuns`,
13
+ data: {
14
+ conf,
15
+ },
16
+ };
17
+ await withRetry(async () => await client.request(reqParams), [], 2, 10_000);
18
+ log.info(`✅ triggered DAG ${dagId}`);
19
+ }
20
+ }
@@ -66,6 +66,86 @@ export declare abstract class CampaignRepository {
66
66
  } | undefined;
67
67
  };
68
68
  };
69
+ /**
70
+ * Retrieves all past campaigns from the database.
71
+ * A campaign is considered past if the current timestamp is greater than the campaign's end timestamp.
72
+ *
73
+ * @returns A promise that resolves to an array of past campaigns.
74
+ */
75
+ static getPastCampaigns(chainId?: number): Promise<{
76
+ type: string;
77
+ id: string;
78
+ params: Prisma.JsonValue;
79
+ subType: number | null;
80
+ startTimestamp: bigint;
81
+ endTimestamp: bigint;
82
+ computeChainId: number;
83
+ distributionChainId: number;
84
+ campaignId: string;
85
+ rewardTokenId: string;
86
+ amount: string;
87
+ opportunityId: string;
88
+ creatorAddress: string;
89
+ }[]>;
90
+ /**
91
+ * Retrieves all live campaigns from the database.
92
+ * A campaign is considered live if the current timestamp is between the campaign's start and end timestamps.
93
+ *
94
+ * @returns A promise that resolves to an array of live campaigns.
95
+ */
96
+ static getLiveCampaigns(query?: {
97
+ computeChainId?: number;
98
+ type?: string;
99
+ }): Promise<({
100
+ Opportunity: {
101
+ name: string;
102
+ type: string;
103
+ id: string;
104
+ status: import("../../../../database/api/.generated").$Enums.Status;
105
+ tags: string[];
106
+ identifier: string;
107
+ chainId: number;
108
+ action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
109
+ depositUrl: string | null;
110
+ mainProtocolId: string | null;
111
+ tvl: number;
112
+ apr: number;
113
+ dailyRewards: number;
114
+ };
115
+ } & {
116
+ type: string;
117
+ id: string;
118
+ params: Prisma.JsonValue;
119
+ subType: number | null;
120
+ startTimestamp: bigint;
121
+ endTimestamp: bigint;
122
+ computeChainId: number;
123
+ distributionChainId: number;
124
+ campaignId: string;
125
+ rewardTokenId: string;
126
+ amount: string;
127
+ opportunityId: string;
128
+ creatorAddress: string;
129
+ })[]>;
130
+ /**
131
+ * Upserts a campaign in the database. If the campaign already exists, it updates the existing record;
132
+ * otherwise, it creates a new one.
133
+ *
134
+ * @param {CreateCampaignModel} campaign - The campaign data to be upserted.
135
+ * @returns The upserted campaign record.
136
+ *
137
+ * @throws {Error} If unable to fetch data for the reward token.
138
+ *
139
+ * @remarks
140
+ * This method performs the following steps:
141
+ * 1. Determines the campaign type from the provided campaign data.
142
+ * 2. Fetches or creates the reward token associated with the campaign.
143
+ * 3. Parses the campaign parameters.
144
+ * 4. Computes the opportunity ID based on the campaign data.
145
+ * 5. Constructs the data object for the campaign to be upserted.
146
+ * 6. Upserts the campaign in the database using the constructed data object.
147
+ * 7. Logs an error if the upsert operation fails.
148
+ */
69
149
  static upsert(campaign: CreateCampaignModel): Promise<{
70
150
  type: string;
71
151
  id: string;
@@ -86,7 +166,7 @@ export declare abstract class CampaignRepository {
86
166
  fail: number;
87
167
  }>;
88
168
  /**
89
- * Fetches the campaign static data for a v3 campaign in database
169
+ * Fetches the campaign data for a v3 campaign in database
90
170
  * @param chainId
91
171
  * @param timestamp from which campaigns endTimestamp are filtered
92
172
  * @returns
@@ -49,6 +49,62 @@ export class CampaignRepository {
49
49
  };
50
50
  }
51
51
  // ─── Public Methods ──────────────────────────────────────────────────
52
+ /**
53
+ * Retrieves all past campaigns from the database.
54
+ * A campaign is considered past if the current timestamp is greater than the campaign's end timestamp.
55
+ *
56
+ * @returns A promise that resolves to an array of past campaigns.
57
+ */
58
+ static async getPastCampaigns(chainId) {
59
+ const now = moment().unix();
60
+ return await apiDbClient.campaign.findMany({
61
+ where: {
62
+ computeChainId: chainId,
63
+ endTimestamp: {
64
+ lt: now,
65
+ },
66
+ },
67
+ });
68
+ }
69
+ /**
70
+ * Retrieves all live campaigns from the database.
71
+ * A campaign is considered live if the current timestamp is between the campaign's start and end timestamps.
72
+ *
73
+ * @returns A promise that resolves to an array of live campaigns.
74
+ */
75
+ static async getLiveCampaigns(query) {
76
+ const now = moment().unix();
77
+ const where = {
78
+ ...query,
79
+ endTimestamp: { gte: now },
80
+ startTimestamp: { lte: now },
81
+ };
82
+ return await apiDbClient.campaign.findMany({
83
+ where,
84
+ include: {
85
+ Opportunity: true,
86
+ },
87
+ });
88
+ }
89
+ /**
90
+ * Upserts a campaign in the database. If the campaign already exists, it updates the existing record;
91
+ * otherwise, it creates a new one.
92
+ *
93
+ * @param {CreateCampaignModel} campaign - The campaign data to be upserted.
94
+ * @returns The upserted campaign record.
95
+ *
96
+ * @throws {Error} If unable to fetch data for the reward token.
97
+ *
98
+ * @remarks
99
+ * This method performs the following steps:
100
+ * 1. Determines the campaign type from the provided campaign data.
101
+ * 2. Fetches or creates the reward token associated with the campaign.
102
+ * 3. Parses the campaign parameters.
103
+ * 4. Computes the opportunity ID based on the campaign data.
104
+ * 5. Constructs the data object for the campaign to be upserted.
105
+ * 6. Upserts the campaign in the database using the constructed data object.
106
+ * 7. Logs an error if the upsert operation fails.
107
+ */
52
108
  static async upsert(campaign) {
53
109
  const campaignType = CampaignService.getTypeFromV3(campaign.type);
54
110
  try {
@@ -174,7 +230,7 @@ export class CampaignRepository {
174
230
  return { success: successCampaigns.length, fail: failedCampaigns.length };
175
231
  }
176
232
  /**
177
- * Fetches the campaign static data for a v3 campaign in database
233
+ * Fetches the campaign data for a v3 campaign in database
178
234
  * @param chainId
179
235
  * @param timestamp from which campaigns endTimestamp are filtered
180
236
  * @returns
@@ -1,9 +1,58 @@
1
1
  import type { CampaignUnique, CampaignWithParams, CreateCampaignModel, GetCampaignQueryModel, UpdateCampaignModel, UpdateMetaDataCampaignModel } from "./";
2
- import { CampaignRepository } from "./campaign.repository";
3
2
  import { Campaign as CampaignEnum, type CampaignParameters, type ChainId } from "@sdk";
3
+ 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<{
8
+ type: string;
9
+ id: string;
10
+ params: import("database/api/.generated/runtime/library").JsonValue;
11
+ subType: number | null;
12
+ startTimestamp: bigint;
13
+ endTimestamp: bigint;
14
+ computeChainId: number;
15
+ distributionChainId: number;
16
+ campaignId: string;
17
+ rewardTokenId: string;
18
+ amount: string;
19
+ opportunityId: string;
20
+ creatorAddress: string;
21
+ }[]>;
22
+ static getLiveCampaigns(query?: {
23
+ computeChainId?: number;
24
+ type?: string;
25
+ }): Promise<({
26
+ Opportunity: {
27
+ name: string;
28
+ type: string;
29
+ id: string;
30
+ status: import("../../../../database/api/.generated").$Enums.Status;
31
+ tags: string[];
32
+ identifier: string;
33
+ chainId: number;
34
+ action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
35
+ depositUrl: string | null;
36
+ mainProtocolId: string | null;
37
+ tvl: number;
38
+ apr: number;
39
+ dailyRewards: number;
40
+ };
41
+ } & {
42
+ type: string;
43
+ id: string;
44
+ params: import("database/api/.generated/runtime/library").JsonValue;
45
+ subType: number | null;
46
+ startTimestamp: bigint;
47
+ endTimestamp: bigint;
48
+ computeChainId: number;
49
+ distributionChainId: number;
50
+ campaignId: string;
51
+ rewardTokenId: string;
52
+ amount: string;
53
+ opportunityId: string;
54
+ creatorAddress: string;
55
+ })[]>;
7
56
  static create(campaign: Omit<CreateCampaignModel, "id">): Promise<{
8
57
  type: string;
9
58
  id: string;
@@ -46,6 +95,11 @@ export declare abstract class CampaignService {
46
95
  * @dev back-office function
47
96
  */
48
97
  static moveToOpportunity(campaign: Omit<UpdateCampaignModel, "id">, upsert?: boolean): Promise<string>;
98
+ /**
99
+ * Get the list of campaigns satisfying the query
100
+ * @param query
101
+ * @returns A list of campaigns
102
+ */
49
103
  static findMany(query: GetCampaignQueryModel): Promise<{
50
104
  params: any;
51
105
  chain: {
@@ -228,9 +282,9 @@ export declare abstract class CampaignService {
228
282
  * Convert raw
229
283
  * @param query
230
284
  * @returns A list of opportunities
231
- * TODO: remove this function in favor of prisma client extensions
285
+ * TODO: remove CampaignService function in favor of prisma client extensions
232
286
  */
233
- static format(campaign: NonNullable<Awaited<ReturnType<typeof CampaignRepository.findMany>>>[number]): {
287
+ static format(campaign: NonNullable<Awaited<ReturnType<(typeof CampaignRepository)["findMany"]>>>[number]): {
234
288
  params: any;
235
289
  chain: {
236
290
  name: string;
@@ -1,6 +1,5 @@
1
1
  import { HttpError } from "../../../errors";
2
2
  import { campaignsDynamicData } from "../../../libs/campaigns/campaignsDynamicData";
3
- import { CampaignRepository } from "./campaign.repository";
4
3
  import { OpportunityService } from "../opportunity";
5
4
  import { StatusService } from "../status/status.service";
6
5
  import { TokenRepository } from "../token/token.repository";
@@ -11,6 +10,7 @@ import { log } from "../../../utils/logger";
11
10
  import { Campaign as CampaignEnum, NETWORK_LABELS, } from "@sdk";
12
11
  import { utils } from "ethers";
13
12
  import moment from "moment";
13
+ import { CampaignRepository } from "./campaign.repository";
14
14
  export class CampaignService {
15
15
  static hashId(campaign) {
16
16
  return Bun.hash(`${campaign.distributionChain}${campaign.campaignId}`).toString();
@@ -21,6 +21,12 @@ 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);
26
+ }
27
+ static async getLiveCampaigns(query) {
28
+ return await CampaignRepository.getLiveCampaigns(query);
29
+ }
24
30
  static async create(campaign) {
25
31
  const id = CampaignService.hashId({ distributionChain: campaign.chainId, campaignId: campaign.campaignId });
26
32
  await OpportunityService.createFromCampaign(campaign);
@@ -81,7 +87,7 @@ export class CampaignService {
81
87
  .slice(0, 42);
82
88
  }
83
89
  if (campaign.opportunityIdentifier === undefined) {
84
- throw new HttpError("Bad Request: opportunityIdentifier is required for this campaign type", 400);
90
+ throw new HttpError("Bad Request: opportunityIdentifier is required for CampaignService campaign type", 400);
85
91
  }
86
92
  const updatedCampaign = {
87
93
  ...existingCampaign,
@@ -115,6 +121,11 @@ export class CampaignService {
115
121
  // Return new opportunityId
116
122
  return (await CampaignService.findUniqueOrThrow(campaign)).opportunityId;
117
123
  }
124
+ /**
125
+ * Get the list of campaigns satisfying the query
126
+ * @param query
127
+ * @returns A list of campaigns
128
+ */
118
129
  static async findMany(query) {
119
130
  if (query.subType && !query.type) {
120
131
  throw new HttpError("Bad Request: Cannot specify a subType without a type", 400);
@@ -156,9 +167,7 @@ export class CampaignService {
156
167
  }
157
168
  static async findNextCampaignToProcess(chainId) {
158
169
  const campaigns = await CampaignService.findCampaignsToProcess(chainId);
159
- return {
160
- campaignId: campaigns?.[0]?.campaignId,
161
- };
170
+ return { campaignId: campaigns?.[0]?.campaignId };
162
171
  }
163
172
  static async pickCampaignToProcess(chainId) {
164
173
  const campaigns = await CampaignService.findCampaignsToProcess(chainId);
@@ -241,7 +250,7 @@ export class CampaignService {
241
250
  * Convert raw
242
251
  * @param query
243
252
  * @returns A list of opportunities
244
- * TODO: remove this function in favor of prisma client extensions
253
+ * TODO: remove CampaignService function in favor of prisma client extensions
245
254
  */
246
255
  static format(campaign) {
247
256
  const { DistributionChain, ComputeChain, RewardToken, params, CampaignStatus, ...c } = campaign;
@@ -1,3 +1,2 @@
1
1
  export * from "./campaign.model";
2
2
  export * from "./campaign.service";
3
- export * from "./campaign.controller";
@@ -1,3 +1,2 @@
1
1
  export * from "./campaign.model";
2
2
  export * from "./campaign.service";
3
- export * from "./campaign.controller";
@@ -22,17 +22,8 @@ export declare const ChainController: Elysia<"/chains", false, {
22
22
  query: unknown;
23
23
  headers: unknown;
24
24
  response: {
25
- 200: {
26
- name: string;
27
- id: number;
28
- icon: string;
29
- explorers: {
30
- type: import("../../../../database/api/.generated").$Enums.ExplorerType;
31
- url: string;
32
- id: string;
33
- chainId: number;
34
- }[];
35
- } | null;
25
+ [x: string]: any;
26
+ 200: any;
36
27
  };
37
28
  };
38
29
  };
@@ -48,17 +39,8 @@ export declare const ChainController: Elysia<"/chains", false, {
48
39
  };
49
40
  headers: unknown;
50
41
  response: {
51
- 200: {
52
- name: string;
53
- id: number;
54
- icon: string;
55
- explorers: {
56
- type: import("../../../../database/api/.generated").$Enums.ExplorerType;
57
- url: string;
58
- id: string;
59
- chainId: number;
60
- }[];
61
- }[];
42
+ [x: string]: any;
43
+ 200: any;
62
44
  };
63
45
  };
64
46
  };
@@ -74,7 +56,8 @@ export declare const ChainController: Elysia<"/chains", false, {
74
56
  };
75
57
  headers: unknown;
76
58
  response: {
77
- 200: number;
59
+ [x: string]: any;
60
+ 200: any;
78
61
  };
79
62
  };
80
63
  };
@@ -85,6 +68,8 @@ export declare const ChainController: Elysia<"/chains", false, {
85
68
  patch: {
86
69
  body: {
87
70
  icon?: string | undefined;
71
+ dailyRewards?: number | undefined;
72
+ liveCampaigns?: number | undefined;
88
73
  };
89
74
  params: {
90
75
  chainId: number;
@@ -94,11 +79,8 @@ export declare const ChainController: Elysia<"/chains", false, {
94
79
  authorization: string;
95
80
  };
96
81
  response: {
97
- 200: {
98
- name: string;
99
- id: number;
100
- icon: string;
101
- };
82
+ [x: string]: any;
83
+ 200: any;
102
84
  };
103
85
  };
104
86
  };
@@ -120,14 +102,8 @@ export declare const ChainController: Elysia<"/chains", false, {
120
102
  authorization: string;
121
103
  };
122
104
  response: {
123
- 200: {
124
- Explorer: {
125
- type: import("../../../../database/api/.generated").$Enums.ExplorerType;
126
- url: string;
127
- id: string;
128
- chainId: number;
129
- }[];
130
- };
105
+ [x: string]: any;
106
+ 200: any;
131
107
  };
132
108
  };
133
109
  };
@@ -1,12 +1,14 @@
1
1
  import { AuthorizationHeadersDto, BackOfficeGuard } from "../../../guards/BackOffice.guard";
2
+ import { apiDbClient } from "../../../utils/prisma";
2
3
  import Elysia, { t } from "elysia";
4
+ import { initChainService } from ".";
3
5
  import { ChainResourceDto, ChainUniqueDto, CreateChainDto, GetChainQueryDto, UpdateChainDto, } from "./chain.model";
4
- import { ChainService } from "./chain.service";
6
+ const chainService = initChainService(apiDbClient);
5
7
  // ─── Chains Controller ───────────────────────────────────────────────────────
6
8
  export const ChainController = new Elysia({ prefix: "/chains", detail: { tags: ["Chains"] } })
7
9
  // ─── Get A Chain By Id ───────────────────────────────────────────────
8
10
  .get("/:chainId", async ({ params: { chainId } }) => {
9
- const chain = await ChainService.get(chainId);
11
+ const chain = await chainService.get(chainId);
10
12
  if (!chain)
11
13
  return null;
12
14
  const { Explorer, ...rest } = chain;
@@ -17,7 +19,7 @@ export const ChainController = new Elysia({ prefix: "/chains", detail: { tags: [
17
19
  })
18
20
  // ─── Get All Supported Chains ────────────────────────────────────────
19
21
  .get("/", async ({ query }) => {
20
- const chains = await ChainService.findMany(query);
22
+ const chains = await chainService.findMany(query);
21
23
  return chains.map(({ Explorer, ...chain }) => ({ explorers: Explorer, ...chain }));
22
24
  }, {
23
25
  query: GetChainQueryDto,
@@ -25,18 +27,18 @@ export const ChainController = new Elysia({ prefix: "/chains", detail: { tags: [
25
27
  detail: { description: "List chains supported and integrated by Merkl." },
26
28
  })
27
29
  // ─── Count Chains ────────────────────────────────────────
28
- .get("/count", async ({ query }) => await ChainService.countMany(query), {
30
+ .get("/count", async ({ query }) => await chainService.countMany(query), {
29
31
  query: GetChainQueryDto,
30
32
  detail: { hide: true },
31
33
  })
32
- .patch("/:chainId", async ({ params, body }) => await ChainService.update(params.chainId, body), {
34
+ .patch("/:chainId", async ({ params, body }) => await chainService.update(params.chainId, body), {
33
35
  params: ChainUniqueDto,
34
36
  body: UpdateChainDto,
35
37
  headers: AuthorizationHeadersDto,
36
38
  beforeHandle: BackOfficeGuard,
37
39
  detail: { hide: true },
38
40
  })
39
- .post("/", async ({ body }) => await ChainService.create(body), {
41
+ .post("/", async ({ body }) => await chainService.create(body), {
40
42
  body: CreateChainDto,
41
43
  headers: AuthorizationHeadersDto,
42
44
  beforeHandle: BackOfficeGuard,
@@ -24,6 +24,8 @@ export declare const ChainArrayOptionalDto: import("@sinclair/typebox").TObject<
24
24
  }>;
25
25
  export declare const UpdateChainDto: import("@sinclair/typebox").TObject<{
26
26
  icon: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
27
+ dailyRewards: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
28
+ liveCampaigns: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
27
29
  }>;
28
30
  export declare const CreateChainDto: import("@sinclair/typebox").TObject<{
29
31
  id: import("@sinclair/typebox").TNumber;