@merkl/api 0.20.78 → 0.20.80

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 (30) hide show
  1. package/dist/src/eden/index.d.ts +5998 -14089
  2. package/dist/src/engine/dynamicData/implementations/Clamm.js +8 -0
  3. package/dist/src/index.d.ts +2 -23
  4. package/dist/src/jobs/update-analytics.js +247 -4
  5. package/dist/src/modules/v4/cache/cache.repository.js +3 -52
  6. package/dist/src/modules/v4/campaign/campaign.controller.js +2 -2
  7. package/dist/src/modules/v4/campaign/campaign.service.d.ts +4 -4
  8. package/dist/src/modules/v4/campaign/campaign.service.js +7 -7
  9. package/dist/src/modules/v4/chain/chain.controller.d.ts +1 -0
  10. package/dist/src/modules/v4/chain/chain.repository.d.ts +2 -0
  11. package/dist/src/modules/v4/chain/chain.repository.js +1 -0
  12. package/dist/src/modules/v4/chain/chain.service.d.ts +2 -0
  13. package/dist/src/modules/v4/chain/chain.service.js +3 -0
  14. package/dist/src/modules/v4/chainInteraction/chainInteraction.service.js +1 -1
  15. package/dist/src/modules/v4/dynamicData/dynamicData.service.js +3 -3
  16. package/dist/src/modules/v4/opportunity/opportunity.repository.d.ts +4 -4
  17. package/dist/src/modules/v4/opportunity/opportunity.repository.js +3 -3
  18. package/dist/src/modules/v4/reward/reward.controller.d.ts +0 -22
  19. package/dist/src/modules/v4/reward/reward.controller.js +0 -2
  20. package/dist/src/modules/v4/router.d.ts +2 -23
  21. package/dist/src/modules/v4/router.js +21 -17
  22. package/dist/src/modules/v4/tvl/tvl.service.js +12 -1
  23. package/dist/src/utils/TailSampler.d.ts +8 -0
  24. package/dist/src/utils/TailSampler.js +23 -0
  25. package/dist/tsconfig.package.tsbuildinfo +1 -1
  26. package/package.json +4 -2
  27. package/dist/src/modules/v4/tracer/index.d.ts +0 -1
  28. package/dist/src/modules/v4/tracer/index.js +0 -1
  29. package/dist/src/modules/v4/tvl/index.d.ts +0 -2
  30. package/dist/src/modules/v4/tvl/index.js +0 -2
@@ -875,6 +875,14 @@ export class ClammDynamicData {
875
875
  ]);
876
876
  const rewardToken = rewardTokens[0];
877
877
  distributionMeanAPR = rewardToken.isPoint ? distributionMeanAPR / 365 / 100 : distributionMeanAPR;
