@merkl/api 0.20.155 → 0.20.156

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.
@@ -234,6 +234,8 @@ export declare const CampaignTestController: Elysia<"/campaigns", false, {
234
234
  price?: number | null | undefined;
235
235
  })[];
236
236
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
237
+ description: string;
238
+ howToSteps: string[];
237
239
  depositUrl: string | undefined;
238
240
  explorerAddress: string | undefined;
239
241
  tags: string[];
@@ -342,6 +344,8 @@ export declare const CampaignTestController: Elysia<"/campaigns", false, {
342
344
  price?: number | null | undefined;
343
345
  })[];
344
346
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
347
+ description: string;
348
+ howToSteps: string[];
345
349
  depositUrl: string | undefined;
346
350
  explorerAddress: string | undefined;
347
351
  tags: string[];
@@ -17,7 +17,9 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
17
17
  post: {
18
18
  body: {
19
19
  name?: string | undefined;
20
+ description?: string | undefined;
20
21
  tags?: string[] | undefined;
22
+ howToSteps?: string[] | undefined;
21
23
  depositUrl?: string | undefined;
22
24
  explorerAddress?: string | undefined;
23
25
  protocols?: string[] | undefined;
@@ -214,6 +216,8 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
214
216
  price?: number | null | undefined;
215
217
  })[];
216
218
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
219
+ description: string;
220
+ howToSteps: string[];
217
221
  depositUrl: string | undefined;
218
222
  explorerAddress: string | undefined;
219
223
  tags: string[];
@@ -305,6 +309,8 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
305
309
  price?: number | null | undefined;
306
310
  })[];
307
311
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
312
+ description: string;
313
+ howToSteps: string[];
308
314
  depositUrl: string | undefined;
309
315
  explorerAddress: string | undefined;
310
316
  tags: string[];
@@ -590,9 +596,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
590
596
  tags: string[];
591
597
  icon: string;
592
598
  } | null | undefined;
593
- description?: string | undefined;
594
599
  distributionType?: "DUTCH_AUCTION" | "FIX_REWARD_VALUE_PER_LIQUIDITY_VALUE" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_VALUE" | "FIX_REWARD_VALUE_PER_LIQUIDITY_AMOUNT" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_AMOUNT" | undefined;
595
- howToSteps?: string[] | undefined;
596
600
  depositUrl?: string | undefined;
597
601
  explorerAddress?: string | undefined;
598
602
  aprRecord?: {
@@ -661,6 +665,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
661
665
  isPoint: boolean;
662
666
  isPreTGE: boolean;
663
667
  }[];
668
+ description: string;
664
669
  tags: string[];
665
670
  identifier: string;
666
671
  chain: {
@@ -670,6 +675,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
670
675
  };
671
676
  action: string;
672
677
  chainId: number;
678
+ howToSteps: string[];
673
679
  tvl: number;
674
680
  apr: number;
675
681
  dailyRewards: number;
@@ -729,9 +735,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
729
735
  tags: string[];
730
736
  icon: string;
731
737
  } | null | undefined;
732
- description?: string | undefined;
733
738
  distributionType?: "DUTCH_AUCTION" | "FIX_REWARD_VALUE_PER_LIQUIDITY_VALUE" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_VALUE" | "FIX_REWARD_VALUE_PER_LIQUIDITY_AMOUNT" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_AMOUNT" | undefined;
734
- howToSteps?: string[] | undefined;
735
739
  depositUrl?: string | undefined;
736
740
  explorerAddress?: string | undefined;
737
741
  aprRecord?: {
@@ -800,6 +804,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
800
804
  isPoint: boolean;
801
805
  isPreTGE: boolean;
802
806
  }[];
807
+ description: string;
803
808
  tags: string[];
804
809
  identifier: string;
805
810
  chain: {
@@ -809,6 +814,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
809
814
  };
810
815
  action: string;
811
816
  chainId: number;
817
+ howToSteps: string[];
812
818
  tvl: number;
813
819
  apr: number;
814
820
  dailyRewards: number;
@@ -905,9 +911,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
905
911
  tags: string[];
906
912
  icon: string;
907
913
  } | null | undefined;
