@merkl/api 0.20.167 → 0.20.169

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 (31) hide show
  1. package/dist/database/index.js +1 -1
  2. package/dist/src/eden/index.d.ts +300 -56
  3. package/dist/src/engine/deprecated/dynamicData/factory.js +3 -1
  4. package/dist/src/engine/metadata/factory.js +2 -0
  5. package/dist/src/index.d.ts +112 -18
  6. package/dist/src/jobs/update-analytics.js +79 -75
  7. package/dist/src/modules/v4/apr/apr.model.d.ts +2 -6
  8. package/dist/src/modules/v4/apr/apr.model.js +1 -3
  9. package/dist/src/modules/v4/campaign/campaign.controller.d.ts +25 -0
  10. package/dist/src/modules/v4/campaign/campaign.controller.js +8 -1
  11. package/dist/src/modules/v4/campaign/campaign.repository.d.ts +16 -0
  12. package/dist/src/modules/v4/campaign/campaign.repository.js +18 -0
  13. package/dist/src/modules/v4/campaign/campaign.service.d.ts +10 -0
  14. package/dist/src/modules/v4/campaign/campaign.service.js +7 -0
  15. package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +87 -18
  16. package/dist/src/modules/v4/opportunity/opportunity.controller.js +8 -2
  17. package/dist/src/modules/v4/opportunity/opportunity.model.d.ts +4 -12
  18. package/dist/src/modules/v4/opportunity/opportunity.repository.d.ts +0 -20
  19. package/dist/src/modules/v4/opportunity/opportunity.repository.js +10 -2
  20. package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +14 -27
  21. package/dist/src/modules/v4/opportunity/opportunity.service.js +62 -1
  22. package/dist/src/modules/v4/programPayload/programPayload.service.js +3 -0
  23. package/dist/src/modules/v4/reward/reward.controller.js +1 -1
  24. package/dist/src/modules/v4/reward/reward.service.d.ts +1 -7
  25. package/dist/src/modules/v4/reward/reward.service.js +1 -1
  26. package/dist/src/modules/v4/router.d.ts +112 -18
  27. package/dist/src/modules/v4/token/token.controller.js +6 -1
  28. package/dist/src/modules/v4/tvl/tvl.model.d.ts +2 -6
  29. package/dist/src/modules/v4/tvl/tvl.model.js +1 -3
  30. package/dist/tsconfig.package.tsbuildinfo +1 -1
  31. package/package.json +1 -1
@@ -501,16 +501,12 @@ declare const app: Elysia<"", false, {
501
501
  cumulated: number;
502
502
  timestamp: bigint;
503
503
  breakdowns: ({
504
- id: string;
505
504
  value: number;
506
- aprRecordId: string;
507
505
  distributionType: import("@db/api").$Enums.DistributionType;
508
506
  identifier: string;
509
507
  type: "CAMPAIGN";
510
508
  } | {
511
- id: string;
512
509
  value: number;
513
- aprRecordId: string;
514
510
  identifier: string;
515
511
  type: import("@db/api").$Enums.AprType;
516
512
  })[];
@@ -521,10 +517,8 @@ declare const app: Elysia<"", false, {
521
517
  timestamp: bigint;
522
518
  breakdowns: {
523
519
  type: import("@db/api").$Enums.TvlType;
524
- id: string;
525
520
  identifier: string;
526
521
  value: number;
527
- tvlRecordId: string;
528
522
  }[];
529
523
  };
530
524
  rewardsRecord: {
@@ -718,6 +712,93 @@ declare const app: Elysia<"", false, {
718
712
  };
719
713
  };
720
714
  };