878
+ let poolBalanceToken0WithoutBlacklist = poolBalanceToken0 - (blacklistedBalance0 ?? 0);
879
+ poolBalanceToken0WithoutBlacklist = !!poolBalanceToken0WithoutBlacklist
880
+ ? poolBalanceToken0WithoutBlacklist
881
+ : 0.00001;
882
+ let poolBalanceToken1WithoutBlacklist = poolBalanceToken1 - (blacklistedBalance1 ?? 0);
883
+ poolBalanceToken1WithoutBlacklist = !!poolBalanceToken1WithoutBlacklist
884
+ ? poolBalanceToken1WithoutBlacklist
885
+ : 0.00001;
878
886
  dynamicData.push({
879
887
  ...campaign,
880
888
  amm: pool.amm,
@@ -148,7 +148,7 @@ declare const app: Elysia<"", false, {
148
148
  };
149
149
  };
150
150
  } & {
151
- v4: {} | {
151
+ v4: {
152
152
  derive: {};
153
153
  resolve: {};
154
154
  schema: {};
@@ -2887,28 +2887,6 @@ declare const app: Elysia<"", false, {
2887
2887
  };
2888
2888
  };
2889
2889
  };
2890
- } & {
2891
- rewards: {
2892
- total: {
2893
- distributed: {
2894
- "by-opportunities": {
2895
- get: {
2896
- body: unknown;
2897
- params: {};
2898
- query: {
2899
- since: Date;
2900
- };
2901
- headers: {
2902
- authorization: string;
2903
- };
2904
- response: {
2905
- 200: string;
2906
- };
2907
- };
2908
- };
2909
- };
2910
- };
2911
- };
2912
2890
  } & {
2913
2891
  rewards: {
2914
2892
  total: {
@@ -3094,6 +3072,7 @@ declare const app: Elysia<"", false, {
3094
3072
  };
3095
3073
  response: {
3096
3074
  200: {
3075
+ name: string;
3097
3076
  Explorer: {
3098
3077
  id: string;
3099
3078
  type: import("@db/api").$Enums.ExplorerType;
@@ -1,15 +1,258 @@
1
1
  import { CacheService } from "@/modules/v4/cache";
2
2
  import { TTLPresets } from "@/modules/v4/cache/cache.model";
3
+ import { CampaignService } from "@/modules/v4/campaign";
4
+ import { ChainService } from "@/modules/v4/chain/chain.service";
3
5
  import { RewardService } from "@/modules/v4/reward";
4
6
  import { log } from "@/utils/logger";
7
+ import { Client } from "@notionhq/client";
8
+ const notion = new Client({ auth: process.env.NOTION_TOKEN });
9
+ const REWARDS_BY_PROTOCOLS_DATABASE_ID = "1cacfed0d48c80c288acc906291a91c8";
10
+ const REWARDS_BY_CHAINS_DATABASE_ID = "1cacfed0d48c805bb300fa8ae5633a2d";
11
+ const REWARDS_BY_TYPES_DATABASE_ID = "1cbcfed0d48c80d7bdedf45c133cbf63";
12
+ const CAMPAIGNS_BY_CHAINS_DATABASE_ID = "1cbcfed0d48c8001b1ccf5c0900669ea";
13
+ const CAMPAIGNS_BY_PROTOCOLS_DATABASE_ID = "1cecfed0d48c8066b016f580e54a6b33";
14
+ const CAMPAIGNS_BY_TYPES_DATABASE_ID = "1cecfed0d48c80dcb6bccf3ac3889b5b";
15
+ const getCurrentMonthPages = async (databaseId, firstDayOfMonth) => {
16
+ const pagesToModify = await notion.databases.query({
17
+ database_id: databaseId,
18
+ filter: {
19
+ property: "From",
20
+ date: {
21
+ equals: new Date(firstDayOfMonth * 1000).toISOString().split("T")[0],
22
+ },
23
+ },
24
+ });
25
+ return pagesToModify.results;
26
+ };
5
27
  const main = async () => {
28
+ const chains = (await ChainService.findMany({})).reduce((prev, curr) => {
29
+ return Object.assign(prev, { [curr.id]: curr.name });
30
+ }, {});
6
31
  const today = new Date();
7
32
  const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1).getTime() / 1000;
8
33
  const promises = [
9
- CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributed, firstDayOfMonth).then(() => log.info("Total Distributed cache updated successfully")),
10
- CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByChains, firstDayOfMonth).then(() => log.info("Total Distributed by Chains cache updated successfully")),
11
- CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByType, firstDayOfMonth).then(() => log.info("Total Distributed by Type cache updated successfully")),
12
- CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByOpportunities, firstDayOfMonth).then(() => log.info("Total Distributed by Opportunities cache updated successfully")),
34
+ CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByType, firstDayOfMonth).then(async (result) => {
35
+ const pagesToModify = await getCurrentMonthPages(REWARDS_BY_TYPES_DATABASE_ID, firstDayOfMonth);
36
+ const promises = [];
37
+ if (today.getDate() === 1 || pagesToModify.length === 0) {
38
+ for (const [type, monthlyTotalRewards] of Object.entries(result)) {
39
+ promises.push(notion.pages.create({
40
+ parent: { type: "database_id", database_id: REWARDS_BY_TYPES_DATABASE_ID },
41
+ properties: {
42
+ Type: {
43
+ type: "title",
44
+ title: [{ type: "text", text: { content: type } }],
45
+ },
46
+ Rewards: { type: "number", number: monthlyTotalRewards },
47
+ From: { type: "date", date: { start: new Date(firstDayOfMonth * 1000).toISOString().split("T")[0] } },
48
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
49
+ },
50
+ }));
51
+ }
52
+ }
53
+ else {
54
+ for (const page of pagesToModify) {
55
+ promises.push(notion.pages.update({
56
+ page_id: page.id,
57
+ properties: {
58
+ Rewards: {
59
+ type: "number",
60
+ number: result[page.properties.Type
61
+ .title[0].text.content],
62
+ },
63
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
64
+ },
65
+ }));
66
+ }
67
+ await Promise.all(promises);
68
+ log.info("Total Distributed by Type data pushed to Notion successfully");
69
+ }
70
+ }),
71
+ CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByChains, firstDayOfMonth).then(async (result) => {
72
+ const pagesToModify = await getCurrentMonthPages(REWARDS_BY_CHAINS_DATABASE_ID, firstDayOfMonth);
73
+ const promises = [];
74
+ if (today.getDate() === 1 || pagesToModify.length === 0) {
75
+ for (const [chain, monthlyTotalRewards] of Object.entries(result)) {
76
+ promises.push(notion.pages.create({
77
+ parent: { type: "database_id", database_id: REWARDS_BY_CHAINS_DATABASE_ID },
78
+ properties: {
79
+ Chains: {
80
+ type: "title",
81
+ title: [{ type: "text", text: { content: chains[chain] } }],
82
+ },
83
+ Rewards: { type: "number", number: monthlyTotalRewards },
84
+ From: { type: "date", date: { start: new Date(firstDayOfMonth * 1000).toISOString().split("T")[0] } },
85
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
86
+ },
87
+ }));
88
+ }
89
+ }
90
+ else {
91
+ for (const page of pagesToModify) {
92
+ promises.push(notion.pages.update({
93
+ page_id: page.id,
94
+ properties: {
95
+ Rewards: {
96
+ type: "number",
97
+ number: result[Object.keys(chains).find(key => page.properties.Chains.title[0].text.content === chains[key])],
98
+ },
99
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
100
+ },
101
+ }));
102
+ }
103
+ await Promise.all(promises);
104
+ log.info("Total Distributed by Chains data pushed to Notion successfully");
105
+ }
106
+ }),
107
+ CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByProtocol, firstDayOfMonth).then(async (result) => {
108
+ const pagesToModify = await getCurrentMonthPages(REWARDS_BY_PROTOCOLS_DATABASE_ID, firstDayOfMonth);
109
+ const promises = [];
110
+ if (today.getDate() === 1 || pagesToModify.length === 0) {
111
+ for (const [protocol, monthlyTotalRewards] of Object.entries(result)) {
112
+ promises.push(notion.pages.create({
113
+ parent: { type: "database_id", database_id: REWARDS_BY_PROTOCOLS_DATABASE_ID },
114
+ properties: {
115
+ Protocols: { type: "title", title: [{ type: "text", text: { content: protocol } }] },
116
+ Rewards: { type: "number", number: monthlyTotalRewards },
117
+ From: { type: "date", date: { start: new Date(firstDayOfMonth * 1000).toISOString().split("T")[0] } },
118
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
119
+ },
120
+ }));
121
+ }
122
+ }
123
+ else {
124
+ for (const page of pagesToModify) {
125
+ promises.push(notion.pages.update({
126
+ page_id: page.id,
127
+ properties: {
128
+ Rewards: {
129
+ type: "number",
130
+ number: result[page.properties.Protocols.title[0].text.content],
131
+ },
132
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
133
+ },
134
+ }));
135
+ }
136
+ }
137
+ await Promise.all(promises);
138
+ log.info("Total Distributed by Protocols data pushed to Notion successfully");
139
+ }),
140
+ // ─── Campaigns ───────────────────────────────────────────────
141
+ CacheService.set(TTLPresets.DAY_1, CampaignService.countByChains, {
142
+ createdAfter: new Date(firstDayOfMonth * 1000),
143
+ }).then(async (result) => {
144
+ const pagesToModify = await getCurrentMonthPages(CAMPAIGNS_BY_CHAINS_DATABASE_ID, firstDayOfMonth);
145
+ const promises = [];
146
+ if (today.getDate() === 1 || pagesToModify.length === 0) {
147
+ for (const [chain, monthlyTotalCampaigns] of Object.entries(result)) {
148
+ promises.push(notion.pages.create({
149
+ parent: { type: "database_id", database_id: CAMPAIGNS_BY_CHAINS_DATABASE_ID },
150
+ properties: {
151
+ Chains: {
152
+ type: "title",
153
+ title: [{ type: "text", text: { content: chains[chain] } }],
154
+ },
155
+ Campaigns: { type: "number", number: monthlyTotalCampaigns },
156
+ From: { type: "date", date: { start: new Date(firstDayOfMonth * 1000).toISOString().split("T")[0] } },
157
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
158
+ },
159
+ }));
160
+ }
161
+ }
162
+ else {
163
+ for (const page of pagesToModify) {
164
+ promises.push(notion.pages.update({
165
+ page_id: page.id,
166
+ properties: {
167
+ Campaigns: {
168
+ type: "number",
169
+ number: result[Object.keys(chains).find(key => page.properties.Chains.title[0].text.content === chains[key])],
170
+ },
171
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
172
+ },
173
+ }));
174
+ }
175
+ }
176
+ await Promise.all(promises);
177
+ log.info("Campaigns by Chains data pushed to Notion successfully");
178
+ }),
179
+ CacheService.set(TTLPresets.DAY_1, CampaignService.countByProtocols, {
180
+ createdAfter: new Date(firstDayOfMonth * 1000),
181
+ }).then(async (result) => {
182
+ const pagesToModify = await getCurrentMonthPages(CAMPAIGNS_BY_PROTOCOLS_DATABASE_ID, firstDayOfMonth);
183
+ const promises = [];
184
+ if (today.getDate() === 1 || pagesToModify.length === 0) {
185
+ for (const [protocol, monthlyTotalCampaigns] of Object.entries(result)) {
186
+ promises.push(notion.pages.create({
187
+ parent: { type: "database_id", database_id: CAMPAIGNS_BY_PROTOCOLS_DATABASE_ID },
188
+ properties: {
189
+ Protocols: {
190
+ type: "title",
191
+ title: [{ type: "text", text: { content: protocol } }],
192
+ },
193
+ Campaigns: { type: "number", number: monthlyTotalCampaigns },
194
+ From: { type: "date", date: { start: new Date(firstDayOfMonth * 1000).toISOString().split("T")[0] } },
195
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
196
+ },
197
+ }));
198
+ }
199
+ }
200
+ else {
201
+ for (const page of pagesToModify) {
202
+ promises.push(notion.pages.update({
203
+ page_id: page.id,
204
+ properties: {
205
+ Campaigns: {
206
+ type: "number",
207
+ number: result[page.properties.Protocols.title[0].text.content],
208
+ },
209
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
210
+ },
211
+ }));
212
+ }
213
+ }
214
+ await Promise.all(promises);
215
+ log.info("Campaigns by Protocols data pushed to Notion successfully");
216
+ }),
217
+ CacheService.set(TTLPresets.DAY_1, CampaignService.countByTypes, {
218
+ createdAfter: new Date(firstDayOfMonth * 1000),
219
+ }).then(async (result) => {
220
+ const pagesToModify = await getCurrentMonthPages(CAMPAIGNS_BY_TYPES_DATABASE_ID, firstDayOfMonth);
221
+ const promises = [];
222
+ if (today.getDate() === 1 || pagesToModify.length === 0) {
223
+ for (const [type, monthlyTotalCampaigns] of Object.entries(result)) {
224
+ promises.push(notion.pages.create({
225
+ parent: { type: "database_id", database_id: CAMPAIGNS_BY_TYPES_DATABASE_ID },
226
+ properties: {
227
+ Types: {
228
+ type: "title",
229
+ title: [{ type: "text", text: { content: type } }],
230
+ },
231
+ Campaigns: { type: "number", number: monthlyTotalCampaigns },
232
+ From: { type: "date", date: { start: new Date(firstDayOfMonth * 1000).toISOString().split("T")[0] } },
233
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
234
+ },
235
+ }));
236
+ }
237
+ }
238
+ else {
239
+ for (const page of pagesToModify) {
240
+ promises.push(notion.pages.update({
241
+ page_id: page.id,
242
+ properties: {
243
+ Campaigns: {
244
+ type: "number",
245
+ number: result[page.properties.Types
246
+ .title[0].text.content],
247
+ },
248
+ To: { type: "date", date: { start: today.toISOString().split("T")[0] } },
249
+ },
250
+ }));
251
+ }
252
+ }
253
+ await Promise.all(promises);
254
+ log.info("Campaigns by Types data pushed to Notion successfully");
255
+ }),
13
256
  ];
