@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
@@ -356,16 +356,12 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
356
356
  cumulated: number;
357
357
  timestamp: bigint;
358
358
  breakdowns: ({
359
- id: string;
360
359
  value: number;
361
- aprRecordId: string;
362
360
  distributionType: import("@db/api").$Enums.DistributionType;
363
361
  identifier: string;
364
362
  type: "CAMPAIGN";
365
363
  } | {
366
- id: string;
367
364
  value: number;
368
- aprRecordId: string;
369
365
  identifier: string;
370
366
  type: import("@db/api").$Enums.AprType;
371
367
  })[];
@@ -376,10 +372,8 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
376
372
  timestamp: bigint;
377
373
  breakdowns: {
378
374
  type: import("@db/api").$Enums.TvlType;
379
- id: string;
380
375
  identifier: string;
381
376
  value: number;
382
- tvlRecordId: string;
383
377
  }[];
384
378
  };
385
379
  rewardsRecord: {
@@ -573,6 +567,93 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
573
567
  };
574
568
  };
575
569
  };
570
+ } & {
571
+ opportunities: {
572
+ bins: {
573
+ apr: {
574
+ get: {
575
+ body: unknown;
576
+ params: {};
577
+ query: {
578
+ status?: string | undefined;
579
+ search?: string | undefined;
580
+ sort?: string | undefined;
581
+ type?: string | undefined;
582
+ name?: string | undefined;
583
+ tokens?: string | undefined;
584
+ items?: number | undefined;
585
+ tags?: string | undefined;
586
+ identifier?: string | undefined;
587
+ page?: number | undefined;
588
+ action?: string | undefined;
589
+ campaignId?: string | undefined;
590
+ creatorAddress?: string | undefined;
591
+ chainId?: string | undefined;
592
+ mainProtocolId?: string | undefined;
593
+ campaigns?: boolean | undefined;
594
+ point?: boolean | undefined;
595
+ rewardTokenSymbol?: string | undefined;
596
+ order?: string | undefined;
597
+ test?: boolean | undefined;
598
+ minimumTvl?: number | undefined;
599
+ };
600
+ headers: unknown;
601
+ response: {
602
+ 200: {
603
+ min: number;
604
+ max: number;
605
+ overThreshold: number;
606
+ binWidth: number;
607
+ bins: any[];
608
+ };
609
+ };
610
+ };
611
+ };
612
+ };
613
+ };
614
+ } & {
615
+ opportunities: {
616
+ bins: {
617
+ tvl: {
618
+ get: {
619
+ body: unknown;
620
+ params: {};
621
+ query: {
622
+ status?: string | undefined;
623
+ search?: string | undefined;
624
+ sort?: string | undefined;
625
+ type?: string | undefined;
626
+ name?: string | undefined;
627
+ tokens?: string | undefined;
628
+ items?: number | undefined;
629
+ tags?: string | undefined;
630
+ identifier?: string | undefined;
631
+ page?: number | undefined;
632
+ action?: string | undefined;
633
+ campaignId?: string | undefined;
634
+ creatorAddress?: string | undefined;
635
+ chainId?: string | undefined;
636
+ mainProtocolId?: string | undefined;
637
+ campaigns?: boolean | undefined;
638
+ point?: boolean | undefined;
639
+ rewardTokenSymbol?: string | undefined;
640
+ order?: string | undefined;
641
+ test?: boolean | undefined;
642
+ minimumTvl?: number | undefined;
643
+ };
644
+ headers: unknown;
645
+ response: {
646
+ 200: {
647
+ min: number;
648
+ max: number;
649
+ binWidth: number;
650
+ bins: any[];
651
+ };
652
+ };
653
+ };
654
+ };
655
+ };
656
+ };
576
657
  } & {
577
658
  opportunities: {
578
659
  ":id": {
@@ -604,10 +685,8 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
604
685
  cumulated: number;
605
686
  breakdowns: {
606
687
  type: "CAMPAIGN" | "TOKEN" | "PROTOCOL";
607
- id: string;
608
688
  identifier: string;
609
689
  value: number;
610
- aprRecordId: string;
611
690
  }[];
612
691
  } | undefined;
613
692
  tvlRecord?: {
@@ -615,10 +694,8 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
615
694
  timestamp: string | bigint;
616
695
  breakdowns: {
617
696
  type: "TOKEN" | "PROTOCOL";
618
- id: string;
619
697
  identifier: string;
620
698
  value: number;
621
- tvlRecordId: string;
622
699
  }[];
623
700
  } | undefined;
624
701
  rewardsRecord?: {
@@ -743,10 +820,8 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
743
820
  cumulated: number;
744
821
  breakdowns: {
745
822
  type: "CAMPAIGN" | "TOKEN" | "PROTOCOL";
746
- id: string;
747
823
  identifier: string;
748
824
  value: number;
749
- aprRecordId: string;
750
825
  }[];
751
826
  } | undefined;
752
827
  tvlRecord?: {
@@ -754,10 +829,8 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
754
829
  timestamp: string | bigint;
755
830
  breakdowns: {
756
831
  type: "TOKEN" | "PROTOCOL";
757
- id: string;
758
832
  identifier: string;
759
833
  value: number;
760
- tvlRecordId: string;
761
834
  }[];
762
835
  } | undefined;
763
836
  rewardsRecord?: {
@@ -919,10 +992,8 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
919
992
  cumulated: number;
920
993
  breakdowns: {
921
994
  type: "CAMPAIGN" | "TOKEN" | "PROTOCOL";
922
- id: string;
923
995
  identifier: string;
924
996
  value: number;
925
- aprRecordId: string;
926
997
  }[];
927
998
  } | undefined;
928
999
  tvlRecord?: {
@@ -930,10 +1001,8 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
930
1001
  timestamp: string | bigint;
931
1002
  breakdowns: {
932
1003
  type: "TOKEN" | "PROTOCOL";
933
- id: string;
934
1004
  identifier: string;
935
1005
  value: number;
936
- tvlRecordId: string;
937
1006
  }[];
938
1007
  } | undefined;
939
1008
  rewardsRecord?: {
@@ -84,14 +84,20 @@ export const OpportunityController = new Elysia({
84
84
  },
85
85
  detail: { description: "Get the count of opportunities corresponding to the query." },
86
86
  response: { 200: t.Number() },
87
+ })
88
+ .get("/bins/apr", async ({ query }) => await OpportunityService.getAprBins(query), {
89
+ query: GetOpportunitiesQueryDto,
90
+ })
91
+ .get("/bins/tvl", async ({ query }) => await OpportunityService.getTvlBins(query), {
92
+ query: GetOpportunitiesQueryDto,
87
93
  })
88
94
  // ─── Get An Opportunity By Id ────────────────────────────────────────
89
95
  .get("/:id", async ({ params, query }) => {
90
96
  try {
91
97
  if (!params.id.includes("-"))
92
- return await OpportunityService.getUniqueOrThrow(params.id, query.test ?? false);
98
+ return await OpportunityService.findUniqueOrThrow(params.id, query.test ?? false);
93
99
  const [chainId, type, identifier] = params.id.split("-");
94
- return await OpportunityService.getUniqueOrThrow({
100
+ return await OpportunityService.findUniqueOrThrow({
95
101
  chainId: +chainId,
96
102
  type: type,
97
103
  identifier,
@@ -77,29 +77,25 @@ export declare const OpportunityResourceDto: import("@sinclair/typebox").TObject
77
77
  cumulated: import("@sinclair/typebox").TNumber;
78
78
  timestamp: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TBigInt, import("@sinclair/typebox").TString]>;
79
79
  breakdowns: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
80
- id: import("@sinclair/typebox").TString;
80
+ identifier: import("@sinclair/typebox").TString;
81
81
  type: import("@sinclair/typebox").TEnum<{
82
82
  CAMPAIGN: "CAMPAIGN";
83
83
  TOKEN: "TOKEN";
84
84
  PROTOCOL: "PROTOCOL";
85
85
  }>;
86
- identifier: import("@sinclair/typebox").TString;
87
86
  value: import("@sinclair/typebox").TNumber;
88
- aprRecordId: import("@sinclair/typebox").TString;
89
87
  }>>;
90
88
  }>>;
91
89
  tvlRecord: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
92
90
  total: import("@sinclair/typebox").TNumber;
93
91
  timestamp: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TBigInt, import("@sinclair/typebox").TString]>;
94
92
  breakdowns: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
95
- id: import("@sinclair/typebox").TString;
93
+ identifier: import("@sinclair/typebox").TString;
96
94
  type: import("@sinclair/typebox").TEnum<{
97
95
  TOKEN: "TOKEN";
98
96
  PROTOCOL: "PROTOCOL";
99
97
  }>;
100
- identifier: import("@sinclair/typebox").TString;
101
98
  value: import("@sinclair/typebox").TNumber;
102
- tvlRecordId: import("@sinclair/typebox").TString;
103
99
  }>>;
104
100
  }>>;
105
101
  rewardsRecord: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
@@ -193,29 +189,25 @@ export declare const OpportunityWithCampaignsResourceDto: import("@sinclair/type
193
189
  cumulated: import("@sinclair/typebox").TNumber;
194
190
  timestamp: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TBigInt, import("@sinclair/typebox").TString]>;
195
191
  breakdowns: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
196
- id: import("@sinclair/typebox").TString;
192
+ identifier: import("@sinclair/typebox").TString;
197
193
  type: import("@sinclair/typebox").TEnum<{
198
194
  CAMPAIGN: "CAMPAIGN";
199
195
  TOKEN: "TOKEN";
200
196
  PROTOCOL: "PROTOCOL";
201
197
  }>;
202
- identifier: import("@sinclair/typebox").TString;
203
198
  value: import("@sinclair/typebox").TNumber;
204
- aprRecordId: import("@sinclair/typebox").TString;
205
199
  }>>;
206
200
  }>>;
207
201
  tvlRecord: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
208
202
  total: import("@sinclair/typebox").TNumber;
209
203
  timestamp: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TBigInt, import("@sinclair/typebox").TString]>;
