@merkl/api 0.16.46 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,22 +6,60 @@ import { OpportunityRepository } from "../../modules/v4/opportunity/opportunity.
6
6
  import { RewardService } from "../../modules/v4/reward";
7
7
  import { TvlService } from "../../modules/v4/tvl";
8
8
  import { executeSimple } from "../../utils/execute";
9
- import { Campaign } from "@sdk";
9
+ import { Campaign as CampaignTypesEnum } from "@sdk";
10
+ import moment from "moment";
11
+ // ─── Required Env Variables ──────────────────────────────────────────────────
10
12
  const chainId = Number(process.env.CHAIN_ID);
11
13
  if (!chainId)
12
14
  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 => {
15
+ // ─── Update Dynamic Data (APR / TVL / Daily Rewards) ─────────────────────────
16
+ async function updateDynamicData(liveCampaigns, campaignType) {
17
+ try {
18
+ const dynamicData = await executeSimple(chainId, campaignsDynamicData(chainId, liveCampaigns, campaignType));
19
+ const oppMap = {};
20
+ for (const data of dynamicData) {
21
+ if (!!data) {
22
+ // Main Parameter OVERRIDING
23
+ if (data.campaignType === CampaignTypesEnum.SILO && data.campaignParameters.whitelist?.length === 1)
24
+ data.mainParameter = `${data.mainParameter}-${data.campaignParameters.whitelist[0]}`;
25
+ if (!oppMap[`${data.campaignType}_${data.mainParameter}`])
26
+ oppMap[`${data.campaignType}_${data.mainParameter}`] = {};
27
+ oppMap[`${data.campaignType}_${data.mainParameter}`][data.campaignId] = data;
28
+ }
29
+ }
30
+ for (const entry of Object.entries(oppMap)) {
31
+ const [type, mainParameter] = entry[0].split("_");
32
+ try {
33
+ const apr = AprService.extractFromDynamicData(+type, Object.values(entry[1]));
34
+ const tvl = TvlService.extractFromDynamicData(+type, Object.values(entry[1]));
35
+ const dailyRewards = await RewardService.extractDailyRewardsRecordFromDynamicData(+type, Object.values(entry[1]));
36
+ const opportunityId = OpportunityService.hashId({
37
+ chainId,
38
+ identifier: mainParameter,
39
+ type: type,
40
+ });
41
+ await OpportunityRepository.updateRecords(opportunityId, apr, tvl, dailyRewards);
42
+ }
43
+ catch (err) {
44
+ console.log(mainParameter);
45
+ console.error(err);
46
+ }
47
+ }
48
+ }
49
+ catch (err) {
50
+ console.error(err);
51
+ }
52
+ }
53
+ // ─── Get And Transform Live Campaigns Into A Map ─────────────────────────────
54
+ const getLiveCampaignsByType = async (chainId) => {
55
+ const liveCampaigns = (await CampaignService.getLiveCampaigns({ computeChainId: chainId })).map(c => {
18
56
  return {
19
57
  amount: c.amount,
20
58
  campaignId: c.campaignId,
21
59
  mainParameter: c.Opportunity.identifier,
22
60
  campaignParameters: c.params,
23
61
  campaignSubType: c.subType,
24
- campaignType,
62
+ campaignType: c.type,
25
63
  chainId: c.distributionChainId,
26
64
  computeChainId: c.computeChainId,
27
65
  creator: c.creatorAddress,
@@ -30,42 +68,59 @@ async function updateDynamicData() {
30
68
  startTimestamp: c.startTimestamp,
31
69
  };
32
70
  });
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
- }
71
+ const campaignTypeToCampaigns = new Map();
72
+ for (const campaign of liveCampaigns) {
73
+ const type = campaign.campaignType;
74
+ let campaigns = campaignTypeToCampaigns.get(campaign.campaignType);
75
+ if (!campaigns)
76
+ campaigns = [campaign];
77
+ else
78
+ campaigns.push(campaign);
79
+ campaignTypeToCampaigns.set(type, campaigns);
44
80
  }
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);
81
+ return campaignTypeToCampaigns;
82
+ };
83
+ // ─── Main function / entry point ─────────────────────────────────────────────
84
+ const main = async () => {
85
+ try {
86
+ // 1. Get a map of campaigns by campaign type
87
+ const liveCampaigns = await getLiveCampaignsByType(chainId);
88
+ // 2. Call updateDynamicData with each entries of the map (process by campaign type)
89
+ for (const [type, campaigns] of liveCampaigns.entries())
90
+ await updateDynamicData(campaigns, type);
91
+ // 3. Update status of opportunities
92
+ // 3.1 Get current live opportunities
93
+ const liveOpportunities = await OpportunityService.findLiveWithCampaigns(chainId);
94
+ // 3.2 For each currently live opportunities, infer its updated status by looping through its campaigns
95
+ const now = moment().unix();
96
+ for (const opportunity of liveOpportunities) {
97
+ let status = "NONE";
98
+ const campaigns = opportunity.campaigns;
99
+ for (const campaign of campaigns) {
100
+ if (status !== "LIVE" && campaign.endTimestamp < now)
101
+ status = "PAST";
102
+ else if (campaign.startTimestamp < now && campaign.endTimestamp > now)
103
+ status = "LIVE";
104
+ else if (status !== "LIVE" && campaign.startTimestamp > now)
105
+ status = "SOON";
106
+ }
107
+ await OpportunityService.updateStatus(opportunity.id, status);
57
108
  }
58
- catch (err) {
59
- console.log(mainParameter);
60
- console.error(err);
109
+ // 4. Compute the opportunity ids of the liveCampaigns
110
+ const opportunities = new Set();
111
+ for (const [type, campaigns] of liveCampaigns.entries()) {
112
+ for (const campaign of campaigns) {
113
+ const opportunityId = OpportunityService.hashId({ chainId, identifier: campaign.mainParameter, type });
114
+ opportunities.add(opportunityId);
115
+ }
61
116
  }
117
+ // 5. Update the status of the liveCampaigns opportunities
118
+ await OpportunityService.updateMany(Array.from(opportunities), { status: "LIVE" });
119
+ process.exit(0);
62
120
  }
63
- }
64
- try {
65
- await updateDynamicData();
66
- process.exit(0);
67
- }
68
- catch (err) {
69
- console.error(err);
70
- process.exit(1);
71
- }
121
+ catch (err) {
122
+ console.error(err);
123
+ process.exit(1);
124
+ }
125
+ };
126
+ await main();
@@ -17,7 +17,7 @@ export class LiquidityService {
17
17
  [Campaign.DOLOMITE]: new DolomitePositionFetcher(),
18
18
  };