908
- description?: string | undefined;
909
914
  distributionType?: "DUTCH_AUCTION" | "FIX_REWARD_VALUE_PER_LIQUIDITY_VALUE" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_VALUE" | "FIX_REWARD_VALUE_PER_LIQUIDITY_AMOUNT" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_AMOUNT" | undefined;
910
- howToSteps?: string[] | undefined;
911
915
  depositUrl?: string | undefined;
912
916
  explorerAddress?: string | undefined;
913
917
  aprRecord?: {
@@ -976,6 +980,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
976
980
  isPoint: boolean;
977
981
  isPreTGE: boolean;
978
982
  }[];
983
+ description: string;
979
984
  tags: string[];
980
985
  identifier: string;
981
986
  chain: {
@@ -985,6 +990,7 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
985
990
  };
986
991
  action: string;
987
992
  chainId: number;
993
+ howToSteps: string[];
988
994
  tvl: number;
989
995
  apr: number;
990
996
  dailyRewards: number;
@@ -36,8 +36,8 @@ export declare const OpportunityResourceDto: import("@sinclair/typebox").TObject
36
36
  type: import("@sinclair/typebox").TString;
37
37
  identifier: import("@sinclair/typebox").TString;
38
38
  name: import("@sinclair/typebox").TString;
39
- description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
40
- howToSteps: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
39
+ description: import("@sinclair/typebox").TString;
40
+ howToSteps: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
41
41
  status: import("@sinclair/typebox").TString;
42
42
  action: import("@sinclair/typebox").TString;
43
43
  tvl: import("@sinclair/typebox").TNumber;
@@ -165,7 +165,7 @@ export declare const OpportunityWithCampaignsResourceDto: import("@sinclair/type
165
165
  price: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TNumber, import("@sinclair/typebox").TNull]>>;
166
166
  symbol: import("@sinclair/typebox").TString;
167
167
  }>>;
168
- description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
168
+ description: import("@sinclair/typebox").TString;
169
169
  tags: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
170
170
  identifier: import("@sinclair/typebox").TString;