14
257
  await Promise.all(promises);
15
258
  };
@@ -1,62 +1,13 @@
1
1
  import { REDIS_READ_TIMEOUT, REDIS_RETRIES, REDIS_WRITE_TIMEOUT, redisClient } from "@/cache/redis";
2
- import { record } from "@elysiajs/opentelemetry";
3
2
  import { withRetry, withTimeout } from "@sdk";
4
3
  export class CacheRepository {
5
4
  static async set(ttl, key, value) {
6
- await record("redis.set", async (span) => {
7
- span.setAttribute("db.system", "redis");
8
- span.setAttribute("net.transport", "ip_tcp");
9
- span.setAttribute("db.statement", `set ${key} ${value} ${ttl}`);
10
- const startTime = Date.now();
11
- try {
12
- const result = await withRetry(withTimeout, [redisClient.set(key, value, { EX: ttl }), REDIS_WRITE_TIMEOUT], REDIS_RETRIES);
13
- span.setAttribute("db.redis.response_time", Date.now() - startTime);
14
- return result;
15
- }
16
- catch (error) {
17
- span.setStatus({ code: 2 }); // OpenTelemetry StatusCode.ERROR
18
- span.setAttribute("error.message", error.message);
19
- span.recordException(error);
20
- throw error;
21
- }
22
- });
5
+ await withRetry(withTimeout, [redisClient.set(key, value, { EX: ttl }), REDIS_WRITE_TIMEOUT], REDIS_RETRIES);
23
6
  }
24
7
  static async ttl(key) {
25
- return await record("redis.ttl", async (span) => {
26
- span.setAttribute("db.system", "redis");
27
- span.setAttribute("net.transport", "ip_tcp");
28
- span.setAttribute("db.statement", `get ${key}`);
29
- const startTime = Date.now();
30
- try {
31
- const result = await withRetry(withTimeout, [redisClient.ttl(key), REDIS_READ_TIMEOUT], REDIS_RETRIES);
32
- span.setAttribute("db.redis.response_time", Date.now() - startTime);
33
- return result;
34
- }
35
- catch (error) {
36
- span.setStatus({ code: 2 }); // OpenTelemetry StatusCode.ERROR
37
- span.setAttribute("error.message", error.message);
38
- span.recordException(error);
39
- throw error;
40
- }
41
- });
8
+ return await withRetry(withTimeout, [redisClient.ttl(key), REDIS_READ_TIMEOUT], REDIS_RETRIES);
42
9
  }
43
10
  static async get(key) {
44
- return await record("redis.get", async (span) => {
45
- span.setAttribute("db.system", "redis");
46
- span.setAttribute("net.transport", "ip_tcp");
47
- span.setAttribute("db.statement", `get ${key}`);
48
- const startTime = Date.now();
49
- try {
50
- const result = await withRetry(withTimeout, [redisClient.get(key), REDIS_READ_TIMEOUT], REDIS_RETRIES);
51
- span.setAttribute("db.redis.response_time", Date.now() - startTime);
52
- return result;
53
- }
54
- catch (error) {
55
- span.setStatus({ code: 2 }); // OpenTelemetry StatusCode.ERROR
56
- span.setAttribute("error.message", error.message);
57
- span.recordException(error);
58
- throw error;
59
- }
60
- });
11
+ return await withRetry(withTimeout, [redisClient.get(key), REDIS_READ_TIMEOUT], REDIS_RETRIES);
61
12
  }
62
13
  }
