@merkl/api 0.10.249 → 0.10.251

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.
@@ -406,6 +406,7 @@ declare const eden: {
406
406
  page?: number | undefined;
407
407
  chainId?: string | undefined;
408
408
  action?: string | undefined;
409
+ creatorAddress?: string | undefined;
409
410
  mainProtocolId?: string | undefined;
410
411
  order?: string | undefined;
411
412
  test?: boolean | undefined;
@@ -516,6 +517,7 @@ declare const eden: {
516
517
  page?: number | undefined;
517
518
  chainId?: string | undefined;
518
519
  action?: string | undefined;
520
+ creatorAddress?: string | undefined;
519
521
  mainProtocolId?: string | undefined;
520
522
  order?: string | undefined;
521
523
  test?: boolean | undefined;
@@ -541,6 +543,7 @@ declare const eden: {
541
543
  page?: number | undefined;
542
544
  chainId?: string | undefined;
543
545
  action?: string | undefined;
546
+ creatorAddress?: string | undefined;
544
547
  mainProtocolId?: string | undefined;
545
548
  order?: string | undefined;
546
549
  test?: boolean | undefined;
@@ -557,6 +560,7 @@ declare const eden: {
557
560
  campaigns: {
558
561
  index: {
559
562
  post: (body: {
563
+ tags?: string[] | undefined;
560
564
  identifier?: string | undefined;
561
565
  subType?: number | undefined;
562
566
  type: number;
@@ -2929,6 +2933,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
2929
2933
  page?: number | undefined;
2930
2934
  chainId?: string | undefined;
2931
2935
  action?: string | undefined;
2936
+ creatorAddress?: string | undefined;
2932
2937
  mainProtocolId?: string | undefined;
2933
2938
  order?: string | undefined;
2934
2939
  test?: boolean | undefined;
@@ -3044,6 +3049,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
3044
3049
  page?: number | undefined;
3045
3050
  chainId?: string | undefined;
3046
3051
  action?: string | undefined;
3052
+ creatorAddress?: string | undefined;
3047
3053
  mainProtocolId?: string | undefined;
3048
3054
  order?: string | undefined;
3049
3055
  test?: boolean | undefined;
@@ -3340,6 +3346,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
3340
3346
  page?: number | undefined;
3341
3347
  chainId?: string | undefined;
3342
3348
  action?: string | undefined;
3349
+ creatorAddress?: string | undefined;
3343
3350
  mainProtocolId?: string | undefined;
3344
3351
  order?: string | undefined;
3345
3352
  test?: boolean | undefined;
@@ -3397,6 +3404,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
3397
3404
  index: {
3398
3405
  post: {
3399
3406
  body: {
3407
+ tags?: string[] | undefined;
3400
3408
  identifier?: string | undefined;
3401
3409
  subType?: number | undefined;
3402
3410
  type: number;
@@ -6598,6 +6606,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
6598
6606
  page?: number | undefined;
6599
6607
  chainId?: string | undefined;
6600
6608
  action?: string | undefined;
6609
+ creatorAddress?: string | undefined;
6601
6610
  mainProtocolId?: string | undefined;
6602
6611
  order?: string | undefined;
6603
6612
  test?: boolean | undefined;
@@ -6708,6 +6717,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
6708
6717
  page?: number | undefined;
6709
6718
  chainId?: string | undefined;
6710
6719
  action?: string | undefined;
6720
+ creatorAddress?: string | undefined;
6711
6721
  mainProtocolId?: string | undefined;
6712
6722
  order?: string | undefined;
6713
6723
  test?: boolean | undefined;
@@ -6733,6 +6743,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
6733
6743
  page?: number | undefined;
6734
6744
  chainId?: string | undefined;
6735
6745
  action?: string | undefined;
6746
+ creatorAddress?: string | undefined;
6736
6747
  mainProtocolId?: string | undefined;
6737
6748
  order?: string | undefined;
6738
6749
  test?: boolean | undefined;
@@ -6749,6 +6760,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
6749
6760
  campaigns: {
6750
6761
  index: {
6751
6762
  post: (body: {
6763
+ tags?: string[] | undefined;
6752
6764
  identifier?: string | undefined;
6753
6765
  subType?: number | undefined;
6754
6766
  type: number;
@@ -187,6 +187,7 @@ declare const app: Elysia<"", false, {
187
187
  page?: number | undefined;
188
188
  chainId?: string | undefined;
189
189
  action?: string | undefined;
190
+ creatorAddress?: string | undefined;
190
191
  mainProtocolId?: string | undefined;
191
192
  order?: string | undefined;
192
193
  test?: boolean | undefined;
@@ -302,6 +303,7 @@ declare const app: Elysia<"", false, {
302
303
  page?: number | undefined;
303
304
  chainId?: string | undefined;
304
305
  action?: string | undefined;
306
+ creatorAddress?: string | undefined;
305
307
  mainProtocolId?: string | undefined;
306
308
  order?: string | undefined;
307
309
  test?: boolean | undefined;
@@ -598,6 +600,7 @@ declare const app: Elysia<"", false, {
598
600
  page?: number | undefined;
599
601
  chainId?: string | undefined;
600
602
  action?: string | undefined;
603
+ creatorAddress?: string | undefined;
601
604
  mainProtocolId?: string | undefined;
602
605
  order?: string | undefined;
603
606
  test?: boolean | undefined;
@@ -655,6 +658,7 @@ declare const app: Elysia<"", false, {
655
658
  index: {
656
659
  post: {
657
660
  body: {
661
+ tags?: string[] | undefined;
658
662
  identifier?: string | undefined;
659
663
  subType?: number | undefined;
660
664
  type: number;
@@ -16,6 +16,7 @@ export declare const CampaignController: Elysia<"/campaigns", false, {
16
16
  index: {
17
17
  post: {
18
18
  body: {
19
+ tags?: string[] | undefined;
19
20
  identifier?: string | undefined;
20
21
  subType?: number | undefined;
21
22
  type: number;
@@ -100,6 +100,7 @@ export declare const CreateCampaignDto: import("@sinclair/typebox").TObject<{
100
100
  startTimestamp: import("@sinclair/typebox").TString;
101
101
  endTimestamp: import("@sinclair/typebox").TString;
102
102
  params: import("@sinclair/typebox").TString;
103
+ tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
103
104
  }>;
104
105
  export declare const GetCampaignQueryDto: import("@sinclair/typebox").TObject<{
105
106
  creatorTag: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
@@ -61,6 +61,7 @@ export const CreateCampaignDto = t.Object({
61
61
  startTimestamp: t.String(),
62
62
  endTimestamp: t.String(),
63
63
  params: t.String(),
64
+ tags: t.Optional(t.Array(t.String())),
64
65
  });
65
66
  export const GetCampaignQueryDto = t.Object({
66
67
  creatorTag: t.Optional(t.String({ description: "Filter campaigns created by a user who has a specific tag" })),
@@ -106,6 +106,7 @@ export class CampaignRepository {
106
106
  connect: metadata.mainProtocol && { id: metadata.mainProtocol },
107
107
  },
108
108
  depositUrl: !!params.url ? params.url : undefined,
109
+ tags: metadata.tags,
109
110
  },
110
111
  },
111
112
  },
@@ -188,6 +189,7 @@ export class CampaignRepository {
188
189
  id: campaignToOpp[campaign.id].mainProtocol,
189
190
  },
190
191
  },
192
+ tags: campaignToOpp[campaign.id].tags,
191
193
  },
192
194
  },
193
195
  },
@@ -9,6 +9,7 @@ import { NETWORK_LABELS } from "@sdk";
9
9
  import moment from "moment";
10
10
  import { StatusService } from "../status";
11
11
  import { TokenService } from "../token";
12
+ import { UserService } from "../user";
12
13
  export class CampaignService {
13
14
  static hashId(campaign) {
14
15
  return Bun.hash(`${campaign.distributionChain}${campaign.campaignId}`).toString();
@@ -19,6 +20,10 @@ export class CampaignService {
19
20
  id,
20
21
  ...campaign,
21
22
  });
23
+ opportunityMetadata.tags = [
24
+ ...((await UserService.findUnique(campaign.creator))?.tags ?? []),
25
+ ...(campaign?.tags ?? []),
26
+ ];
22
27
  return await CampaignRepository.upsert({ id, ...campaign }, opportunityMetadata);
23
28
  }
24
29
  static async createMany(campaigns) {
@@ -33,6 +38,10 @@ export class CampaignService {
33
38
  id,
34
39
  ...campaign,
35
40
  });
41
+ oppMetadata.tags = [
42
+ ...((await UserService.findUnique(campaign.creator))?.tags ?? []),
43
+ ...(campaign?.tags ?? []),
44
+ ];
36
45
  campaignToOppMetadata[id] = oppMetadata;
37
46
  campaignsToInsert.push({ id, ...campaign });
38
47
  }
@@ -5,7 +5,7 @@ export class ClaimService {
5
5
  // ─── Get Historical Claims ─────────────────────────────────────────────────
6
6
  static async getHistoricalClaims(params, chainFilter = []) {
7
7
  const roots = (await MerklRootService.fetchAll()).map(r => r.live);
8
- const rewards = await RewardService.getByRecipient(params.address, roots, true, chainFilter);
8
+ const rewards = await RewardService.getByRecipient(params.address, roots, true, true, chainFilter);
9
9
  const filteredRewards = chainFilter.length
10
10
  ? rewards.filter(reward => chainFilter.includes(reward.RewardToken.chainId))
11
11
  : rewards;
@@ -56,6 +56,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
56
56
  page?: number | undefined;
57
57
  chainId?: string | undefined;
58
58
  action?: string | undefined;
59
+ creatorAddress?: string | undefined;
59
60
  mainProtocolId?: string | undefined;
60
61
  order?: string | undefined;
61
62
  test?: boolean | undefined;
@@ -171,6 +172,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
171
172
  page?: number | undefined;
172
173
  chainId?: string | undefined;
173
174
  action?: string | undefined;
175
+ creatorAddress?: string | undefined;
174
176
  mainProtocolId?: string | undefined;
175
177
  order?: string | undefined;
176
178
  test?: boolean | undefined;
@@ -467,6 +469,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
467
469
  page?: number | undefined;
468
470
  chainId?: string | undefined;
469
471
  action?: string | undefined;
472
+ creatorAddress?: string | undefined;
470
473
  mainProtocolId?: string | undefined;
471
474
  order?: string | undefined;
472
475
  test?: boolean | undefined;
@@ -33,6 +33,7 @@ export type OpportunityMetadata = {
33
33
  address: string;
34
34
  }[];
35
35
  mainProtocol?: ProtocolId;
36
+ tags?: string[];
36
37
  };
37
38
  export type OpportunityUnique = {
38
39
  chainId: ChainId;
@@ -278,6 +279,7 @@ export declare const GetOpportunitiesQueryDto: import("@sinclair/typebox").TObje
278
279
  name: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
279
280
  chainId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRegExp>;
280
281
  action: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TRegExp>;
282
+ creatorAddress: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
281
283
  tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
282
284
  test: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
283
285
  minimumTvl: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
@@ -51,6 +51,7 @@ export const GetOpportunitiesQueryDto = t.Object({
51
51
  action: t.Optional(t.RegExp(/^(POOL|HOLD|DROP|LEND|BORROW)(,(POOL|HOLD|DROP|LEND|BORROW)){0,4}$/, {
52
52
  description: "A comma seprated list actions. Legal values are: `POOL`, `HOLD`, `DROP`, `LEND`, `BORROW`",
53
53
  })),
54
+ creatorAddress: t.Optional(t.String({ description: "Filter by creator address" })),
54
55
  tags: t.Optional(t.String({ description: "Filter by tag" })),
55
56
  test: t.Optional(t.Boolean({ description: "Include opportunities with test campaigns" })),
56
57
  minimumTvl: t.Optional(t.Number({ description: "Minimum TVL threshhold in USD" })),
@@ -137,6 +137,7 @@ export class OpportunityRepository {
137
137
  const sort = (query.sort === "rewards" ? "dailyRewards" : query.sort) ?? "dailyRewards";
138
138
  const order = query.order ?? "desc";
139
139
  const test = query.test ?? false;
140
+ const creatorAddress = query.creatorAddress ?? null;
140
141
  const noFilters = Object.values(filters).every(v => v === undefined);
141
142
  const tokensFilters = tokens?.map(symbol => ({
142
143
  Tokens: { some: { symbol: { equals: symbol, mode: "insensitive" } } },
@@ -162,7 +163,16 @@ export class OpportunityRepository {
162
163
  status: !status ? undefined : { in: status },
163
164
  },
164
165
  { mainProtocolId: !protocols ? undefined : { in: protocols } },
165
- { Campaigns: test ? undefined : { some: { RewardToken: { isTest: false } } } },
166
+ {
167
+ Campaigns: test || !creatorAddress
168
+ ? undefined
169
+ : {
170
+ some: {
171
+ RewardToken: !test ? { isTest: false } : undefined,
172
+ creatorAddress: creatorAddress ? creatorAddress : undefined,
173
+ },
174
+ },
175
+ },
166
176
  ],
167
177
  },
168
178
  };
@@ -172,6 +182,7 @@ export class OpportunityRepository {
172
182
  const { page: _page, items: _items } = query;
173
183
  const page = _page ? _page : 0;
174
184
  const items = _items ? _items : 20;
185
+ const test = query.test ?? false;
175
186
  const args = OpportunityRepository.#transformQueryToPrismaFilters(query);
176
187
  return await apiDbClient.opportunity.findMany({
177
188
  take: items,
@@ -181,7 +192,9 @@ export class OpportunityRepository {
181
192
  MainProtocol: true,
182
193
  Chain: true,
183
194
  Protocols: true,
184
- Tokens: true,
195
+ Tokens: {
196
+ where: !test ? { isTest: false } : undefined,
197
+ },
185
198
  },
186
199
  ...args,
187
200
  });
@@ -65,6 +65,7 @@ export declare const v4: Elysia<"/v4", false, {
65
65
  page?: number | undefined;
66
66
  chainId?: string | undefined;
67
67
  action?: string | undefined;
68
+ creatorAddress?: string | undefined;
68
69
  mainProtocolId?: string | undefined;
69
70
  order?: string | undefined;
70
71
  test?: boolean | undefined;
@@ -180,6 +181,7 @@ export declare const v4: Elysia<"/v4", false, {
180
181
  page?: number | undefined;
181
182
  chainId?: string | undefined;
182
183
  action?: string | undefined;
184
+ creatorAddress?: string | undefined;
183
185
  mainProtocolId?: string | undefined;
184
186
  order?: string | undefined;
185
187
  test?: boolean | undefined;
@@ -476,6 +478,7 @@ export declare const v4: Elysia<"/v4", false, {
476
478
  page?: number | undefined;
477
479
  chainId?: string | undefined;
478
480
  action?: string | undefined;
481
+ creatorAddress?: string | undefined;
479
482
  mainProtocolId?: string | undefined;
480
483
  order?: string | undefined;
481
484
  test?: boolean | undefined;
@@ -533,6 +536,7 @@ export declare const v4: Elysia<"/v4", false, {
533
536
  index: {
534
537
  post: {
535
538
  body: {
539
+ tags?: string[] | undefined;
536
540
  identifier?: string | undefined;
537
541
  subType?: number | undefined;
538
542
  type: number;
@@ -64,7 +64,10 @@ export const UserController = new Elysia({ prefix: "/users", detail: { tags: ["U
64
64
  detail: { hide: true },
65
65
  })
66
66
  // ─── Sync Creator Tags with Engine DB ─────────────────────────────────
67
- .post("/sync", async () => await UserService.syncTags(), {
67
+ .post("/sync", async () => {
68
+ await UserService.syncTags();
69
+ await UserService.syncOpportunityTags();
70
+ }, {
68
71
  headers: AuthorizationHeadersDto,
69
72
  beforeHandle: BackOfficeGuard,
70
73
  detail: { hide: true },
@@ -22,4 +22,5 @@ export declare abstract class UserService {
22
22
  address: string;
23
23
  }>;
24
24
  static syncTags(): Promise<void>;
25
+ static syncOpportunityTags(): Promise<void>;
25
26
  }
@@ -1,5 +1,6 @@
1
1
  import { log } from "../../../utils/logger";
2
2
  import { engineDbClient } from "../../../utils/prisma";
3
+ import { OpportunityService } from "../opportunity";
3
4
  import { UserRepository } from "./user.repository";
4
5
  // ─── Users Services ──────────────────────────────────────────────────────────
5
6
  export class UserService {
@@ -19,6 +20,9 @@ export class UserService {
19
20
  return await UserRepository.createMany(users);
20
21
  }
21
22
  static async updateTags(user, tags) {
23
+ if (!(await UserRepository.findUnique(user))) {
24
+ await UserRepository.create({ address: user, tags: [] });
25
+ }
22
26
  return await UserRepository.updateTags(user, tags);
23
27
  }
24
28
  static async syncTags() {
@@ -47,4 +51,17 @@ export class UserService {
47
51
  }
48
52
  }
49
53
  }
54
+ static async syncOpportunityTags() {
55
+ const users = await UserRepository.findManyWithTags();
56
+ for (const user of users) {
57
+ const opportunities = await OpportunityService.getMany({ creatorAddress: user.address });
58
+ for (const opportunity of opportunities) {
59
+ if (!user.tags.every(tag => opportunity.tags.includes(tag))) {
60
+ log.local(`updating tags for opportunity ${opportunity.id}: adding ${user.tags.join(",")}`);
61
+ log.local(`opportunity tags: ${opportunity.tags.join(",")}`);
62
+ await OpportunityService.update(opportunity.id, { tags: [...opportunity.tags, ...user.tags] });
63
+ }
64
+ }
65
+ }
66
+ }
50
67
  }
@@ -27,7 +27,7 @@ export default (app) => app.use(checkQueryAddressValidity()).get("/rewards", asy
27
27
  }
28
28
  const user = query.user;
29
29
  // @Warning: this is not taking into account the creator tag filter
30
- const v4Res = await RewardService.getUserRewardsByChain(user, false, chainIds);
30
+ const v4Res = await RewardService.getUserRewardsByChain(user, false, chainIds, null, true);
31
31
  const v3Res = RewardConvertorService.convertV4toRewardV3(v4Res);
32
32
  return v3Res;
33
33
  }, { query, tags: ["Rewards"] });
@@ -45,7 +45,7 @@ export default (app) => app
45
45
  }
46
46
  }
47
47
  // @Warning: this is not taking into account the mainParameter filter
48
- const v4Res = await RewardService.getUserRewardsByChain(user, false, [chainId], query.reloadChainId ?? null);
48
+ const v4Res = await RewardService.getUserRewardsByChain(user, false, [chainId], query.reloadChainId ?? null, true);
49
49
  const v3Res = RewardConvertorService.convertV4toUserRewardV3(v4Res, proof);
50
50
  return v3Res;
51
51
  }, {