715
+ } & {
716
+ opportunities: {
717
+ bins: {
718
+ apr: {
719
+ get: {
720
+ body: unknown;
721
+ params: {};
722
+ query: {
723
+ status?: string | undefined;
724
+ search?: string | undefined;
725
+ sort?: string | undefined;
726
+ type?: string | undefined;
727
+ name?: string | undefined;
728
+ tokens?: string | undefined;
729
+ items?: number | undefined;
730
+ tags?: string | undefined;
731
+ identifier?: string | undefined;
732
+ page?: number | undefined;
733
+ action?: string | undefined;
734
+ campaignId?: string | undefined;
735
+ creatorAddress?: string | undefined;
736
+ chainId?: string | undefined;
737
+ mainProtocolId?: string | undefined;
738
+ campaigns?: boolean | undefined;
739
+ point?: boolean | undefined;
740
+ rewardTokenSymbol?: string | undefined;
741
+ order?: string | undefined;
742
+ test?: boolean | undefined;
743
+ minimumTvl?: number | undefined;
744
+ };
745
+ headers: unknown;
746
+ response: {
747
+ 200: {
748
+ min: number;
749
+ max: number;
750
+ overThreshold: number;
751
+ binWidth: number;
752
+ bins: any[];
753
+ };
754
+ };
755
+ };
756
+ };
757
+ };
758
+ };
759
+ } & {
760
+ opportunities: {
761
+ bins: {
762
+ tvl: {
763
+ get: {
764
+ body: unknown;
765
+ params: {};
766
+ query: {
767
+ status?: string | undefined;
768
+ search?: string | undefined;
769
+ sort?: string | undefined;
770
+ type?: string | undefined;
771
+ name?: string | undefined;
772
+ tokens?: string | undefined;
773
+ items?: number | undefined;
774
+ tags?: string | undefined;
775
+ identifier?: string | undefined;
776
+ page?: number | undefined;
777
+ action?: string | undefined;
778
+ campaignId?: string | undefined;
779
+ creatorAddress?: string | undefined;
780
+ chainId?: string | undefined;
781
+ mainProtocolId?: string | undefined;
782
+ campaigns?: boolean | undefined;
783
+ point?: boolean | undefined;
784
+ rewardTokenSymbol?: string | undefined;
785
+ order?: string | undefined;
786
+ test?: boolean | undefined;
787
+ minimumTvl?: number | undefined;
788
+ };
789
+ headers: unknown;
790
+ response: {
791
+ 200: {
792
+ min: number;
793
+ max: number;
794
+ binWidth: number;
795
+ bins: any[];
796
+ };
797
+ };
798
+ };
799
+ };
800
+ };
801
+ };
721
802
  } & {
722
803
  opportunities: {
723
804
  ":id": {
@@ -749,10 +830,8 @@ declare const app: Elysia<"", false, {
749
830
  cumulated: number;
750
831
  breakdowns: {
751
832
  type: "CAMPAIGN" | "TOKEN" | "PROTOCOL";
752
- id: string;
753
833
  identifier: string;
754
834
  value: number;
755
- aprRecordId: string;
756
835
  }[];
757
836
  } | undefined;
758
837
  tvlRecord?: {
@@ -760,10 +839,8 @@ declare const app: Elysia<"", false, {
760
839
  timestamp: string | bigint;
761
840
  breakdowns: {
762
841
  type: "TOKEN" | "PROTOCOL";
763
- id: string;
764
842
  identifier: string;
765
843
  value: number;
766
- tvlRecordId: string;
767
844
  }[];
768
845
  } | undefined;
769
846
  rewardsRecord?: {
@@ -888,10 +965,8 @@ declare const app: Elysia<"", false, {
888
965
  cumulated: number;
889
966
  breakdowns: {
890
967
  type: "CAMPAIGN" | "TOKEN" | "PROTOCOL";
891
- id: string;
892
968
  identifier: string;
893
969
  value: number;
894
- aprRecordId: string;
895
970
  }[];
896
971
  } | undefined;
897
972
  tvlRecord?: {
@@ -899,10 +974,8 @@ declare const app: Elysia<"", false, {
899
974
  timestamp: string | bigint;
900
975
  breakdowns: {
901
976
  type: "TOKEN" | "PROTOCOL";
902
- id: string;
903
977
  identifier: string;
904
978
  value: number;
905
- tvlRecordId: string;
906
979
  }[];
907
980
  } | undefined;
908
981
  rewardsRecord?: {
@@ -1064,10 +1137,8 @@ declare const app: Elysia<"", false, {
1064
1137
  cumulated: number;
1065
1138
  breakdowns: {
1066
1139
  type: "CAMPAIGN" | "TOKEN" | "PROTOCOL";
1067
- id: string;
1068
1140
  identifier: string;
1069
1141
  value: number;
1070
- aprRecordId: string;
1071
1142
  }[];
1072
1143
  } | undefined;
1073
1144
  tvlRecord?: {
@@ -1075,10 +1146,8 @@ declare const app: Elysia<"", false, {
1075
1146
  timestamp: string | bigint;
1076
1147
  breakdowns: {
1077
1148
  type: "TOKEN" | "PROTOCOL";
1078
- id: string;
1079
1149
  identifier: string;
1080
1150
  value: number;
1081
- tvlRecordId: string;
1082
1151
  }[];
1083
1152
  } | undefined;
1084
1153
  rewardsRecord?: {
@@ -1771,6 +1840,31 @@ declare const app: Elysia<"", false, {
1771
1840
  };
1772
1841
  };
1773
1842
  };
1843
+ } & {
1844
+ ":id": {
1845
+ timeseries: {
1846
+ get: {
1847
+ body: unknown;
1848
+ params: {
1849
+ id: string;
1850
+ };
1851
+ query: unknown;
1852
+ headers: unknown;
1853
+ response: {
1854
+ 200: {
1855
+ tvlRecords: {
1856
+ total: number;
1857
+ timestamp: bigint;
1858
+ }[];
1859
+ aprRecords: {
1860
+ timestamp: bigint;
1861
+ cumulated: number;
1862
+ }[];
1863
+ };
1864
+ };
1865
+ };
1866
+ };
1867
+ };
1774
1868
  } & {
1775
1869
  "campaigns-to-process": {
1776
1870
  index: {
@@ -57,56 +57,11 @@ const main = async () => {
57
57
  }, {});
58
58
  const now = new Date();
59
59
  const today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 0, 0, 0, 0)).getTime() / 1000;
60
- const firstDayOfMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1, // Day 1 of the month
61
- 0, // 0 hours
62
- 0, // 0 minutes
63
- 0, // 0 seconds
64
- 0 // 0 milliseconds
65
- )).getTime() / 1000;
60
+ const firstDayOfMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1, 0, 0, 0, 0)).getTime() / 1000;
66
61
  const promises = [
67
- // ─── Rewards By Types ────────────────────────────────────────
68
- CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByType, firstDayOfMonth).then(async (result) => {
69
- const currentMonthPages = await getPagesOfTheMonth(MONTHLY_REWARDS_BY_TYPES_DATABASE_ID);
70
- const promises = [];
71
- // ─── Check If Page Already Exists ────────────────────
72
- for (const type of Object.keys(result)) {
73
- const page = currentMonthPages.find(page => "properties" in page &&
74
- page.properties.Types.title[0].text.content === type);
75
- // ─── If Page Exists, Update It ───────────────
76
- if (page) {
77
- promises.push(notion.pages.update({
78
- page_id: page.id,
79
- properties: {
80
- Rewards: {
81
- type: "number",
82
- number: result[type],
83
- },
84
- To: { type: "date", date: { start: now.toISOString().split("T")[0] } },
85
- },
86
- }));
87
- // ─── Else, Create It ─────────────────
88
- }
89
- else {
90
- promises.push(notion.pages.create({
91
- parent: { type: "database_id", database_id: MONTHLY_REWARDS_BY_TYPES_DATABASE_ID },
92
- properties: {
93
- Types: {
94
- type: "title",
95
- title: [{ type: "text", text: { content: type } }],
96
- },
97
- Rewards: { type: "number", number: result[type] },
98
- From: { type: "date", date: { start: new Date(firstDayOfMonth * 1000).toISOString().split("T")[0] } },
99
- To: { type: "date", date: { start: now.toISOString().split("T")[0] } },
100
- },
101
- }));
102
- }
103
- }
104
- // ─── Run All The Promises In Parallel ────────────────
105
- await Promise.all(promises);
106
- log.info("Total Distributed by Types data pushed to Notion successfully");
107
- }),
108
- // ─── Rewards By Chains ───────────────────────────────────────
109
- CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByChains, firstDayOfMonth).then(async (result) => {
62
+ // ─── Monthly Rewards ─────────────────────────────────────────────────────────
63
+ // ─── By Chains ───────────────────────────────────────────────
64
+ CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByChain, firstDayOfMonth).then(async (result) => {
110
65
  const currentMonthPages = await getPagesOfTheMonth(MONTHLY_REWARDS_BY_CHAINS_DATABASE_ID);
111
66
  const promises = [];
112
67
  for (const chain of Object.keys(result)) {
@@ -143,7 +98,7 @@ const main = async () => {
143
98
  await Promise.all(promises);
144
99
  log.info("Total Distributed by Chains data pushed to Notion successfully");
145
100
  }),
146
- // ─── Rewards By Protocols ────────────────────────────────────
101
+ // ─── By Protocols ────────────────────────────────────────────
147
102
  CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByProtocol, firstDayOfMonth).then(async (result) => {
148
103
  const currentMonthPages = await getPagesOfTheMonth(MONTHLY_REWARDS_BY_PROTOCOLS_DATABASE_ID);
149
104
  const promises = [];
@@ -181,44 +136,50 @@ const main = async () => {
181
136
  await Promise.all(promises);
182
137
  log.info("Total Distributed by Protocols data pushed to Notion successfully");
183
138
  }),
184
- // ─── Daily Rewards ───────────────────────────────────────────
185
- CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByProtocol, today).then(async (result) => {
186
- const pagesOfTheDay = await getPagesOfTheDay(DAILY_REWARDS_BY_PROTOCOLS_DATABASE_ID);
139
+ // ─── By Types ────────────────────────────────────────────────
140
+ CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByType, firstDayOfMonth).then(async (result) => {
141
+ const currentMonthPages = await getPagesOfTheMonth(MONTHLY_REWARDS_BY_TYPES_DATABASE_ID);
187
142
  const promises = [];
188
- for (const protocol of Object.keys(result)) {
189
- const page = pagesOfTheDay.find(page => "properties" in page &&
190
- page.properties.Protocols.title[0].text.content === protocol);
143
+ // ─── Check If Page Already Exists ────────────────────
144
+ for (const type of Object.keys(result)) {
145
+ const page = currentMonthPages.find(page => "properties" in page &&
146
+ page.properties.Types.title[0].text.content === type);
147
+ // ─── If Page Exists, Update It ───────────────
191
148
  if (page) {
192
149
  promises.push(notion.pages.update({
193
150
  page_id: page.id,
194
151
  properties: {
195
152
  Rewards: {
196
153
  type: "number",
197
- number: result[page.properties.Protocols.title[0].text.content],
154
+ number: result[type],
198
155
  },
199
- Date: { type: "date", date: { start: now.toISOString().split("T")[0] } },
156
+ To: { type: "date", date: { start: now.toISOString().split("T")[0] } },
200
157
  },
201
158
  }));
159
+ // ─── Else, Create It ─────────────────
202
160
  }
203
161
  else {
204
162
  promises.push(notion.pages.create({
205
- parent: { type: "database_id", database_id: DAILY_REWARDS_BY_PROTOCOLS_DATABASE_ID },
163
+ parent: { type: "database_id", database_id: MONTHLY_REWARDS_BY_TYPES_DATABASE_ID },
206
164
  properties: {
207
- Protocols: { type: "title", title: [{ type: "text", text: { content: protocol } }] },
208
- Rewards: { type: "number", number: result[protocol] },
209
- Date: {
210
- type: "date",
211
- date: { start: now.toISOString().split("T")[0] },
165
+ Types: {
166
+ type: "title",
167
+ title: [{ type: "text", text: { content: type } }],
212
168
  },
169
+ Rewards: { type: "number", number: result[type] },
170
+ From: { type: "date", date: { start: new Date(firstDayOfMonth * 1000).toISOString().split("T")[0] } },
171
+ To: { type: "date", date: { start: now.toISOString().split("T")[0] } },
213
172
  },
214
173
  }));
215
174
  }
216
175
  }
176
+ // ─── Run All The Promises In Parallel ────────────────
217
177
  await Promise.all(promises);
218
- log.info("Total Distributed by Protocols data pushed to Notion successfully");
178
+ log.info("Total Distributed by Types data pushed to Notion successfully");
219
179
  }),
180
+ // ─── Daily Rewards ───────────────────────────────────────────────────────────
220
181
  // ─── By Chains ───────────────────────────────────────────────
221
- CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByChains, today).then(async (result) => {
182
+ CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByChain, today).then(async (result) => {
222
183
  const pagesOfTheDay = await getPagesOfTheDay(DAILY_REWARDS_BY_CHAINS_DATABASE_ID);
223
184
  const promises = [];
224
185
  for (const chain of Object.keys(result)) {
@@ -254,7 +215,43 @@ const main = async () => {
254
215
  await Promise.all(promises);
255
216
  log.info("Total Distributed by Chains data pushed to Notion successfully");
256
217
  }),
257
- // ─── Daily Rewards By Types ──────────────────────────────────
218
+ // ─── By Protocols ────────────────────────────────────────────
219
+ CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByProtocol, today).then(async (result) => {
220
+ const pagesOfTheDay = await getPagesOfTheDay(DAILY_REWARDS_BY_PROTOCOLS_DATABASE_ID);
221
+ const promises = [];
222
+ for (const protocol of Object.keys(result)) {
223
+ const page = pagesOfTheDay.find(page => "properties" in page &&
224
+ page.properties.Protocols.title[0].text.content === protocol);
225
+ if (page) {
226
+ promises.push(notion.pages.update({
227
+ page_id: page.id,
228
+ properties: {
229
+ Rewards: {
230
+ type: "number",
231
+ number: result[page.properties.Protocols.title[0].text.content],
232
+ },
233
+ Date: { type: "date", date: { start: now.toISOString().split("T")[0] } },
234
+ },
235
+ }));
236
+ }
237
+ else {
238
+ promises.push(notion.pages.create({
239
+ parent: { type: "database_id", database_id: DAILY_REWARDS_BY_PROTOCOLS_DATABASE_ID },
240
+ properties: {
241
+ Protocols: { type: "title", title: [{ type: "text", text: { content: protocol } }] },
242
+ Rewards: { type: "number", number: result[protocol] },
243
+ Date: {
244
+ type: "date",
245
+ date: { start: now.toISOString().split("T")[0] },
246
+ },
247
+ },
248
+ }));
249
+ }
250
+ }
251
+ await Promise.all(promises);
252
+ log.info("Total Distributed by Protocols data pushed to Notion successfully");
253
+ }),
254
+ // ─── By Types ────────────────────────────────────────────────
258
255
  CacheService.set(TTLPresets.DAY_1, RewardService.getTotalDistributedByType, today).then(async (result) => {
259
256
  const currentMonthPages = await getPagesOfTheDay(DAILY_REWARDS_BY_TYPES_DATABASE_ID);
260
257
  const promises = [];
@@ -294,7 +291,8 @@ const main = async () => {
294
291
  await Promise.all(promises);
295
292
  log.info("Total Distributed by Types data pushed to Notion successfully");
296
293
  }),
297
- // ─── Campaigns ───────────────────────────────────────────────
294
+ // ─── Monthly New Campaigns ───────────────────────────────────────────────────
295
+ // ─── By Chains ───────────────────────────────────────────────
298
296
  CacheService.set(TTLPresets.DAY_1, CampaignService.countByChains, {
299
297
  createdAfter: new Date(firstDayOfMonth * 1000),
300
298
  }).then(async (result) => {
@@ -337,7 +335,7 @@ const main = async () => {
337
335
  await Promise.all(promises);
338
336
  log.info("Campaigns by Chains data pushed to Notion successfully");
339
337
  }),
340
- // ─── Campaigns By Protocols ──────────────────────────────────
338
+ // ─── By Protocols ────────────────────────────────────────────
341
339
  CacheService.set(TTLPresets.DAY_1, CampaignService.countByProtocols, {
342
340
  createdAfter: new Date(firstDayOfMonth * 1000),
343
341
  }).then(async (result) => {
@@ -376,7 +374,7 @@ const main = async () => {
376
374
  await Promise.all(promises);
377
375
  log.info("Campaigns by Protocols data pushed to Notion successfully");
378
376
  }),
379
- // ─── Campaigns By Types ──────────────────────────────────────
377
+ // ─── By Types ────────────────────────────────────────────────
380
378
  CacheService.set(TTLPresets.DAY_1, CampaignService.countByTypes, {
381
379
  createdAfter: new Date(firstDayOfMonth * 1000),
382
380
  }).then(async (result) => {
@@ -418,7 +416,8 @@ const main = async () => {
418
416
  await Promise.all(promises);
419
417
  log.info("Campaigns by Types data pushed to Notion successfully");
420
418
  }),
421
- // ─── Daily Campaigns ─────────────────────────────────────────
419
+ // ─── Daily New Campaigns ─────────────────────────────────────────────────────
420
+ // ─── By Chains ───────────────────────────────────────────────
422
421
  CacheService.set(TTLPresets.DAY_1, CampaignService.countByChains, {
423
422
  createdAfter: new Date(today * 1000),
424
423
  }).then(async (result) => {
@@ -457,7 +456,7 @@ const main = async () => {
457
456
  await Promise.all(promises);
458
457
  log.info("Campaigns by Chains data pushed to Notion successfully");
459
458
  }),
460
- // ─── Daily New Campaigns By Protocols ────────────────────────
459
+ // ─── By Protocols ────────────────────────────────────────────
461
460
  CacheService.set(TTLPresets.DAY_1, CampaignService.countByProtocols, {
462
461
  createdAfter: new Date(today * 1000),
463
462
  }).then(async (result) => {
@@ -495,7 +494,7 @@ const main = async () => {
495
494
  await Promise.all(promises);
496
495
  log.info("Campaigns by Protocols data pushed to Notion successfully");
497
496
  }),
498
- // ─── Daily Campaigns By Types ────────────────────────────────
497
+ // ─── By Types ────────────────────────────────────────────────
499
498
  CacheService.set(TTLPresets.DAY_1, CampaignService.countByTypes, {
500
499
  createdAfter: new Date(today * 1000),
501
500
  }).then(async (result) => {
@@ -534,10 +533,15 @@ const main = async () => {
534
533
  log.info("Campaigns by Types data pushed to Notion successfully");
535
534
  }),
536
535
  ];
537
- await Promise.all(promises);
536
+ return await Promise.allSettled(promises);
538
537
  };
539
538
  main()
540
- .then(() => process.exit(0))
539
+ .then(results => {
540
+ const rejected = results.find(result => result.status === "rejected");
541
+ if (rejected)
542
+ throw new Error(`One or more promises were rejected: ${JSON.stringify(rejected.reason)}`);
543
+ process.exit(0);
544
+ })
541
545
  .catch(err => {
542
546
  console.error(err);
543
547
  process.exit(1);
@@ -17,28 +17,24 @@ export type AprBreakdown = Resource<"AprBreakdown", "id" | "aprRecordId", {
17
17
  distributionType?: DistributionType;
18
18
  }>;
19
19
  export declare const AprBreakdownResourceDto: import("@sinclair/typebox").TObject<{
20
- id: import("@sinclair/typebox").TString;
20
+ identifier: import("@sinclair/typebox").TString;
21
21
  type: import("@sinclair/typebox").TEnum<{
22
22
  CAMPAIGN: "CAMPAIGN";
23
23
  TOKEN: "TOKEN";
24
24
  PROTOCOL: "PROTOCOL";
25
25
  }>;
26
- identifier: import("@sinclair/typebox").TString;
27
26
  value: import("@sinclair/typebox").TNumber;
28
- aprRecordId: import("@sinclair/typebox").TString;
29
27
  }>;
30
28
  export declare const AprRecordResourceDto: import("@sinclair/typebox").TObject<{
31
29
  cumulated: import("@sinclair/typebox").TNumber;
32
30
  timestamp: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TBigInt, import("@sinclair/typebox").TString]>;
33
31
  breakdowns: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
34
- id: import("@sinclair/typebox").TString;
32
+ identifier: import("@sinclair/typebox").TString;
35
33
  type: import("@sinclair/typebox").TEnum<{
36
34
  CAMPAIGN: "CAMPAIGN";
37
35
  TOKEN: "TOKEN";
38
36
  PROTOCOL: "PROTOCOL";
39
37
  }>;
40
- identifier: import("@sinclair/typebox").TString;
41
38
  value: import("@sinclair/typebox").TNumber;
42
- aprRecordId: import("@sinclair/typebox").TString;
43
39
  }>>;
44
40
  }>;
@@ -2,11 +2,9 @@ import { AprType } from "@db/api";
2
2
  import { t } from "elysia";
3
3
  // ─── Dtos ────────────────────────────────────────────────────────────────────
4
4
  export const AprBreakdownResourceDto = t.Object({
5
- id: t.String(),
6
- type: t.Enum(AprType),
7
5
  identifier: t.String(),
6
+ type: t.Enum(AprType),
8
7
  value: t.Number(),
9
- aprRecordId: t.String(),
10
8
  });
11
9
  export const AprRecordResourceDto = t.Object({
12
10
  cumulated: t.Number(),
@@ -441,6 +441,31 @@ export declare const CampaignController: Elysia<"/campaigns", false, {
441
441
  };
442
442
  };
443
443
  };
444
+ } & {
445
+ ":id": {
446
+ timeseries: {
447
+ get: {
448
+ body: unknown;
449
+ params: {
450
+ id: string;
451
+ };
452
+ query: unknown;
453
+ headers: unknown;
454
+ response: {
455
+ 200: {
456
+ tvlRecords: {
457
+ total: number;
458
+ timestamp: bigint;
459
+ }[];
460
+ aprRecords: {
461
+ timestamp: bigint;
462
+ cumulated: number;
463
+ }[];
464
+ };
465
+ };
466
+ };
467
+ };
468
+ };
444
469
  } & {
445
470
  "campaigns-to-process": {
446
471
  index: {
@@ -3,6 +3,7 @@ import { BackOfficeGuard } from "@/guards/BackOffice.guard";
3
3
  import { AuthorizationHeadersDto, EngineGuard } from "@/guards/Engine.guard";
4
4
  import { CacheService } from "@/modules/v4/cache/cache.service";
5
5
  import { ChainUniqueDto } from "@/modules/v4/chain/chain.model";
6
+ import { log } from "@/utils/logger";
6
7
  import { Campaign } from "@sdk";
7
8
  import Elysia, { t } from "elysia";
8
9
  import { throwOnUnsupportedChainId } from "src/utils/throw";
@@ -84,7 +85,7 @@ export const CampaignController = new Elysia({ prefix: "/campaigns", detail: { t
84
85
  return CampaignService.format(await CampaignService.findUniqueOrThrow({ distributionChain: +distributionChain, campaignId }));
85
86
  }
86
87
  catch (err) {
87
- console.log(err);
88
+ log.error(`Error getting campaign: ${params.id}`, err);
88
89
  throw new NotFoundError("Campaign not found.");
89
90
  }
90
91
  }, {
@@ -94,6 +95,12 @@ export const CampaignController = new Elysia({ prefix: "/campaigns", detail: { t
94
95
  description: `**Retrieve A Campaign**
95
96
  <p>This endpoint enables you to retrieve a campaign by providing its unique identifier.</p>`,
96
97
  },
98
+ })
99
+ .get("/:id/timeseries", async ({ params }) => {
100
+ if (!params.id.includes("-"))
101
+ return await CampaignService.getTimeSeries(params.id);
102
+ const [distributionChain, campaignId] = params.id.split("-");
103
+ return await CampaignService.getTimeSeries({ distributionChain: +distributionChain, campaignId });
97
104
  })
98
105
  .group("/campaigns-to-process", app => {
99
106
  return (app
@@ -775,4 +775,20 @@ export declare abstract class CampaignRepository {
775
775
  manualOverrides: import("@db/api").$Enums.CampaignManualOverride[];
776
776
  createdAt: Date;
777
777
  }>;
778
+ static getTvlRecords(campaign: {
779
+ opportunityId: string;
780
+ startTimestamp: bigint;
781
+ endTimestamp: bigint;
782
+ }): Promise<{
783
+ total: number;
784
+ timestamp: bigint;
785
+ }[]>;
786
+ static getAprRecords(campaign: {
787
+ opportunityId: string;
788
+ startTimestamp: bigint;
789
+ endTimestamp: bigint;
790
+ }): Promise<{
791
+ timestamp: bigint;
792
+ cumulated: number;
793
+ }[]>;
778
794
  }
@@ -449,4 +449,22 @@ export class CampaignRepository {
449
449
  };
450
450
  return await apiDbClient.campaign.update({ where: { id }, data: updateData });
451
451
  }
452
+ static async getTvlRecords(campaign) {
453
+ return await apiDbClient.tVLRecord.findMany({
454
+ where: {
455
+ opportunityId: campaign.opportunityId,
456
+ timestamp: { gte: campaign.startTimestamp, lte: campaign.endTimestamp },
457
+ },
458
+ select: { timestamp: true, total: true },
459
+ });
460
+ }
461
+ static async getAprRecords(campaign) {
462
+ return await apiDbClient.aprRecord.findMany({
463
+ where: {
464
+ opportunityId: campaign.opportunityId,
465
+ timestamp: { gte: campaign.startTimestamp, lte: campaign.endTimestamp },
466
+ },
467
+ select: { timestamp: true, cumulated: true },
468
+ });
469
+ }
452
470
  }
@@ -914,4 +914,14 @@ export declare abstract class CampaignService {
914
914
  endTimestamp: any;
915
915
  params: string;
916
916
  };
917
+ static getTimeSeries(campaignId: CampaignUnique | string): Promise<{
918
+ tvlRecords: {
919
+ total: number;
920
+ timestamp: bigint;
921
+ }[];
922
+ aprRecords: {
923
+ timestamp: bigint;
924
+ cumulated: number;
925
+ }[];
926
+ }>;
917
927
  }
@@ -384,4 +384,11 @@ export class CampaignService {
384
384
  params: JSON.stringify(fakeCampaign.campaignParameters),
385
385
  };
386
386
  }
387
+ static async getTimeSeries(campaignId) {
388
+ const id = typeof campaignId === "string" ? campaignId : CampaignService.hashId(campaignId);
389
+ const campaign = await CampaignRepository.findUniqueOrThrow(id, false);
390
+ const tvlRecords = await CampaignRepository.getTvlRecords(campaign);
391
+ const aprRecords = await CampaignRepository.getAprRecords(campaign);
392
+ return { tvlRecords, aprRecords };
393
+ }
387
394
  }