210
204
  breakdowns: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
211
- id: import("@sinclair/typebox").TString;
205
+ identifier: import("@sinclair/typebox").TString;
212
206
  type: import("@sinclair/typebox").TEnum<{
213
207
  TOKEN: "TOKEN";
214
208
  PROTOCOL: "PROTOCOL";
215
209
  }>;
216
- identifier: import("@sinclair/typebox").TString;
217
210
  value: import("@sinclair/typebox").TNumber;
218
- tvlRecordId: import("@sinclair/typebox").TString;
219
211
  }>>;
220
212
  }>>;
221
213
  rewardsRecord: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
@@ -131,10 +131,8 @@ export declare abstract class OpportunityRepository {
131
131
  TvlRecords: ({
132
132
  TvlBreakdown: {
133
133
  type: import("@db/api").$Enums.TvlType;
134
- id: string;
135
134
  identifier: string;
136
135
  value: number;
137
- tvlRecordId: string;
138
136
  }[];
139
137
  } & {
140
138
  total: number;
@@ -145,10 +143,8 @@ export declare abstract class OpportunityRepository {
145
143
  AprRecords: ({
146
144
  AprBreakdown: {
147
145
  type: import("@db/api").$Enums.AprType;
148
- id: string;
149
146
  identifier: string;
150
147
  value: number;
151
- aprRecordId: string;
152
148
  }[];
153
149
  } & {
154
150
  id: string;
@@ -281,10 +277,8 @@ export declare abstract class OpportunityRepository {
281
277
  TvlRecords: ({
282
278
  TvlBreakdown: {
283
279
  type: import("@db/api").$Enums.TvlType;
284
- id: string;
285
280
  identifier: string;
286
281
  value: number;
287
- tvlRecordId: string;
288
282
  }[];
289
283
  } & {
290
284
  total: number;
@@ -295,10 +289,8 @@ export declare abstract class OpportunityRepository {
295
289
  AprRecords: ({
296
290
  AprBreakdown: {
297
291
  type: import("@db/api").$Enums.AprType;
298
- id: string;
299
292
  identifier: string;
300
293
  value: number;
301
- aprRecordId: string;
302
294
  }[];
303
295
  } & {
304
296
  id: string;
@@ -490,10 +482,8 @@ export declare abstract class OpportunityRepository {
490
482
  TvlRecords: ({
491
483
  TvlBreakdown: {
492
484
  type: import("@db/api").$Enums.TvlType;
493
- id: string;
494
485
  identifier: string;
495
486
  value: number;
496
- tvlRecordId: string;
497
487
  }[];
498
488
  } & {
499
489
  total: number;
@@ -504,10 +494,8 @@ export declare abstract class OpportunityRepository {
504
494
  AprRecords: ({
505
495
  AprBreakdown: {
506
496
  type: import("@db/api").$Enums.AprType;
507
- id: string;
508
497
  identifier: string;
509
498
  value: number;
510
- aprRecordId: string;
511
499
  }[];
512
500
  } & {
513
501
  id: string;
@@ -647,10 +635,8 @@ export declare abstract class OpportunityRepository {
647
635
  TvlRecords: ({
648
636
  TvlBreakdown: {
649
637
  type: import("@db/api").$Enums.TvlType;
650
- id: string;
651
638
  identifier: string;
652
639
  value: number;
653
- tvlRecordId: string;
654
640
  }[];
655
641
  } & {
656
642
  total: number;
@@ -661,10 +647,8 @@ export declare abstract class OpportunityRepository {
661
647
  AprRecords: ({
662
648
  AprBreakdown: {
663
649
  type: import("@db/api").$Enums.AprType;
664
- id: string;
665
650
  identifier: string;
666
651
  value: number;
667
- aprRecordId: string;
668
652
  }[];
669
653
  } & {
670
654
  id: string;
@@ -858,10 +842,8 @@ export declare abstract class OpportunityRepository {
858
842
  TvlRecords: ({
859
843
  TvlBreakdown: {
860
844
  type: import("@db/api").$Enums.TvlType;
861
- id: string;
862
845
  identifier: string;
863
846
  value: number;
864
- tvlRecordId: string;
865
847
  }[];
866
848
  } & {
867
849
  total: number;
@@ -872,10 +854,8 @@ export declare abstract class OpportunityRepository {
872
854
  AprRecords: ({
873
855
  AprBreakdown: {
874
856
  type: import("@db/api").$Enums.AprType;
875
- id: string;
876
857
  identifier: string;
877
858
  value: number;
878
- aprRecordId: string;
879
859
  }[];
880
860
  } & {
881
861
  id: string;
@@ -111,8 +111,16 @@ export class OpportunityRepository {
111
111
  }
112
112
  static #getRecordInclusion(withTest = true, withPoints = true) {
113
113
  return {
114
- AprRecords: { take: 1, orderBy: { timestamp: "desc" }, include: { AprBreakdown: true } },
115
- TvlRecords: { take: 1, orderBy: { timestamp: "desc" }, include: { TvlBreakdown: true } },
114
+ AprRecords: {
115
+ take: 1,
116
+ orderBy: { timestamp: "desc" },
117
+ include: { AprBreakdown: { select: { identifier: true, type: true, value: true } } },
118
+ },
119
+ TvlRecords: {
120
+ take: 1,
121
+ orderBy: { timestamp: "desc" },
122
+ include: { TvlBreakdown: { select: { identifier: true, type: true, value: true } } },
123
+ },
116
124
  DailyRewardsRecords: {
117
125
  take: 1,
118
126
  orderBy: { timestamp: "desc" },
@@ -8,6 +8,19 @@ import { OpportunityRepository } from "./opportunity.repository";
8
8
  export declare abstract class OpportunityService {
9
9
  #private;
10
10
  static hashId(opportunity: OpportunityUnique): string;
11
+ static getAprBins(query: GetOpportunitiesQueryModel): Promise<{
12
+ min: number;
13
+ max: number;
14
+ overThreshold: number;
15
+ binWidth: number;
16
+ bins: any[];
17
+ }>;
18
+ static getTvlBins(query: GetOpportunitiesQueryModel): Promise<{
19
+ min: number;
20
+ max: number;
21
+ binWidth: number;
22
+ bins: any[];
23
+ }>;
11
24
  static override(id: string, data: OpportunityOverrideModel): Promise<{
12
25
  status: import("@db/api").$Enums.Status;
13
26
  type: string;
@@ -334,10 +347,8 @@ export declare abstract class OpportunityService {
334
347
  cumulated: number;
335
348
  breakdowns: {
336
349
  type: "CAMPAIGN" | "TOKEN" | "PROTOCOL";
337
- id: string;
338
350
  identifier: string;
339
351
  value: number;
340
- aprRecordId: string;
341
352
  }[];
342
353
  } | undefined;
343
354
  tvlRecord?: {
@@ -345,10 +356,8 @@ export declare abstract class OpportunityService {
345
356
  timestamp: string | bigint;
346
357
  breakdowns: {
347
358
  type: "TOKEN" | "PROTOCOL";
348
- id: string;
349
359
  identifier: string;
350
360
  value: number;
351
- tvlRecordId: string;
352
361
  }[];
353
362
  } | undefined;
354
363
  rewardsRecord?: {
@@ -482,10 +491,8 @@ export declare abstract class OpportunityService {
482
491
  cumulated: number;
483
492
  breakdowns: {
484
493
  type: "CAMPAIGN" | "TOKEN" | "PROTOCOL";
485
- id: string;
486
494
  identifier: string;
487
495
  value: number;
488
- aprRecordId: string;
489
496
  }[];
490
497
  } | undefined;
491
498
  tvlRecord?: {
@@ -493,10 +500,8 @@ export declare abstract class OpportunityService {
493
500
  timestamp: string | bigint;
494
501
  breakdowns: {
495
502
  type: "TOKEN" | "PROTOCOL";
496
- id: string;
497
503
  identifier: string;
498
504
  value: number;
499
- tvlRecordId: string;
500
505
  }[];
501
506
  } | undefined;
502
507
  rewardsRecord?: {
@@ -613,7 +618,7 @@ export declare abstract class OpportunityService {
613
618
  };
614
619
  }[];
615
620
  }>;
616
- static getUniqueOrThrow(opportunityId: string | OpportunityUnique, withTest?: boolean, withPoints?: boolean): Promise<OpportunityResourceModel>;
621
+ static findUniqueOrThrow(opportunityId: string | OpportunityUnique, withTest?: boolean, withPoints?: boolean): Promise<OpportunityResourceModel>;
617
622
  /**
618
623
  * Get the list of opportunities satisfying the query
619
624
  * @param query
@@ -625,16 +630,12 @@ export declare abstract class OpportunityService {
625
630
  cumulated: number;
626
631
  timestamp: bigint;
627
632
  breakdowns: ({
628
- id: string;
629
633
  value: number;
630
- aprRecordId: string;
631
634
  distributionType: import("@db/api").$Enums.DistributionType;
632
635
  identifier: string;
633
636
  type: "CAMPAIGN";
634
637
  } | {
635
- id: string;
636
638
  value: number;
637
- aprRecordId: string;
638
639
  identifier: string;
639
640
  type: import("@db/api").$Enums.AprType;
640
641
  })[];
@@ -645,10 +646,8 @@ export declare abstract class OpportunityService {
645
646
  timestamp: bigint;
646
647
  breakdowns: {
647
648
  type: import("@db/api").$Enums.TvlType;
648
- id: string;
649
649
  identifier: string;
650
650
  value: number;
651
- tvlRecordId: string;
652
651
  }[];
653
652
  };
654
653
  rewardsRecord: {
@@ -815,16 +814,12 @@ export declare abstract class OpportunityService {
815
814
  cumulated: number;
816
815
  timestamp: bigint;
817
816
  breakdowns: ({
818
- id: string;
819
817
  value: number;
820
- aprRecordId: string;
821
818
  distributionType: import("@db/api").$Enums.DistributionType;
822
819
  identifier: string;
823
820
  type: "CAMPAIGN";
824
821
  } | {
825
- id: string;
826
822
  value: number;
827
- aprRecordId: string;
828
823
  identifier: string;
829
824
  type: import("@db/api").$Enums.AprType;
830
825
  })[];
@@ -835,10 +830,8 @@ export declare abstract class OpportunityService {
835
830
  timestamp: bigint;
836
831
  breakdowns: {
837
832
  type: import("@db/api").$Enums.TvlType;
838
- id: string;
839
833
  identifier: string;
840
834
  value: number;
841
- tvlRecordId: string;
842
835
  }[];
843
836
  };
844
837
  rewardsRecord: {
@@ -998,16 +991,12 @@ export declare abstract class OpportunityService {
998
991
  cumulated: number;
999
992
  timestamp: bigint;
1000
993
  breakdowns: ({
1001
- id: string;
1002
994
  value: number;
1003
- aprRecordId: string;
1004
995
  distributionType: import("@db/api").$Enums.DistributionType;
1005
996
  identifier: string;
1006
997
  type: "CAMPAIGN";
1007
998
  } | {
1008
- id: string;
1009
999
  value: number;
1010
- aprRecordId: string;
1011
1000
  identifier: string;
1012
1001
  type: import("@db/api").$Enums.AprType;
1013
1002
  })[];
@@ -1018,10 +1007,8 @@ export declare abstract class OpportunityService {
1018
1007
  timestamp: bigint;
1019
1008
  breakdowns: {
1020
1009
  type: import("@db/api").$Enums.TvlType;
1021
- id: string;
1022
1010
  identifier: string;
1023
1011
  value: number;
1024
- tvlRecordId: string;
1025
1012
  }[];
1026
1013
  };
1027
1014
  rewardsRecord: {
@@ -17,6 +17,67 @@ export class OpportunityService {
17
17
  static hashId(opportunity) {
18
18
  return Bun.hash(`${opportunity.chainId}${opportunity.type}${opportunity.identifier}`).toString();
19
19
  }
20
+ static async getAprBins(query) {
21
+ const BINS_COUNT = 20;
22
+ const opportunities = await OpportunityRepository.findMany({
23
+ ...query,
24
+ status: "LIVE",
25
+ sort: "apr",
26
+ order: "asc",
27
+ items: 0,
28
+ });
29
+ const mid = Math.floor(opportunities.length / 2);
30
+ const median = opportunities.length % 2 !== 0
31
+ ? opportunities[mid].apr
32
+ : (opportunities[mid - 1].apr + opportunities[mid].apr) / 2;
33
+ const threshold = 5 * median;
34
+ if (opportunities.length < 2)
35
+ throw new Error("Not enough opportunities");
36
+ const maxAprUnderThreshold = opportunities.filter(o => o.apr <= threshold).at(-1)?.apr ?? 0;
37
+ const minAprAbove0 = opportunities.find(o => o.apr > 0)?.apr ?? 0;
38
+ const binWidth = (maxAprUnderThreshold - minAprAbove0) / BINS_COUNT;
39
+ const bins = new Array(BINS_COUNT);
40
+ for (let i = 0; i < BINS_COUNT; i++)
41
+ bins[i] = 0;
42
+ let overThreshold = 0;
43
+ for (const opportunity of opportunities) {
44
+ if (opportunity.apr > 0 && opportunity.apr < threshold)
45
+ bins[Math.min(Math.floor(opportunity.apr / binWidth), BINS_COUNT - 1)]++;
46
+ else
47
+ overThreshold++;
48
+ }
49
+ return {
50
+ min: opportunities[0].apr,
51
+ max: opportunities[opportunities.length - 1].apr,
52
+ overThreshold,
53
+ binWidth,
54
+ bins,
55
+ };
56
+ }
57
+ static async getTvlBins(query) {
58
+ const BINS_COUNT = 20;
59
+ const opportunities = await OpportunityRepository.findMany({
60
+ ...query,
61
+ status: "LIVE,SOON",
62
+ sort: "tvl",
63
+ order: "asc",
64
+ items: 0,
65
+ });
66
+ if (opportunities.length < 2)
67
+ throw new Error("Not enough opportunities");
68
+ const binWidth = (opportunities[opportunities.length - 1].tvl - opportunities[0].tvl) / BINS_COUNT;
69
+ const bins = new Array(BINS_COUNT);
70
+ for (let i = 0; i < BINS_COUNT; i++)
71
+ bins[i] = 0;
72
+ for (const opportunity of opportunities)
73
+ bins[Math.min(Math.floor(opportunity.tvl / binWidth), BINS_COUNT - 1)]++;
74
+ return {
75
+ min: opportunities[0].tvl,
76
+ max: opportunities[opportunities.length - 1].tvl,
77
+ binWidth,
78
+ bins,
79
+ };
80
+ }
20
81
  static async override(id, data) {
21
82
  const opportunity = await OpportunityRepository.findUniqueOrThrow(id);
22
83
  const overrides = opportunity.manualOverrides ?? [];
@@ -131,7 +192,7 @@ export class OpportunityService {
131
192
  const opportunity = await OpportunityRepository.findUniqueOrThrow(id, withTest, withTest ? withTest : withPoints, true);
132
193
  return OpportunityService.formatResponse(opportunity);
133
194
  }
134
- static async getUniqueOrThrow(opportunityId, withTest = false, withPoints = false) {
195
+ static async findUniqueOrThrow(opportunityId, withTest = false, withPoints = false) {
135
196
  const id = typeof opportunityId === "string" ? opportunityId : OpportunityService.hashId(opportunityId);
136
197
  const opportunity = await OpportunityRepository.findUniqueOrThrow(id, withTest, withTest ? withTest : withPoints);
137
198
  return OpportunityService.formatResponse(opportunity);
@@ -194,6 +194,9 @@ export class ProgramPayloadService {
194
194
  const totalAmount = Object.values(body).reduce((sum, amount) => sum + BigInt(amount), 0n);
195
195
  const minimumAmountPerHour = await ProgramPayloadService.getMinimumAmount(query.rewardToken, query.distributionChainId);
196
196
  const numberOfHours = (BigInt(query.endTimestamp) - BigInt(query.startTimestamp)) / 3600n;
197
+ if (numberOfHours < 1n) {
198
+ throw new Error("Duration is less than 1 hour");
199
+ }
197
200
  if (!minimumAmountPerHour) {
198
201
  throw new Error("Token not found");
199
202
  }
@@ -129,6 +129,6 @@ export const RewardController = new Elysia({ prefix: "/rewards", detail: { tags:
129
129
  detail: { hide: true },
130
130
  })
131
131
  .get("/total/distributed", async ({ query }) => await RewardService.getTotalDistributed(query.since.getTime() / 1000))
132
- .get("/total/distributed/by-chains", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, RewardService.getTotalDistributedByChains, query.since.getTime() / 1000))
132
+ .get("/total/distributed/by-chains", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, RewardService.getTotalDistributedByChain, query.since.getTime() / 1000))
133
133
  .get("/total/distributed/by-types", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, RewardService.getTotalDistributedByType, query.since.getTime() / 1000))
134
134
  .get("/total/distributed/by-protocols", async ({ query }) => await CacheService.wrap(TTLPresets.DAY_1, RewardService.getTotalDistributedByProtocol, query.since.getTime() / 1000));