@merkl/api 0.10.320 → 0.10.321

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.
@@ -708,6 +708,22 @@ declare const eden: {
708
708
  } | undefined;
709
709
  }>>;
710
710
  };
711
+ opportunity: {
712
+ patch: (body: {
713
+ tags?: string[] | undefined;
714
+ opportunityIdentifier?: string | undefined;
715
+ campaignId: string;
716
+ distributionChain: number;
717
+ }, options: {
718
+ headers: {
719
+ authorization: string;
720
+ };
721
+ query?: Record<string, unknown> | undefined;
722
+ fetch?: RequestInit | undefined;
723
+ }) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
724
+ 200: string;
725
+ }>>;
726
+ };
711
727
  index: {
712
728
  get: (options: {
713
729
  headers?: Record<string, unknown> | undefined;
@@ -2448,7 +2464,7 @@ declare const eden: {
2448
2464
  strategy?: string | undefined;
2449
2465
  poolId?: string | undefined;
2450
2466
  contract?: string | undefined;
2451
- forwarders?: {}[] | undefined;
2467
+ forwarders?: (string | {})[] | undefined;
2452
2468
  targetToken?: string | undefined;
2453
2469
  isOutOfRangeIncentivized?: boolean | undefined;
2454
2470
  weightFees?: number | undefined;
@@ -3924,6 +3940,25 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
3924
3940
  };
3925
3941
  };
3926
3942
  };
3943
+ } & {
3944
+ opportunity: {
3945
+ patch: {
3946
+ body: {
3947
+ tags?: string[] | undefined;
3948
+ opportunityIdentifier?: string | undefined;
3949
+ campaignId: string;
3950
+ distributionChain: number;
3951
+ };
3952
+ params: {};
3953
+ query: unknown;
3954
+ headers: {
3955
+ authorization: string;
3956
+ };
3957
+ response: {
3958
+ 200: string;
3959
+ };
3960
+ };
3961
+ };
3927
3962
  } & {
3928
3963
  index: {
3929
3964
  get: {
@@ -6134,7 +6169,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
6134
6169
  strategy?: string | undefined;
6135
6170
  poolId?: string | undefined;
6136
6171
  contract?: string | undefined;
6137
- forwarders?: {}[] | undefined;
6172
+ forwarders?: (string | {})[] | undefined;
6138
6173
  targetToken?: string | undefined;
6139
6174
  isOutOfRangeIncentivized?: boolean | undefined;
6140
6175
  weightFees?: number | undefined;
@@ -7667,6 +7702,22 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
7667
7702
  } | undefined;
7668
7703
  }>>;
7669
7704
  };