171
171
  chain: import("@sinclair/typebox").TObject<{
@@ -182,7 +182,7 @@ export declare const OpportunityWithCampaignsResourceDto: import("@sinclair/type
182
182
  FIX_REWARD_AMOUNT_PER_LIQUIDITY_AMOUNT: "FIX_REWARD_AMOUNT_PER_LIQUIDITY_AMOUNT";
183
183
  }>>;
184
184
  chainId: import("@sinclair/typebox").TNumber;
185
- howToSteps: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
185
+ howToSteps: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
186
186
  depositUrl: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
187
187
  explorerAddress: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
188
188
  tvl: import("@sinclair/typebox").TNumber;
@@ -358,6 +358,8 @@ export declare const CreateOpportunityDto: import("@sinclair/typebox").TObject<{
358
358
  SWAP: "SWAP";
359
359
  INVALID: "INVALID";
360
360
  }>;
361
+ description: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
362
+ howToSteps: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
361
363
  tokens: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
362
364
  address: import("@sinclair/typebox").TString;
363
365
  chainId: import("@sinclair/typebox").TNumber;
@@ -13,8 +13,8 @@ export const OpportunityResourceDto = t.Object({
13
13
  type: t.String(),
14
14
  identifier: t.String(),
15
15
  name: t.String(),
16
- description: t.Optional(t.String()),
17
- howToSteps: t.Optional(t.Array(t.String())),
16
+ description: t.String(),
17
+ howToSteps: t.Array(t.String()),
18
18
  status: t.String(),
19
19
  action: t.String(),
20
20
  tvl: t.Number(),
@@ -103,6 +103,8 @@ export const CreateOpportunityDto = t.Object({
103
103
  name: t.Optional(t.String()),
104
104
  status: t.Enum(Status),
105
105
  action: t.Enum(OpportunityAction),
106
+ description: t.Optional(t.String()),
107
+ howToSteps: t.Optional(t.Array(t.String())),
106
108
  tokens: t.Array(TokenDto),
107
109
  protocols: t.Optional(t.Array(t.String())),
108
110
  mainProtocol: t.Optional(t.String()),
@@ -204,6 +204,8 @@ export class OpportunityRepository {
204
204
  status: newOpp.status,
205
205
  type: newOpp.type,
206
206
  tags: newOpp.tags,
207
+ description: newOpp.description,
208
+ howToSteps: newOpp.howToSteps,
207
209
  depositUrl: !previousOpportunity?.manualOverrides.includes("depositUrl")
208
210
  ? newOpp.depositUrl
209
211
  : previousOpportunity.depositUrl,
@@ -231,6 +233,8 @@ export class OpportunityRepository {
231
233
  status: newOpp.status,
232
234
  type: newOpp.type,
233
235
  tags: newOpp.tags,
236
+ description: newOpp.description,
237
+ howToSteps: newOpp.howToSteps,
234
238
  depositUrl: !previousOpportunity?.manualOverrides.includes("depositUrl") ? newOpp.depositUrl : undefined,
235
239
  explorerAddress: !previousOpportunity?.manualOverrides.includes("explorerAddress")
236
240
  ? newOpp.explorerAddress
@@ -1,6 +1,8 @@
1
1
  import type { CampaignWithParams, GetCampaignQueryModel } from "@/modules/v4/campaign/campaign.model";
2
- import { type OpportunityManualOverride, type Prisma } from "@db/api";
2
+ import { type OpportunityAction, type OpportunityManualOverride, type Prisma } from "@db/api";
3
3
  import { type MerklChainId } from "@sdk";
4
+ import type { Protocol } from "../protocol/protocol.model";
5
+ import type { Token } from "../token/token.model";
4
6
  import type { CreateOpportunityModel, GetOpportunitiesQueryModel, LightOpportunityFromDB, Opportunity, OpportunityOverrideModel, OpportunityResourceModel, OpportunityUnique } from "./opportunity.model";
5
7
  import { OpportunityRepository } from "./opportunity.repository";
6
8
  export declare abstract class OpportunityService {
@@ -95,6 +97,8 @@ export declare abstract class OpportunityService {
95
97
  price?: number | null | undefined;
96
98
  })[];
97
99
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
100
+ description: string;
101
+ howToSteps: string[];
98
102
  depositUrl: string | undefined;
99
103
  explorerAddress: string | undefined;
100
104
  tags: string[];
@@ -223,6 +227,8 @@ export declare abstract class OpportunityService {
223
227
  price?: number | null | undefined;
224
228
  })[];
225
229
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
230
+ description: string;
231
+ howToSteps: string[];
226
232
  depositUrl: string | undefined;
227
233
  explorerAddress: string | undefined;
228
234
  tags: string[];
@@ -299,6 +305,8 @@ export declare abstract class OpportunityService {
299
305
  price?: number | null | undefined;
300
306
  })[];
301
307
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
308
+ description: string;
309
+ howToSteps: string[];
302
310
  depositUrl: string | undefined;
303
311
  explorerAddress: string | undefined;
304
312
  tags: string[];
@@ -318,9 +326,7 @@ export declare abstract class OpportunityService {
318
326
  tags: string[];
319
327
  icon: string;
320
328
  } | null | undefined;
321
- description?: string | undefined;
322
329
  distributionType?: "DUTCH_AUCTION" | "FIX_REWARD_VALUE_PER_LIQUIDITY_VALUE" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_VALUE" | "FIX_REWARD_VALUE_PER_LIQUIDITY_AMOUNT" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_AMOUNT" | undefined;
323
- howToSteps?: string[] | undefined;
324
330
  depositUrl?: string | undefined;
325
331
  explorerAddress?: string | undefined;
326
332
  aprRecord?: {
@@ -389,6 +395,7 @@ export declare abstract class OpportunityService {
389
395
  isPoint: boolean;
390
396
  isPreTGE: boolean;
391
397
  }[];
398
+ description: string;
392
399
  tags: string[];
393
400
  identifier: string;
394
401
  chain: {
@@ -398,6 +405,7 @@ export declare abstract class OpportunityService {
398
405
  };
399
406
  action: string;
400
407
  chainId: number;
408
+ howToSteps: string[];
401
409
  tvl: number;
402
410
  apr: number;
403
411
  dailyRewards: number;
@@ -466,9 +474,7 @@ export declare abstract class OpportunityService {
466
474
  tags: string[];
467
475
  icon: string;
468
476
  } | null | undefined;
469
- description?: string | undefined;
470
477
  distributionType?: "DUTCH_AUCTION" | "FIX_REWARD_VALUE_PER_LIQUIDITY_VALUE" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_VALUE" | "FIX_REWARD_VALUE_PER_LIQUIDITY_AMOUNT" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_AMOUNT" | undefined;
471
- howToSteps?: string[] | undefined;
472
478
  depositUrl?: string | undefined;
473
479
  explorerAddress?: string | undefined;
474
480
  aprRecord?: {
@@ -537,6 +543,7 @@ export declare abstract class OpportunityService {
537
543
  isPoint: boolean;
538
544
  isPreTGE: boolean;
539
545
  }[];
546
+ description: string;
540
547
  tags: string[];
541
548
  identifier: string;
542
549
  chain: {
@@ -546,6 +553,7 @@ export declare abstract class OpportunityService {
546
553
  };
547
554
  action: string;
548
555
  chainId: number;
556
+ howToSteps: string[];
549
557
  tvl: number;
550
558
  apr: number;
551
559
  dailyRewards: number;
@@ -1244,4 +1252,6 @@ export declare abstract class OpportunityService {
1244
1252
  lastCampaignCreatedAt: Date;
1245
1253
  }>;
1246
1254
  static updateMany(ids: string[], data: Partial<Opportunity["raw"]>): Promise<import("database/api/.generated/runtime/library").GetBatchResult>;
1255
+ static description(action: OpportunityAction, tokens: Token["model"][], protocol: Protocol["model"], chainId: number): Promise<string>;
1256
+ static howToSteps(action: OpportunityAction, tokens: Token["model"][], protocol: Protocol["model"]): string[];
1247
1257
  }
@@ -10,6 +10,7 @@ import { AprType, Status } from "@db/api";
10
10
  import { Campaign as CampaignType } from "@sdk";
11
11
  import moment from "moment";
12
12
  import { metadataBuilderFactory } from "../../../engine/metadata/factory";
13
+ import { ChainService } from "../chain/chain.service";
13
14
  import { ProtocolService } from "../protocol/protocol.service";
14
15
  import { OpportunityRepository } from "./opportunity.repository";
15
16
  export class OpportunityService {
@@ -79,6 +80,8 @@ export class OpportunityService {
79
80
  action: metadata.action,
80
81
  tokens,
81
82
  mainProtocol: metadata.mainProtocol,
83
+ description: await OpportunityService.description(metadata.action, tokens, protocol, campaign.computeChainId),
84
+ howToSteps: OpportunityService.howToSteps(metadata.action, tokens, protocol),
82
85
  // If creator has specified a deposit URL, use it
83
86
  // Else if we have the specific logic to handle the deposit URL, use it
84
87
  // Else if the protocol has a deposit URL, use it
@@ -271,4 +274,45 @@ export class OpportunityService {
271
274
  static async updateMany(ids, data) {
272
275
  return await OpportunityRepository.updateMany(ids, data);
273
276
  }
277
+ static async description(action, tokens, protocol, chainId) {
278
+ const chain = await ChainService.findUniqueOrThrow(chainId);
279
+ const symbols = tokens?.map(t => t.symbol).join("-");
280
+ if (action === "POOL")
281
+ return `Earn rewards by providing liquidity to the ${protocol?.name} ${symbols} pool on ${chain.name}, or through a liquidity manager supported by Merkl`;
282
+ if (action === "HOLD")
283
+ return `Earn rewards by holding ${symbols} or by staking it in a supported contract`;
284
+ if (action === "LEND")
285
+ return `Earn rewards by lending ${symbols} to ${protocol?.name} on ${chain.name}`;
286
+ if (action === "BORROW")
287
+ return `Earn rewards by taking a long position on ${protocol?.name} ${symbols} on ${chain.name}`;
288
+ if (action === "DROP")
289
+ return `Visit your dashboard to check if you've earned rewards from this airdrop`;
290
+ if (action === "LONG")
291
+ return `Borrow ${symbols} on ${protocol?.name} on ${chain.name}`;
292
+ if (action === "SHORT")
293
+ return `Earn rewards by taking a short position on ${protocol?.name} ${symbols} on ${chain.name}`;
294
+ if (action === "SWAP")
295
+ return `Earn rewards by trading ${symbols} on ${chain.name}`;
296
+ return "";
297
+ }
298
+ static howToSteps(action, tokens, protocol) {
299
+ const symbols = tokens?.map(t => t.symbol).join("-");
300
+ if (action === "POOL")
301
+ return [`Provide liquidity on ${protocol?.name}.`, "Earn rewards based on your liquidity position."];
302
+ if (action === "HOLD")
303
+ return [`Hold ${symbols}.`, "Rewards accumulate automatically."];
304
+ if (action === "LEND")
305
+ return [`Lend assets on ${protocol?.name}.`, "Rewards accumulate automatically."];
306
+ if (action === "BORROW")
307
+ return [`Borrow assets on ${protocol?.name}.`, "Rewards accumulate automatically."];
308
+ if (action === "DROP")
309
+ return ["Check your eligibility on Merkl."];
310
+ if (action === "LONG")
311
+ return [`Open a long position on ${protocol?.name}.`, "Rewards accumulate automatically."];
312
+ if (action === "SHORT")
313
+ return [`Open a short position on ${protocol?.name}.`, "Rewards accumulate automatically."];
314
+ if (action === "SWAP")
315
+ return [`Swap on ${protocol?.name}.`, "Rewards accumulate automatically."];
316
+ return [];
317
+ }
274
318
  }
@@ -32,7 +32,9 @@ export declare const v4: Elysia<"/v4", false, {
32
32
  post: {
33
33
  body: {
34
34
  name?: string | undefined;
35
+ description?: string | undefined;
35
36
  tags?: string[] | undefined;
37
+ howToSteps?: string[] | undefined;
36
38
  depositUrl?: string | undefined;
37
39
  explorerAddress?: string | undefined;
38
40
  protocols?: string[] | undefined;
@@ -229,6 +231,8 @@ export declare const v4: Elysia<"/v4", false, {
229
231
  price?: number | null | undefined;
230
232
  })[];
231
233
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
234
+ description: string;
235
+ howToSteps: string[];
232
236
  depositUrl: string | undefined;
233
237
  explorerAddress: string | undefined;
234
238
  tags: string[];
@@ -320,6 +324,8 @@ export declare const v4: Elysia<"/v4", false, {
320
324
  price?: number | null | undefined;
321
325
  })[];
322
326
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
327
+ description: string;
328
+ howToSteps: string[];
323
329
  depositUrl: string | undefined;
324
330
  explorerAddress: string | undefined;
325
331
  tags: string[];
@@ -605,9 +611,7 @@ export declare const v4: Elysia<"/v4", false, {
605
611
  tags: string[];
606
612
  icon: string;
607
613
  } | null | undefined;
608
- description?: string | undefined;
609
614
  distributionType?: "DUTCH_AUCTION" | "FIX_REWARD_VALUE_PER_LIQUIDITY_VALUE" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_VALUE" | "FIX_REWARD_VALUE_PER_LIQUIDITY_AMOUNT" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_AMOUNT" | undefined;
610
- howToSteps?: string[] | undefined;
611
615
  depositUrl?: string | undefined;
612
616
  explorerAddress?: string | undefined;
613
617
  aprRecord?: {
@@ -676,6 +680,7 @@ export declare const v4: Elysia<"/v4", false, {
676
680
  isPoint: boolean;
677
681
  isPreTGE: boolean;
678
682
  }[];
683
+ description: string;
679
684
  tags: string[];
680
685
  identifier: string;
681
686
  chain: {
@@ -685,6 +690,7 @@ export declare const v4: Elysia<"/v4", false, {
685
690
  };
686
691
  action: string;
687
692
  chainId: number;
693
+ howToSteps: string[];
688
694
  tvl: number;
689
695
  apr: number;
690
696
  dailyRewards: number;
@@ -744,9 +750,7 @@ export declare const v4: Elysia<"/v4", false, {
744
750
  tags: string[];
745
751
  icon: string;
746
752
  } | null | undefined;
747
- description?: string | undefined;
748
753
  distributionType?: "DUTCH_AUCTION" | "FIX_REWARD_VALUE_PER_LIQUIDITY_VALUE" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_VALUE" | "FIX_REWARD_VALUE_PER_LIQUIDITY_AMOUNT" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_AMOUNT" | undefined;
749
- howToSteps?: string[] | undefined;
750
754
  depositUrl?: string | undefined;
751
755
  explorerAddress?: string | undefined;
752
756
  aprRecord?: {
@@ -815,6 +819,7 @@ export declare const v4: Elysia<"/v4", false, {
815
819
  isPoint: boolean;
816
820
  isPreTGE: boolean;
817
821
  }[];
822
+ description: string;
818
823
  tags: string[];
819
824
  identifier: string;
820
825
  chain: {
@@ -824,6 +829,7 @@ export declare const v4: Elysia<"/v4", false, {
824
829
  };
825
830
  action: string;
826
831
  chainId: number;
832
+ howToSteps: string[];
827
833
  tvl: number;
828
834
  apr: number;
829
835
  dailyRewards: number;
@@ -920,9 +926,7 @@ export declare const v4: Elysia<"/v4", false, {
920
926
  tags: string[];
921
927
  icon: string;
922
928
  } | null | undefined;
923
- description?: string | undefined;
924
929
  distributionType?: "DUTCH_AUCTION" | "FIX_REWARD_VALUE_PER_LIQUIDITY_VALUE" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_VALUE" | "FIX_REWARD_VALUE_PER_LIQUIDITY_AMOUNT" | "FIX_REWARD_AMOUNT_PER_LIQUIDITY_AMOUNT" | undefined;
925
- howToSteps?: string[] | undefined;
926
930
  depositUrl?: string | undefined;
927
931
  explorerAddress?: string | undefined;
928
932
  aprRecord?: {
@@ -991,6 +995,7 @@ export declare const v4: Elysia<"/v4", false, {
991
995
  isPoint: boolean;
992
996
  isPreTGE: boolean;
993
997
  }[];
998
+ description: string;
994
999
  tags: string[];
995
1000
  identifier: string;
996
1001
  chain: {
@@ -1000,6 +1005,7 @@ export declare const v4: Elysia<"/v4", false, {
1000
1005
  };
1001
1006
  action: string;
1002
1007
  chainId: number;
1008
+ howToSteps: string[];
1003
1009
  tvl: number;
1004
1010
  apr: number;
1005
1011
  dailyRewards: number;
@@ -1317,6 +1323,8 @@ export declare const v4: Elysia<"/v4", false, {
1317
1323
  price?: number | null | undefined;
1318
1324
  })[];
1319
1325
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
1326
+ description: string;
1327
+ howToSteps: string[];
1320
1328
  depositUrl: string | undefined;
1321
1329
  explorerAddress: string | undefined;
1322
1330
  tags: string[];
@@ -2211,6 +2219,8 @@ export declare const v4: Elysia<"/v4", false, {
2211
2219
  price?: number | null | undefined;
2212
2220
  })[];
2213
2221
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
2222
+ description: string;
2223
+ howToSteps: string[];
2214
2224
  depositUrl: string | undefined;
2215
2225
  explorerAddress: string | undefined;
2216
2226
  tags: string[];
@@ -2319,6 +2329,8 @@ export declare const v4: Elysia<"/v4", false, {
2319
2329
  price?: number | null | undefined;
2320
2330
  })[];
2321
2331
  mainProtocol: "splice" | "reserve" | "morpho" | "quickswap" | "euler" | "aura" | "poolside" | "gearbox" | "filament" | "fluid" | "compound" | "ionic" | "layerbank" | "moonwell" | "fraxlend" | "fenix" | "ra" | "syncswap" | "beefy" | "aerodrome" | "velodrome" | "curve" | "toros" | "akron" | "enzyme" | "dragonswap" | "koi" | "rfx" | "woofi" | "pendle" | "zkSwapThreePool" | "maha" | "tempest" | "holdstation" | "venus" | "reactor_fusion" | "vicuna" | "curveNPool" | "satlayer" | "veda" | "cian" | "concrete" | "hourglass" | "katana" | "gamma" | "stability" | "uniswap" | "ambient" | "arthswap" | "base-swap" | "camelot" | "crust" | "horiza" | "izumi" | "kim" | "pancake-swap" | "ramses" | "retro" | "stryke" | "sushi-swap" | "swapr" | "thruster" | "voltage" | "zero" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "balancer" | "cross_curve" | "neptune" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "ironclad" | "sturdy" | "frax" | "silo" | "dolomite" | "badger" | "ajna" | "ion" | "eigenlayer" | "vest" | "zerolend" | "lnd" | "hyperdrive" | "oku" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "iguana" | "xlend" | "sake" | "sonicmarket" | "angles" | "bunni" | "beratrax" | "yei" | "gammaswap" | "uranium" | undefined;
2332
+ description: string;
2333
+ howToSteps: string[];
2322
2334
  depositUrl: string | undefined;
2323
2335
  explorerAddress: string | undefined;
2324
2336
  tags: string[];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,101 @@
1
+ import { OpportunityService } from "@/modules/v4/opportunity/opportunity.service";
2
+ import { apiDbClient } from "@db";
3
+ let page = 0;
4
+ while (true) {
5
+ const opportunities = await apiDbClient.opportunity.findMany({
6
+ select: {
7
+ id: true,
8
+ name: true,
9
+ explorerAddress: true,
10
+ depositUrl: true,
11
+ identifier: true,
12
+ MainProtocol: {
13
+ select: {
14
+ url: true,
15
+ name: true,
16
+ },
17
+ },
18
+ Chain: {
19
+ select: {
20
+ name: true,
21
+ },
22
+ },
23
+ type: true,
24
+ action: true,
25
+ Tokens: {
26
+ select: {
27
+ symbol: true,
28
+ address: true,
29
+ name: true,
30
+ },
31
+ },
32
+ Campaigns: {
33
+ take: 1,
34
+ include: {
35
+ RewardToken: {
36
+ select: {
37
+ address: true,
38
+ },
39
+ },
40
+ },
41
+ },
42
+ description: true,
43
+ },
44
+ take: 1000,
45
+ skip: page * 1000,
46
+ });
47
+ page += 1;
48
+ if (opportunities.length === 0) {
49
+ break;
50
+ }
51
+ for (const opportunity of opportunities) {
52
+ const { action, Tokens: tokens, MainProtocol: protocol, Chain: chain } = opportunity;
53
+ const symbols = tokens?.map(t => t.symbol).join("-");
54
+ let description = "";
55
+ switch (action) {
56
+ case "POOL":
57
+ description = `Earn rewards by providing liquidity to the ${protocol?.name} ${symbols} pool on ${chain.name}, or through a liquidity manager supported by Merkl`;
58
+ break;
59
+ case "HOLD":
60
+ description = `Earn rewards by holding ${symbols} or by staking it in a supported contract`;
61
+ break;
62
+ case "LEND":
63
+ description = `Earn rewards by lending ${symbols} to ${protocol?.name} on ${chain.name}`;
64
+ break;
65
+ case "BORROW":
66
+ description = `Earn rewards by taking a long position on ${protocol?.name} ${symbols} on ${chain.name}`;
67
+ break;
68
+ case "DROP":
69
+ description = `Visit your dashboard to check if you've earned rewards from this airdrop`;
70
+ break;
71
+ case "LONG":
72
+ description = `Borrow ${symbols} on ${protocol?.name} on ${chain.name}`;
73
+ break;
74
+ case "SHORT":
75
+ description = `Earn rewards by taking a short position on ${protocol?.name} ${symbols} on ${chain.name}`;
76
+ break;
77
+ case "SWAP":
78
+ description = `Earn rewards by trading ${symbols} on ${chain.name}`;
79
+ break;
80
+ default:
81
+ break;
82
+ }
83
+ const howToSteps = OpportunityService.howToSteps(action, tokens, protocol);
84
+ if (description !== opportunity.description) {
85
+ await apiDbClient.opportunity.update({
86
+ where: {
87
+ id: opportunity.id,
88
+ },
89
+ data: {
90
+ description,
91
+ howToSteps,
92
+ },
93
+ });
94
+ console.log(`updated description for ${opportunity.id} - ${opportunity.name} to ${description}`);
95
+ }
96
+ else {
97
+ console.log(`no description for ${opportunity.id} - ${opportunity.name}`);
98
+ }
99
+ }
100
+ }
101
+ process.exit(0);