@@ -152,5 +152,5 @@ export const CampaignController = new Elysia({ prefix: "/campaigns", detail: { t
152
152
  detail: { hide: true },
153
153
  })
154
154
  .get("count/by-chains", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, CampaignService.countByChains, query))
155
- .get("/count/by-types", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, CampaignService.countByType, query))
156
- .get("/count/by-protocols", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, CampaignService.countByProtocol, query));
155
+ .get("/count/by-types", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, CampaignService.countByTypes, query))
156
+ .get("/count/by-protocols", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, CampaignService.countByProtocols, query));
@@ -346,7 +346,7 @@ export declare abstract class CampaignService {
346
346
  opportunityId: string;
347
347
  }[]>>;
348
348
  static countByChains(query: GetCampaignQueryModel): Promise<Record<string, number>>;
349
- static findAndGroupByType(query: GetCampaignQueryModel): Promise<Map<string, {
349
+ static findAndGroupByTypes(query: GetCampaignQueryModel): Promise<Map<string, {
350
350
  params: any;
351
351
  chain: {
352
352
  id: number;
@@ -419,8 +419,8 @@ export declare abstract class CampaignService {
419
419
  amount: string;
420
420
  opportunityId: string;
421
421
  }[]>>;
422
- static countByType(query: GetCampaignQueryModel): Promise<Record<string, number>>;
423
- static findAndGroupByProtocol(query: GetCampaignQueryModel): Promise<Map<string | null, {
422
+ static countByTypes(query: GetCampaignQueryModel): Promise<Record<string, number>>;
423
+ static findAndGroupByProtocols(query: GetCampaignQueryModel): Promise<Map<string | null, {
424
424
  params: any;
425
425
  chain: {
426
426
  id: number;
@@ -493,7 +493,7 @@ export declare abstract class CampaignService {
493
493
  amount: string;
494
494
  opportunityId: string;
495
495
  }[]>>;
496
- static countByProtocol(query: GetCampaignQueryModel): Promise<Record<string, number>>;
496
+ static countByProtocols(query: GetCampaignQueryModel): Promise<Record<string, number>>;
497
497
  static countBy<T>(campaignsMap: Map<T, ReturnType<(typeof CampaignService)["format"]>[]>): Record<string, number>;
498
498
  /**
499
499
  * Counts the number of campaigns that complies to query
@@ -138,17 +138,17 @@ export class CampaignService {
138
138
  static async countByChains(query) {
139
139
  return CampaignService.countBy(await CampaignService.findAndGroupByChains({ ...query, items: 0 }));
140
140
  }
141
- static async findAndGroupByType(query) {
141
+ static async findAndGroupByTypes(query) {
142
142
  return Map.groupBy(await CampaignService.findMany(query), campaign => campaign.type);
143
143
  }
144
- static async countByType(query) {
145
- return CampaignService.countBy(await CampaignService.findAndGroupByType({ ...query, items: 0 }));
144
+ static async countByTypes(query) {
145
+ return CampaignService.countBy(await CampaignService.findAndGroupByTypes({ ...query, items: 0 }));
146
146
  }
147
- static async findAndGroupByProtocol(query) {
148
- return Map.groupBy(await CampaignService.findMany(query), campaign => campaign.Opportunity.mainProtocolId);
147
+ static async findAndGroupByProtocols(query) {
148
+ return Map.groupBy(await CampaignService.findMany({ ...query, withOpportunity: true }), campaign => campaign.Opportunity.mainProtocolId);
149
149
  }
150
- static async countByProtocol(query) {
151
- return CampaignService.countBy(await CampaignService.findAndGroupByType({ ...query, items: 0 }));
150
+ static async countByProtocols(query) {
151
+ return CampaignService.countBy(await CampaignService.findAndGroupByProtocols({ ...query, items: 0 }));
152
152
  }
153
153
  static countBy(campaignsMap) {
154
154
  const count = {};
@@ -125,6 +125,7 @@ export declare const ChainController: Elysia<"/chains", false, {
125
125
  };
126
126
  response: {
127
127
  200: {
128
+ name: string;
128
129
  Explorer: {
129
130
  id: string;
130
131
  type: import("@db/api").$Enums.ExplorerType;
@@ -63,6 +63,7 @@ export declare class ChainRepository {
63
63
  * @returns
64
64
  */
65
65
  static create(data: CreateChainModel): Promise<{
66
+ name: string;
66
67
  Explorer: {
67
68
  id: string;
68
69
  type: import("@db/api").$Enums.ExplorerType;
@@ -71,6 +72,7 @@ export declare class ChainRepository {
71
72
  }[];
72
73
  }>;
73
74
  static findUniqueOrThrow(id: number): Promise<{
75
+ name: string;
74
76
  Explorer: {
75
77
  id: string;
76
78
  type: import("@db/api").$Enums.ExplorerType;
@@ -64,6 +64,7 @@ export class ChainRepository {
64
64
  },
65
65
  select: {
66
66
  Explorer: true,
67
+ name: true,
67
68
  },
68
69
  });
69
70
  }
@@ -35,6 +35,7 @@ export declare abstract class ChainService {
35
35
  */
36
36
  static getSupportedIds(): Promise<number[]>;
37
37
  static create(chain: CreateChainModel): Promise<{
38
+ name: string;
38
39
  Explorer: {
39
40
  id: string;
40
41
  type: import("@db/api").$Enums.ExplorerType;
@@ -52,4 +53,5 @@ export declare abstract class ChainService {
52
53
  name: string;
53
54
  icon: string;
54
55
  }>;
56
+ static getName(id: number): Promise<string>;
55
57
  }
@@ -47,4 +47,7 @@ export class ChainService {
47
47
  static async updateDailyRewards(id, dailyRewards) {
48
48
  return await ChainRepository.update(id, { dailyRewards });
49
49
  }
50
+ static async getName(id) {
51
+ return (await ChainRepository.findUniqueOrThrow(id)).name;
52
+ }
50
53
  }
@@ -1,4 +1,4 @@
1
+ import { TracerService } from "@/modules/v4/tracer/tracer.service";
1
2
  import { ChainInteractionService } from "@sdk";
2
- import { TracerService } from "../tracer";
3
3
  const ChainInteractionServiceWrapper = TracerService.createTracedProxy(ChainInteractionService, "ChainInteractionService");
4
4
  export { ChainInteractionServiceWrapper as ChainInteractionService };
@@ -1,14 +1,14 @@
1
1
  import { dynamicDataBuilderFactory } from "@/engine/dynamicData/factory";
2
2
  import { HttpError } from "@/errors";
3
+ import { OpportunityRepository } from "@/modules/v4/opportunity/opportunity.repository";
3
4
  import { OpportunityService } from "@/modules/v4/opportunity/opportunity.service";
5
+ import { RewardService } from "@/modules/v4/reward/reward.service";
6
+ import { TvlService } from "@/modules/v4/tvl/tvl.service";
4
7
  import bigintToString from "@/utils/bigintToString";
5
8
  import { log } from "@/utils/logger";
6
9
  import { Campaign, NETWORK_LABELS } from "@sdk";
7
10
  import { Campaign as CampaignEnum } from "@sdk";
8
11
  import { AprService } from "../apr";
9
- import { OpportunityRepository } from "../opportunity/opportunity.repository";
10
- import { RewardService } from "../reward";
11
- import { TvlService } from "../tvl";
12
12
  export class DynamicDataService {
13
13
  static async queryERC20DynamicData(chainId, tokenAddress, rewardTokenAddress, symbolRewardToken, decimals = 18) {
14
14
  const campaigns = [
@@ -1,9 +1,9 @@
1
+ import type { AprRecord } from "@/modules/v4/apr/apr.model";
2
+ import type { Campaign } from "@/modules/v4/campaign/campaign.model";
3
+ import { type DailyRewardsRecord } from "@/modules/v4/reward";
4
+ import type { TvlRecord } from "@/modules/v4/tvl/tvl.model";
1
5
  import { type Prisma, Status } from "@db/api";
2
6
  import type { MerklChainId } from "@sdk";
3
- import { type AprRecord } from "../apr";
4
- import type { Campaign } from "../campaign";
5
- import { type DailyRewardsRecord } from "../reward";
6
- import { type TvlRecord } from "../tvl";
7
7
  import type { CreateOpportunityModel, GetOpportunitiesQueryModel, Opportunity } from "./opportunity.model";
8
8
  export declare abstract class OpportunityRepository {
9
9
  #private;
@@ -1,11 +1,11 @@
1
+ import { AprService } from "@/modules/v4/apr/apr.service";
1
2
  import { ProtocolService } from "@/modules/v4/protocol/protocol.service";
3
+ import { RewardService } from "@/modules/v4/reward";
4
+ import { TvlService } from "@/modules/v4/tvl/tvl.service";
2
5
  import { log } from "@/utils/logger";
3
6
  import { apiDbClient } from "@db";
4
7
  import { Status } from "@db/api";
5
8
  import moment from "moment";
6
- import { AprService } from "../apr";
7
- import { RewardService } from "../reward";
8
- import { TvlService } from "../tvl";
9
9
  export class OpportunityRepository {
10
10
  // ─── Utils ───────────────────────────────────────────────────────────
11
11
  static #transformQueryToPrismaFilters(query) {
@@ -347,28 +347,6 @@ export declare const RewardController: Elysia<"/rewards", false, {
347
347
  };
348
348
  };
349
349
  };
350
- } & {
351
- rewards: {
352
- total: {
353
- distributed: {
354
- "by-opportunities": {
355
- get: {
356
- body: unknown;
357
- params: {};
358
- query: {
359
- since: Date;
360
- };
361
- headers: {
362
- authorization: string;
363
- };
364
- response: {
365
- 200: string;
366
- };
367
- };
368
- };
369
- };
370
- };
371
- };
372
350
  } & {
373
351
  rewards: {
374
352
  total: {
@@ -3,7 +3,6 @@ import { AuthorizationHeadersDto, EngineGuard } from "@/guards/Engine.guard";
3
3
  import { ChainDto } from "@/modules/v4/accounting/accounting.model";
4
4
  import { CampaignService } from "@/modules/v4/campaign/campaign.service";
5
5
  import { TokenService } from "@/modules/v4/token/token.service";
6
- import bigintToString from "@/utils/bigintToString";
7
6
  import { throwOnInvalidRequiredAddress, throwOnUnsupportedChainId } from "@/utils/throw";
8
7
  import Elysia, { t } from "elysia";
9
8
  import { CacheService } from "../cache";
@@ -132,7 +131,6 @@ export const RewardController = new Elysia({ prefix: "/rewards", detail: { tags:
132
131
  detail: { hide: true },
133
132
  })
134
133
  .get("/total/distributed", async ({ query }) => await RewardService.getTotalDistributed(query.since.getTime() / 1000))
135
- .get("/total/distributed/by-opportunities", async ({ query }) => JSON.stringify(bigintToString(Array.from((await RewardService.getTotalDistributedByOpportunities(query.since.getTime() / 1000)).entries()))))
136
134
  .get("/total/distributed/by-chains", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, RewardService.getTotalDistributedByChains, query.since.getTime() / 1000))
137
135
  .get("/total/distributed/by-types", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, RewardService.getTotalDistributedByType, query.since.getTime() / 1000))
138
136
  .get("/total/distributed/by-protocols", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, RewardService.getTotalDistributedByProtocol, query.since.getTime() / 1000));