19
19
  static async fetchPositions(query) {
20
- const opportunities = await OpportunityService.findLiveWithFirstCampaign(query.chainId);
20
+ const opportunities = await OpportunityService.findLiveWithCampaigns(query.chainId, 1);
21
21
  const promises = [];
22
22
  for (const campaignType of Object.keys(Campaign)) {
23
23
  const fetcher = LiquidityService.#fetchers[Number.parseInt(campaignType)];
@@ -864,6 +864,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
864
864
  patch: {
865
865
  body: {
866
866
  name?: string | undefined;
867
+ status?: "NONE" | "PAST" | "LIVE" | "SOON" | undefined;
867
868
  tags?: string[] | undefined;
868
869
  };
869
870
  params: {
@@ -340,6 +340,12 @@ export declare const OpportunityIdDto: import("@sinclair/typebox").TObject<{
340
340
  export declare const UpdateOpportunityDto: import("@sinclair/typebox").TObject<{
341
341
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
342
342
  tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
343
+ status: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TEnum<{
344
+ NONE: "NONE";
345
+ PAST: "PAST";
346
+ LIVE: "LIVE";
347
+ SOON: "SOON";
348
+ }>>;
343
349
  }>;
344
350
  export type GetOpportunitiesQueryModel = typeof GetOpportunitiesQueryDto.static;
345
351
  export type GetOpportunityQueryModel = typeof GetOpportunityQueryDto.static;
@@ -103,4 +103,5 @@ export const OpportunityIdDto = t.Object({ id: t.String() });
103
103
  export const UpdateOpportunityDto = t.Object({
104
104
  name: t.Optional(t.String()),
105
105
  tags: t.Optional(t.Array(t.String())),
106
+ status: t.Optional(t.Enum(Status)),
106
107
  });
@@ -628,7 +628,7 @@ export declare abstract class OpportunityRepository {
628
628
  apr: number;
629
629
  dailyRewards: number;
630
630
  })[]>;
631
- static findLiveWithFirstCampaign(chainId: MerklChainId): Promise<({
631
+ static findLiveWithCampaigns(chainId: MerklChainId, take?: number): Promise<({
632
632
  Chain: {
633
633
  name: string;
634
634
  id: number;
@@ -936,4 +936,5 @@ export declare abstract class OpportunityRepository {
936
936
  apr: number;
937
937
  dailyRewards: number;
938
938
  }>;
939
+ static updateMany(ids: string[], data: UpdateOpportunityModel): Promise<import("database/api/.generated/runtime/library").GetBatchResult>;
939
940
  }
@@ -257,7 +257,7 @@ export class OpportunityRepository {
257
257
  ...args,
258
258
  });
259
259
  }
260
- static async findLiveWithFirstCampaign(chainId) {
260
+ static async findLiveWithCampaigns(chainId, take) {
261
261
  const now = moment().unix();
262
262
  return await apiDbClient.opportunity.findMany({
263
263
  include: {
@@ -274,7 +274,7 @@ export class OpportunityRepository {
274
274
  CampaignStatus: true,
275
275
  Creator: true,
276
276
  },
277
- take: 1,
277
+ take: take ? take : undefined,
278
278
  orderBy: { endTimestamp: "desc" },
279
279
  },
280
280
  MainProtocol: true,
@@ -406,4 +406,7 @@ export class OpportunityRepository {
406
406
  static async update(id, data) {
407
407
  return await apiDbClient.opportunity.update({ where: { id }, data });
408
408
  }
409
+ static async updateMany(ids, data) {
410
+ return await apiDbClient.opportunity.updateMany({ where: { id: { in: ids } }, data });
411
+ }
409
412
  }
@@ -1,5 +1,5 @@
1
1
  import { type CreateCampaignModel, type GetCampaignQueryModel } from "../campaign";
2
- import { Prisma } from "../../../../database/api/.generated";
2
+ import { Prisma, Status } from "../../../../database/api/.generated";
3
3
  import { type ChainId, type MerklChainId } from "@sdk";
4
4
  import type { CreateOpportunityModel, GetOpportunitiesQueryModel, LightOpportunityFromDB, OpportunityResourceModel, OpportunityUnique, UpdateOpportunityModel } from "./opportunity.model";
5
5
  import { OpportunityRepository } from "./opportunity.repository";
@@ -63,6 +63,21 @@ export declare abstract class OpportunityService {
63
63
  depositUrl: any;
64
64
  tags: string[];
65
65
  }>;
66
+ static updateStatus(opportunityId: string, status: Status): Promise<{
67
+ name: string;
68
+ type: string;
69
+ id: string;
70
+ status: import("../../../../database/api/.generated").$Enums.Status;
71
+ tags: string[];
72
+ identifier: string;
73
+ chainId: number;
74
+ action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
75
+ depositUrl: string | null;
76
+ mainProtocolId: string | null;
77
+ tvl: number;
78
+ apr: number;
79
+ dailyRewards: number;
80
+ }>;
66
81
  static updateStatusFromCampaign(campaign: Omit<CreateCampaignModel, "id">, upsert?: boolean): Promise<{
67
82
  id: string;
68
83
  chainId: number;
@@ -535,7 +550,7 @@ export declare abstract class OpportunityService {
535
550
  * @returns the number of opportunities
536
551
  */
537
552
  static countMany(query: GetOpportunitiesQueryModel): Promise<number>;
538
- static findLiveWithFirstCampaign(chainId: MerklChainId): Promise<{
553
+ static findLiveWithCampaigns(chainId: MerklChainId, take?: number): Promise<{
539
554
  apr: number;
540
555
  aprRecord: {
541
556
  cumulated: number;
@@ -882,4 +897,5 @@ export declare abstract class OpportunityService {
882
897
  apr: number;
883
898
  dailyRewards: number;
884
899
  }>;
900
+ static updateMany(ids: string[], data: UpdateOpportunityModel): Promise<import("database/api/.generated/runtime/library").GetBatchResult>;
885
901
  }
@@ -28,7 +28,7 @@ import { getMorphoMetadata } from "./subservices/getMorphoMetadata.service";
28
28
  import { getRadiantMetadata } from "./subservices/getRadiantMetadata.service";
29
29
  import { getSiloMetadata } from "./subservices/getSiloMetadata.service";
30
30
  import { getUniswapV4Metadata } from "./subservices/getUniswapV4Metadata.service";
31
- import { getVestMetadata } from "./subservices/getVestMetadata.service";
31
+ import { getVestMetadata } from "./subservices/getVestMetaData.service";
32
32
  export class OpportunityService {
33
33
  static hashId(opportunity) {
34
34
  return Bun.hash(`${opportunity.chainId}${opportunity.type}${opportunity.identifier}`).toString();
@@ -165,6 +165,9 @@ export class OpportunityService {
165
165
  await OpportunityRepository.create(opportunity, upsert);
166
166
  return opportunity;
167
167
  }
168
+ static async updateStatus(opportunityId, status) {
169
+ return await OpportunityRepository.update(opportunityId, { status });
170
+ }
168
171
  static async updateStatusFromCampaign(campaign, upsert = true) {
169
172
  const campaignType = CampaignService.getTypeFromV3(campaign.type);
170
173
  const metadata = await OpportunityService.#getMetadata(campaign);
@@ -283,10 +286,10 @@ export class OpportunityService {
283
286
  static async countMany(query) {
284
287
  return await OpportunityRepository.countMany(query);
285
288
  }
286
- static async findLiveWithFirstCampaign(chainId) {
289
+ static async findLiveWithCampaigns(chainId, take) {
287
290
  return record("data-layer.access", async () => {
288
291
  return await CacheService.wrap(TTLPresets.MIN_10, async (chainId) => {
289
- const opportunities = await OpportunityRepository.findLiveWithFirstCampaign(chainId);
292
+ const opportunities = await OpportunityRepository.findLiveWithCampaigns(chainId, take);
290
293
  return opportunities.map(o => {
291
294
  return OpportunityService.formatResponse(o);
292
295
  });
@@ -365,4 +368,7 @@ export class OpportunityService {
365
368
  static async update(id, data) {
366
369
  return await OpportunityRepository.update(id, data);
367
370
  }
371
+ static async updateMany(ids, data) {
372
+ return await OpportunityRepository.updateMany(ids, data);
373
+ }
368
374
  }
@@ -1,4 +1,2 @@
1
- import type { apiDbClient } from "../../../utils/prisma";
2
1
  export * from "./protocol.model";
3
2
  export * from "./protocol.service";
4
- export declare const initProtocolService: (dbClient: typeof apiDbClient) => any;
@@ -1,10 +1,2 @@
1
- import { initChainService } from "../chain";
2
- import { ProtocolRepository } from "./protocol.repository";
3
- import { ProtocolService } from "./protocol.service";
4
1
  export * from "./protocol.model";
5
2
  export * from "./protocol.service";
6
- export const initProtocolService = (dbClient) => {
7
- const repository = new ProtocolRepository(dbClient);
8
- const chainService = initChainService(dbClient);
9
- return new ProtocolService(repository, chainService);
10
- };
@@ -28,8 +28,18 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
28
28
  };
29
29
  headers: unknown;
30
30
  response: {
31
- [x: string]: any;
32
- 200: any;
31
+ 200: ({
32
+ name: string;
33
+ url: string;
34
+ description: string;
35
+ id: string;
36
+ tags: string[];
37
+ icon: string;
38
+ } & {
39
+ dailyRewards?: number | undefined;
40
+ numberOfLiveCampaigns?: number | undefined;
41
+ opportunityLiveTags?: string[] | undefined;
42
+ })[];
33
43
  };
34
44
  };
35
45
  };
@@ -43,8 +53,7 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
43
53
  query: unknown;
44
54
  headers: unknown;
45
55
  response: {
46
- [x: string]: any;
47
- 200: any;
56
+ 200: number;
48
57
  };
49
58
  };
50
59
  };
@@ -60,8 +69,17 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
60
69
  query: unknown;
61
70
  headers: unknown;
62
71
  response: {
63
- [x: string]: any;
64
- 200: any;
72
+ 200: {
73
+ name: string;
74
+ url: string;
75
+ description: string;
76
+ id: string;
77
+ tags: string[];
78
+ icon: string;
79
+ dailyRewards?: number | undefined;
80
+ numberOfLiveCampaigns?: number | undefined;
81
+ opportunityLiveTags?: string[] | undefined;
82
+ } | null;
65
83
  };
66
84
  };
67
85
  };
@@ -84,8 +102,14 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
84
102
  authorization: string;
85
103
  };
86
104
  response: {
87
- [x: string]: any;
88
- 200: any;
105
+ 200: {
106
+ name: string;
107
+ url: string;
108
+ description: string;
109
+ id: string;
110
+ tags: string[];
111
+ icon: string;
112
+ };
89
113
  };
90
114
  };
91
115
  };
@@ -108,8 +132,14 @@ export declare const ProtocolController: Elysia<"/protocols", false, {
108
132
  authorization: string;
109
133
  };
110
134
  response: {
111
- [x: string]: any;
112
- 200: any;
135
+ 200: {
136
+ name: string;
137
+ url: string;
138
+ description: string;
139
+ id: string;
140
+ tags: string[];
141
+ icon: string;
142
+ };
113
143
  };
114
144
  };
115
145
  };
@@ -1,30 +1,28 @@
1
1
  import { AuthorizationHeadersDto, BackOfficeGuard } from "../../../guards/BackOffice.guard";
2
- import { apiDbClient } from "../../../utils/prisma";
3
2
  import Elysia, { t } from "elysia";
4
- import { initProtocolService } from ".";
3
+ import { ProtocolService } from ".";
5
4
  import { CreateProtocolDto, GetProtocolsQueryDto, ProtocolIdDto, ProtocolResourceDto, UpdateProtocolDto, } from "./protocol.model";
6
- const protocolService = initProtocolService(apiDbClient);
7
5
  // ─── Protocols Controller ────────────────────────────────────────────────────
8
6
  export const ProtocolController = new Elysia({ prefix: "/protocols", detail: { tags: ["Protocols"] } })
9
7
  // ─── Get Many Protocols ──────────────────────────────────────────────
10
- .get("/", async ({ query }) => await protocolService.findMany(query), {
8
+ .get("/", async ({ query }) => await ProtocolService.findMany(query), {
11
9
  query: GetProtocolsQueryDto,
12
10
  response: t.Array(ProtocolResourceDto),
13
11
  detail: { description: "List protocols supported and integrated by Merkl." },
14
12
  })
15
13
  // ─── Count Protocols ─────────────────────────────────────────────────
16
- .get("/count", async ({ query }) => await protocolService.countMany(query), {
14
+ .get("/count", async ({ query }) => await ProtocolService.countMany(query), {
17
15
  detail: { description: "Get the number of protocols correspoinding to the query." },
18
16
  })
19
17
  // ─── Get A Protocol By Its Id Or Name ────────────────────────────────
20
18
  .get("/:id", async ({ params }) => {
21
- const fromId = await protocolService.getFromId(params.id);
19
+ const fromId = await ProtocolService.getFromId(params.id);
22
20
  if (fromId)
23
21
  return fromId;
24
- return await protocolService.getFromName(params.id);
22
+ return await ProtocolService.getFromName(params.id);
25
23
  }, { detail: { hide: true } })
26
24
  // ─── Update A Protocol ───────────────────────────────────────────────
27
- .patch("/:id", async ({ params, body }) => await protocolService.update(params.id, body), {
25
+ .patch("/:id", async ({ params, body }) => await ProtocolService.update(params.id, body), {
28
26
  params: ProtocolIdDto,
29
27
  body: UpdateProtocolDto,
30
28
  headers: AuthorizationHeadersDto,
@@ -32,7 +30,7 @@ export const ProtocolController = new Elysia({ prefix: "/protocols", detail: { t
32
30
  detail: { hide: true },
33
31
  })
34
32
  // ─── Create A Protocol ───────────────────────────────────────────────
35
- .post("/", async ({ body }) => await protocolService.create(body), {
33
+ .post("/", async ({ body }) => await ProtocolService.create(body), {
36
34
  body: CreateProtocolDto,
37
35
  headers: AuthorizationHeadersDto,
38
36
  beforeHandle: BackOfficeGuard,
@@ -879,6 +879,7 @@ export declare const v4: Elysia<"/v4", false, {
879
879
  patch: {
880
880
  body: {
881
881
  name?: string | undefined;
882
+ status?: "NONE" | "PAST" | "LIVE" | "SOON" | undefined;
882
883
  tags?: string[] | undefined;
883
884
  };
884
885
  params: {
@@ -1279,8 +1280,18 @@ export declare const v4: Elysia<"/v4", false, {
1279
1280
  };
1280
1281
  headers: unknown;
1281
1282
  response: {
1282
- [x: string]: any;
1283
- 200: any;
1283
+ 200: ({
1284
+ name: string;
1285
+ url: string;
1286
+ description: string;
1287
+ id: string;
1288
+ tags: string[];
1289
+ icon: string;
1290
+ } & {
1291
+ dailyRewards?: number | undefined;
1292
+ numberOfLiveCampaigns?: number | undefined;
1293
+ opportunityLiveTags?: string[] | undefined;
1294
+ })[];
1284
1295
  };
1285
1296
  };
1286
1297
  };
@@ -1294,8 +1305,7 @@ export declare const v4: Elysia<"/v4", false, {
1294
1305
  query: unknown;
1295
1306
  headers: unknown;
1296
1307
  response: {
1297
- [x: string]: any;
1298
- 200: any;
1308
+ 200: number;
1299
1309
  };
1300
1310
  };
1301
1311
  };
@@ -1311,8 +1321,17 @@ export declare const v4: Elysia<"/v4", false, {
1311
1321
  query: unknown;
1312
1322
  headers: unknown;
1313
1323
  response: {
1314
- [x: string]: any;
1315
- 200: any;
1324
+ 200: {
1325
+ name: string;
1326
+ url: string;
1327
+ description: string;
1328
+ id: string;
1329
+ tags: string[];
1330
+ icon: string;
1331
+ dailyRewards?: number | undefined;
1332
+ numberOfLiveCampaigns?: number | undefined;
1333
+ opportunityLiveTags?: string[] | undefined;
1334
+ } | null;
1316
1335
  };
1317
1336
  };
1318
1337
  };
@@ -1335,8 +1354,14 @@ export declare const v4: Elysia<"/v4", false, {
1335
1354
  authorization: string;
1336
1355
  };
1337
1356
  response: {
1338
- [x: string]: any;
1339
- 200: any;
1357
+ 200: {
1358
+ name: string;
1359
+ url: string;
1360
+ description: string;
1361
+ id: string;
1362
+ tags: string[];
1363
+ icon: string;
1364
+ };
1340
1365
  };
1341
1366
  };
1342
1367
  };
@@ -1359,8 +1384,14 @@ export declare const v4: Elysia<"/v4", false, {
1359
1384
  authorization: string;
1360
1385
  };
1361
1386
  response: {
1362
- [x: string]: any;
1363
- 200: any;
1387
+ 200: {
1388
+ name: string;
1389
+ url: string;
1390
+ description: string;
1391
+ id: string;
1392
+ tags: string[];
1393
+ icon: string;
1394
+ };
1364
1395
  };
1365
1396
  };
1366
1397
  };
@@ -7,7 +7,7 @@ import { ChainDto } from "../accounting";
7
7
  import { CreateTokenDto, FindUniqueTokenAllowanceDto, FindUniqueTokenDto, GetTokenBalanceDto, GetTokenQueryDto, NotionWebhookDto, TokenIdDto, UpdateTokenDto, } from "./token.model";
8
8
  import { TokenService } from "./token.service";
9
9
  // ─── Tokens Controller ───────────────────────────────────────────────────────
10
- export const TokenController = new Elysia({ prefix: "/tokens", detail: { tags: ["Tokens"], hide: true } })
10
+ export const TokenController = new Elysia({ prefix: "/tokens", detail: { tags: ["Tokens"] } })
11
11
  // ─── Get A Token By Id ───────────────────────────────────────────────
12
12
  .get("/:id", async ({ params }) => {
13
13
  try {
@@ -18,7 +18,12 @@ export const TokenController = new Elysia({ prefix: "/tokens", detail: { tags: [
18
18
  if (err.code && err.code === "P2025")
19
19
  throw new NotFoundError();
20
20
  }
21
- }, { params: FindUniqueTokenDto })
21
+ }, {
22
+ params: FindUniqueTokenDto,
23
+ detail: {
24
+ hide: true,
25
+ },
26
+ })
22
27
  .get("/:id/allowance/:owner/:spender", async ({ params: { id, owner, spender } }) => {
23
28
  try {
24
29
  const [chainId, address] = id.split("-");
@@ -30,11 +35,19 @@ export const TokenController = new Elysia({ prefix: "/tokens", detail: { tags: [
30
35
  if (err.code && err.code === "P2025")
31
36
  throw new NotFoundError();
32
37
  }
33
- }, { params: FindUniqueTokenAllowanceDto })
38
+ }, {
39
+ params: FindUniqueTokenAllowanceDto,
40
+ detail: {
41
+ hide: true,
42
+ },
43
+ })
34
44
  // ─── Get Valid Reward Token ───────────────────────────────────────────
35
45
  .get("/reward/:chainId", async ({ params }) => TokenService.getValidRewardTokens(params.chainId), {
36
46
  params: ChainDto,
37
47
  beforeHandle: ({ params }) => throwOnUnsupportedChainId(params.chainId),
48
+ detail: {
49
+ description: "Get the list of tokens that are accept as reward tokens on a given chain",
50
+ },
38
51
  })
39
52
  // ─── Get Tokens With Balances ────────────────────────────────────────
40
53
  .get("/balances", async ({ query: { chainId, userAddress, tokenAddress, additionalTokenAddresses } }) => {
@@ -43,11 +56,24 @@ export const TokenController = new Elysia({ prefix: "/tokens", detail: { tags: [
43
56
  return await TokenService.fetchVerifiedBalances(chainId, userAddress, additionalTokenAddresses);
44
57
  }, {
45
58
  query: GetTokenBalanceDto,
59
+ detail: {
60
+ hide: true,
61
+ },
46
62
  })
47
63
  // ─── Get Many Tokens ─────────────────────────────────────────────────
48
- .get("/", async ({ query }) => await TokenService.findMany(query), { query: GetTokenQueryDto })
64
+ .get("/", async ({ query }) => await TokenService.findMany(query), {
65
+ query: GetTokenQueryDto,
66
+ detail: {
67
+ hide: true,
68
+ },
69
+ })
49
70
  // ─── Count Tokens ────────────────────────────────────────────────────
50
- .get("/count", async ({ query }) => await TokenService.countMany(query), { query: GetTokenQueryDto })
71
+ .get("/count", async ({ query }) => await TokenService.countMany(query), {
72
+ query: GetTokenQueryDto,
73
+ detail: {
74
+ hide: true,
75
+ },
76
+ })
51
77
  // ─── Update IsTest Status ────────────────────────────────────────────
52
78
  .post("/", async ({ body }) => await TokenService.fillAndCreate(body), {
53
79
  body: CreateTokenDto,