7705
+ opportunity: {
7706
+ patch: (body: {
7707
+ tags?: string[] | undefined;
7708
+ opportunityIdentifier?: string | undefined;
7709
+ campaignId: string;
7710
+ distributionChain: number;
7711
+ }, options: {
7712
+ headers: {
7713
+ authorization: string;
7714
+ };
7715
+ query?: Record<string, unknown> | undefined;
7716
+ fetch?: RequestInit | undefined;
7717
+ }) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
7718
+ 200: string;
7719
+ }>>;
7720
+ };
7670
7721
  index: {
7671
7722
  get: (options: {
7672
7723
  headers?: Record<string, unknown> | undefined;
@@ -9407,7 +9458,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
9407
9458
  strategy?: string | undefined;
9408
9459
  poolId?: string | undefined;
9409
9460
  contract?: string | undefined;
9410
- forwarders?: {}[] | undefined;
9461
+ forwarders?: (string | {})[] | undefined;
9411
9462
  targetToken?: string | undefined;
9412
9463
  isOutOfRangeIncentivized?: boolean | undefined;
9413
9464
  weightFees?: number | undefined;
@@ -833,6 +833,25 @@ declare const app: Elysia<"", false, {
833
833
  };
834
834
  };
835
835
  };
836
+ } & {
837
+ opportunity: {
838
+ patch: {
839
+ body: {
840
+ tags?: string[] | undefined;
841
+ opportunityIdentifier?: string | undefined;
842
+ campaignId: string;
843
+ distributionChain: number;
844
+ };
845
+ params: {};
846
+ query: unknown;
847
+ headers: {
848
+ authorization: string;
849
+ };
850
+ response: {
851
+ 200: string;
852
+ };
853
+ };
854
+ };
836
855
  } & {
837
856
  index: {
838
857
  get: {
@@ -3043,7 +3062,7 @@ declare const app: Elysia<"", false, {
3043
3062
  strategy?: string | undefined;
3044
3063
  poolId?: string | undefined;
3045
3064
  contract?: string | undefined;
3046
- forwarders?: {}[] | undefined;
3065
+ forwarders?: (string | {})[] | undefined;
3047
3066
  targetToken?: string | undefined;
3048
3067
  isOutOfRangeIncentivized?: boolean | undefined;
3049
3068
  weightFees?: number | undefined;
@@ -55,6 +55,25 @@ export declare const CampaignController: Elysia<"/campaigns", false, {
55
55
  };
56
56
  };
57
57
  };
58
+ } & {
59
+ opportunity: {
60
+ patch: {
61
+ body: {
62
+ tags?: string[] | undefined;
63
+ opportunityIdentifier?: string | undefined;
64
+ campaignId: string;
65
+ distributionChain: number;
66
+ };
67
+ params: {};
68
+ query: unknown;
69
+ headers: {
70
+ authorization: string;
71
+ };
72
+ response: {
73
+ 200: string;
74
+ };
75
+ };
76
+ };
58
77
  } & {
59
78
  index: {
60
79
  get: {
@@ -1,8 +1,9 @@
1
+ import { BackOfficeGuard } from "../../../guards/BackOffice.guard";
1
2
  import { AuthorizationHeadersDto, EngineGuard } from "../../../guards/Engine.guard";
2
3
  import Elysia, { t } from "elysia";
3
4
  import { throwOnUnsupportedChainId } from "src/utils/throw";
4
5
  import { ChainUniqueDto } from "../chain";
5
- import { CampaignResourceDto, CreateCampaignDto, GetCampaignQueryDto } from "./campaign.model";
6
+ import { CampaignResourceDto, CreateCampaignDto, GetCampaignQueryDto, UpdateCampaignDto } from "./campaign.model";
6
7
  import { CampaignService } from "./campaign.service";
7
8
  // ─── Campaigns Controller ────────────────────────────────────────────────────
8
9
  export const CampaignController = new Elysia({ prefix: "/campaigns", detail: { tags: ["Campaigns"] } })
@@ -12,6 +13,12 @@ export const CampaignController = new Elysia({ prefix: "/campaigns", detail: { t
12
13
  headers: AuthorizationHeadersDto,
13
14
  body: CreateCampaignDto,
14
15
  detail: { hide: true },
16
+ })
17
+ .patch("/opportunity", async ({ body }) => await CampaignService.moveToOpportunity(body), {
18
+ beforeHandle: BackOfficeGuard,
19
+ headers: AuthorizationHeadersDto,
20
+ body: UpdateCampaignDto,
21
+ detail: { hide: true },
15
22
  })
16
23
  // ─── Get Many Campaigns ──────────────────────────────────────────────
17
24
  .get("/", async ({ query }) => await CampaignService.findMany(query), {
@@ -106,6 +106,12 @@ export declare const CreateCampaignDto: import("@sinclair/typebox").TObject<{
106
106
  params: import("@sinclair/typebox").TString;
107
107
  tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
108
108
  }>;
109
+ export declare const UpdateCampaignDto: import("@sinclair/typebox").TObject<{
110
+ distributionChain: import("@sinclair/typebox").TNumber;
111
+ campaignId: import("@sinclair/typebox").TString;
112
+ opportunityIdentifier: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
113
+ tags: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
114
+ }>;
109
115
  export declare const GetCampaignQueryDto: import("@sinclair/typebox").TObject<{
110
116
  creatorTag: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
111
117
  chainId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
@@ -147,4 +153,10 @@ export type CampaignUnique = typeof CampaignUniqueDto.static;
147
153
  export type CreateCampaignModel = typeof CreateCampaignDto.static & {
148
154
  id: string;
149
155
  };
156
+ export type UpdateCampaignModel = typeof UpdateCampaignDto.static & {
157
+ id: string;
158
+ };
159
+ export type extendedUpdateCampaignModel = UpdateCampaignModel & {
160
+ opportunityId: string;
161
+ };
150
162
  export type GetCampaignQueryModel = typeof GetCampaignQueryDto.static;
@@ -67,6 +67,12 @@ export const CreateCampaignDto = t.Object({
67
67
  params: t.String(),
68
68
  tags: t.Optional(t.Array(t.String())),
69
69
  });
70
+ export const UpdateCampaignDto = t.Object({
71
+ distributionChain: t.Numeric(),
72
+ campaignId: t.String(),
73
+ opportunityIdentifier: t.Optional(t.String()),
74
+ tags: t.Optional(t.Array(t.String())),
75
+ });
70
76
  export const GetCampaignQueryDto = t.Object({
71
77
  creatorTag: t.Optional(t.String({ description: "Filter campaigns created by a user who has a specific tag" })),
72
78
  chainId: t.Optional(t.Numeric({
@@ -1,4 +1,4 @@
1
- import type { CampaignUnique, CreateCampaignModel, GetCampaignQueryModel } from "./";
1
+ import type { CampaignUnique, CreateCampaignModel, GetCampaignQueryModel, extendedUpdateCampaignModel } from "./";
2
2
  import { Prisma } from "../../../../database/api/.generated";
3
3
  import { type ChainId } from "@sdk";
4
4
  export declare abstract class CampaignRepository {
@@ -134,4 +134,19 @@ export declare abstract class CampaignRepository {
134
134
  campaignId: string;
135
135
  }[]>;
136
136
  static findChains(): Promise<Record<string, ChainId>>;
137
+ static update(id: string, data: extendedUpdateCampaignModel): Promise<{
138
+ type: import("../../../../database/api/.generated").$Enums.CampaignType;
139
+ id: string;
140
+ params: Prisma.JsonValue;
141
+ subType: number | null;
142
+ startTimestamp: bigint;
143
+ endTimestamp: bigint;
144
+ computeChainId: number;
145
+ distributionChainId: number;
146
+ campaignId: string;
147
+ rewardTokenId: string;
148
+ amount: string;
149
+ opportunityId: string;
150
+ creatorAddress: string;
151
+ }>;
137
152
  }
@@ -303,4 +303,12 @@ export class CampaignRepository {
303
303
  return acc;
304
304
  }, {});
305
305
  }
306
+ static async update(id, data) {
307
+ const updateData = {
308
+ Opportunity: {
309
+ connect: { id: data.opportunityId },
310
+ },
311
+ };
312
+ return await apiDbClient.campaign.update({ where: { id }, data: updateData });
313
+ }
306
314
  }
@@ -1,4 +1,4 @@
1
- import { type CampaignUnique, type CampaignWithParams, type ConvertedCampaignType, type CreateCampaignModel, type GetCampaignQueryModel } from "./";
1
+ import { type CampaignUnique, type CampaignWithParams, type ConvertedCampaignType, type CreateCampaignModel, type GetCampaignQueryModel, type UpdateCampaignModel } from "./";
2
2
  import { CampaignRepository } from "./campaign.repository";
3
3
  import type { CampaignType } from "../../../../database/api/.generated";
4
4
  import { type CampaignParameters, type Campaign as CampaignTypeV3, type ChainId } from "@sdk";
@@ -19,6 +19,7 @@ export declare abstract class CampaignService {
19
19
  opportunityId: string;
20
20
  creatorAddress: string;
21
21
  } | undefined>;
22
+ static moveToOpportunity(campaign: Omit<UpdateCampaignModel, "id">, upsert?: boolean): Promise<string>;
22
23
  static createMany(campaigns: Omit<CreateCampaignModel, "id">[]): Promise<{
23
24
  success: number;
24
25
  fail: number;
@@ -5,10 +5,12 @@ import { CampaignRepository } from "./campaign.repository";
5
5
  import { OpportunityService } from "../opportunity";
6
6
  import { executeSimple } from "../../../utils/execute";
7
7
  import { log } from "../../../utils/logger";
8
- import { NETWORK_LABELS } from "@sdk";
8
+ import { NETWORK_LABELS, } from "@sdk";
9
+ import { utils } from "ethers";
9
10
  import moment from "moment";
10
11
  import { StatusService } from "../status";
11
12
  import { TokenService } from "../token";
13
+ import { TokenRepository } from "../token/token.repository";
12
14
  export class CampaignService {
13
15
  static hashId(campaign) {
14
16
  return Bun.hash(`${campaign.distributionChain}${campaign.campaignId}`).toString();
@@ -18,6 +20,55 @@ export class CampaignService {
18
20
  await OpportunityService.createFromCampaign(campaign);
19
21
  return await CampaignRepository.upsert({ id, ...campaign });
20
22
  }
23
+ static async moveToOpportunity(campaign, upsert = false) {
24
+ const id = CampaignService.hashId({
25
+ distributionChain: campaign.distributionChain,
26
+ campaignId: campaign.campaignId,
27
+ });
28
+ const existingCampaign = await CampaignService.findUniqueOrThrow(campaign);
29
+ const token = await TokenRepository.findUniqueOrThrow(existingCampaign.rewardTokenId);
30
+ if (existingCampaign.type === "ERC20" && campaign.opportunityIdentifier === undefined) {
31
+ const campaignParams = existingCampaign.params;
32
+ campaign.opportunityIdentifier = utils
33
+ .keccak256(campaignParams.targetToken &&
34
+ utils.keccak256(utils.defaultAbiCoder.encode(["address[]"], [campaignParams.whitelist.sort()])))
35
+ .slice(0, 42);
36
+ }
37
+ if (campaign.opportunityIdentifier === undefined) {
38
+ throw new HttpError("Bad Request: opportunityIdentifier is required for this campaign type", 400);
39
+ }
40
+ const updatedCampaign = {
41
+ ...existingCampaign,
42
+ opportunityIdentifier: campaign.opportunityIdentifier,
43
+ chainId: campaign.distributionChain,
44
+ creator: existingCampaign.creatorAddress,
45
+ rewardTokenAddress: token.address,
46
+ params: JSON.stringify(existingCampaign.params),
47
+ type: campaignTypeToEnumMap[existingCampaign.type],
48
+ subType: existingCampaign.subType ?? undefined,
49
+ startTimestamp: existingCampaign.startTimestamp.toString(),
50
+ endTimestamp: existingCampaign.endTimestamp.toString(),
51
+ };
52
+ const opportunityId = OpportunityService.hashId({
53
+ chainId: existingCampaign.computeChainId,
54
+ identifier: campaign.opportunityIdentifier,
55
+ type: existingCampaign.type,
56
+ });
57
+ const updatedCampaignData = {
58
+ ...campaign,
59
+ opportunityId,
60
+ };
61
+ // Create new opportunity
62
+ await OpportunityService.createFromCampaign(updatedCampaign, upsert);
63
+ // Move campaign to new opportunity
64
+ await CampaignRepository.update(id, { id, ...updatedCampaignData });
65
+ // Update new opportunity with campaign
66
+ await OpportunityService.recreate(opportunityId);
67
+ // Remov (update) campaign from old opportunity
68
+ await OpportunityService.recreate(existingCampaign.opportunityId);
69
+ // Return new opportunityId
70
+ return (await CampaignService.findUniqueOrThrow(campaign)).opportunityId;
71
+ }
21
72
  static async createMany(campaigns) {
22
73
  const failedToFetchMetadata = [];
23
74
  const campaignsToInsert = [];
@@ -191,7 +191,7 @@ export declare const ProgramPayloadController: Elysia<"/program-payload", false,
191
191
  strategy?: string | undefined;
192
192
  poolId?: string | undefined;
193
193
  contract?: string | undefined;
194
- forwarders?: {}[] | undefined;
194
+ forwarders?: (string | {})[] | undefined;
195
195
  targetToken?: string | undefined;
196
196
  isOutOfRangeIncentivized?: boolean | undefined;
197
197
  weightFees?: number | undefined;
@@ -23,7 +23,7 @@ export declare const SinglePayloadInputDto: import("@sinclair/typebox").TObject<
23
23
  endTimestamp: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
24
24
  targetToken: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
25
25
  url: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
26
- forwarders: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{}>>>;
26
+ forwarders: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TObject<{}>, import("@sinclair/typebox").TString]>>>;
27
27
  poolAddress: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
28
28
  isOutOfRangeIncentivized: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
29
29
  weightFees: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
@@ -24,7 +24,7 @@ export const SinglePayloadInputDto = t.Object({
24
24
  endTimestamp: t.Optional(t.Numeric({ description: "End timestamp for the campaign" })),
25
25
  targetToken: t.Optional(t.String({ description: "Address of the target token that is incentivized" })),
26
26
  url: t.Optional(t.String({ description: "URL for more information" })),
27
- forwarders: t.Optional(t.Array(t.Object({}))),
27
+ forwarders: t.Optional(t.Array(t.Union([t.Object({}), t.String()]))),
28
28
  poolAddress: t.Optional(t.String({ description: "Address of the pool that is incentivized" })),
29
29
  isOutOfRangeIncentivized: t.Optional(t.Boolean({ description: "Whether out-of-range is incentivized" })),
30
30
  weightFees: t.Optional(t.Number({ description: "Weight of the fees" })),
@@ -30,7 +30,8 @@ export declare enum pufferCampaigns {
30
30
  aerodrome_cl50_xpufETH = "0xCDf927C0F7b81b146C0C9e9323eb5A28D1BFA183",
31
31
  uniswapv3_eth_pufETH = "0xBDB04e915B94FbFD6e8552ff7860E59Db7d4499a",
32
32
  uniswapv3_weth_PUFFER = "0xc5c9a9AB6403CDBa9722463000146C18b504F0bA",
33
- uniswapv3_vt_weth = "0xa56600e670724b42F38d3A6e4B25e8D786B4F5f9"
33
+ uniswapv3_vt_weth = "0xa56600e670724b42F38d3A6e4B25e8D786B4F5f9",
34
+ venus_pufeth = "0xE0ee5dDeBFe0abe0a4Af50299D68b74Cec31668e"
34
35
  }
35
36
  export declare enum zkSyncCampaigns {
36
37
  Izumi_Finance_Zk_Weth = "Izumi Finance ZK/WETH 0xd62bc9f19bd94fde9c41df4b6eb6419ea6b8e25c",
@@ -33,6 +33,7 @@ export var pufferCampaigns;
33
33
  pufferCampaigns["uniswapv3_eth_pufETH"] = "0xBDB04e915B94FbFD6e8552ff7860E59Db7d4499a";
34
34
  pufferCampaigns["uniswapv3_weth_PUFFER"] = "0xc5c9a9AB6403CDBa9722463000146C18b504F0bA";
35
35
  pufferCampaigns["uniswapv3_vt_weth"] = "0xa56600e670724b42F38d3A6e4B25e8D786B4F5f9";
36
+ pufferCampaigns["venus_pufeth"] = "0xE0ee5dDeBFe0abe0a4Af50299D68b74Cec31668e";
36
37
  })(pufferCampaigns || (pufferCampaigns = {}));
37
38
  export var zkSyncCampaigns;
38
39
  (function (zkSyncCampaigns) {
@@ -1106,6 +1107,16 @@ const ZkSyncInterfaceCampaigns = {
1106
1107
  },
1107
1108
  };
1108
1109
  const PufferInterfaceCampaigns = {
1110
+ [pufferCampaigns.venus_pufeth]: {
1111
+ campaignType: Campaign.ERC20,
1112
+ computeChainId: ChainId.MAINNET,
1113
+ hooks: [],
1114
+ targetToken: "0xE0ee5dDeBFe0abe0a4Af50299D68b74Cec31668e",
1115
+ whitelist: [],
1116
+ blacklist: [],
1117
+ url: "https://app.venus.io/#/isolated-pools/pool/0xF522cd0360EF8c2FF48B648d53EA1717Ec0F3Ac3/market/0xE0ee5dDeBFe0abe0a4Af50299D68b74Cec31668e?chainId=1",
1118
+ forwarders: [],
1119
+ },
1109
1120
  [pufferCampaigns.Zircuit_Restaking_Pool]: {
1110
1121
  campaignType: Campaign.ERC20,
1111
1122
  computeChainId: ChainId.MAINNET,
@@ -59,7 +59,7 @@ export class ProgramPayloadService {
59
59
  const nonEncodedConfig = { ...parsedConfig };
60
60
  if ("forwarders" in parsedConfig) {
61
61
  parsedConfig.forwarders = config?.forwarders
62
- ? config.forwarders.map(forwarder => encodeForwarderData(forwarder))
62
+ ? config.forwarders.map(forwarder => typeof forwarder === "string" ? forwarder : encodeForwarderData(forwarder))
63
63
  : [];
64
64
  }
65
65
  const distributionChainId = config.distributionChainId ? config.distributionChainId : ChainId.MAINNET;
@@ -711,6 +711,25 @@ export declare const v4: Elysia<"/v4", false, {
711
711
  };
712
712
  };
713
713
  };
714
+ } & {
715
+ opportunity: {
716
+ patch: {
717
+ body: {
718
+ tags?: string[] | undefined;
719
+ opportunityIdentifier?: string | undefined;
720
+ campaignId: string;
721
+ distributionChain: number;
722
+ };
723
+ params: {};
724
+ query: unknown;
725
+ headers: {
726
+ authorization: string;
727
+ };
728
+ response: {
729
+ 200: string;
730
+ };
731
+ };
732
+ };
714
733
  } & {
715
734
  index: {
716
735
  get: {
@@ -2921,7 +2940,7 @@ export declare const v4: Elysia<"/v4", false, {
2921
2940
  strategy?: string | undefined;
2922
2941
  poolId?: string | undefined;
2923
2942
  contract?: string | undefined;
2924
- forwarders?: {}[] | undefined;
2943
+ forwarders?: (string | {})[] | undefined;
2925
2944
  targetToken?: string | undefined;
2926
2945
  isOutOfRangeIncentivized?: boolean | undefined;
2927
2946
  weightFees?: number | undefined;