@merkl/api 0.19.32 → 0.19.34
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.
- package/dist/database/api/.generated/edge.js +2 -2
- package/dist/database/api/.generated/index.js +2 -2
- package/dist/database/api/.generated/package.json +1 -1
- package/dist/database/api/.generated/schema.prisma +1 -1
- package/dist/src/eden/index.d.ts +30 -15
- package/dist/src/engine/opportunityMetadata/implementations/Erc20.js +3 -5
- package/dist/src/index.d.ts +6 -3
- package/dist/src/libs/deprecated-merklv3/index.js +0 -1
- package/dist/src/modules/v4/campaign/campaign.controller.d.ts +6 -3
- package/dist/src/modules/v4/campaign/campaign.controller.js +24 -58
- package/dist/src/modules/v4/campaign/campaign.repository.d.ts +1 -1
- package/dist/src/modules/v4/campaign/campaign.repository.js +1 -1
- package/dist/src/modules/v4/campaign/campaign.service.d.ts +14 -0
- package/dist/src/modules/v4/campaign/campaign.service.js +34 -22
- package/dist/src/modules/v4/opportunity/opportunity.repository.js +3 -1
- package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +6 -28
- package/dist/src/modules/v4/opportunity/opportunity.service.js +8 -45
- package/dist/src/modules/v4/protocol/protocol.service.js +0 -21
- package/dist/src/modules/v4/router.d.ts +6 -3
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
@@ -36,7 +36,8 @@ export class CampaignService {
|
|
36
36
|
try {
|
37
37
|
await OpportunityService.createFromCampaign(campaign);
|
38
38
|
}
|
39
|
-
catch {
|
39
|
+
catch (e) {
|
40
|
+
console.error(e);
|
40
41
|
throw new CannotParseOpportunity(campaign.campaignId, campaign.chainId, campaign.type);
|
41
42
|
}
|
42
43
|
return await CampaignRepository.upsert({ id, ...campaign });
|
@@ -46,17 +47,22 @@ export class CampaignService {
|
|
46
47
|
* @dev deprecated should be replaced with a manual override
|
47
48
|
*/
|
48
49
|
static async updateMetaData(campaign) {
|
49
|
-
const
|
50
|
+
const campaignUnique = {
|
50
51
|
distributionChain: campaign.distributionChain,
|
51
52
|
campaignId: campaign.campaignId,
|
52
|
-
}
|
53
|
-
const
|
53
|
+
};
|
54
|
+
const id = CampaignService.hashId(campaignUnique);
|
55
|
+
let existingCampaign = await CampaignService.findUnique(campaign);
|
56
|
+
if (!existingCampaign) {
|
57
|
+
await CampaignService.fill([campaignUnique]);
|
58
|
+
existingCampaign = await CampaignService.findUniqueOrThrow(campaign);
|
59
|
+
}
|
54
60
|
const params = existingCampaign.params;
|
55
61
|
if ("url" in params) {
|
56
62
|
params.url = campaign.url;
|
57
63
|
}
|
58
64
|
const updatedParams = JSON.stringify(params);
|
59
|
-
return await CampaignRepository.
|
65
|
+
return await CampaignRepository.updateParams(id, updatedParams);
|
60
66
|
}
|
61
67
|
/**
|
62
68
|
* @dev back-office function for manual overrides
|
@@ -181,8 +187,8 @@ export class CampaignService {
|
|
181
187
|
}
|
182
188
|
static async findCampaignsToProcess(distributionChainId) {
|
183
189
|
return (await CampaignRepository.findCampaignsToProcess(distributionChainId))
|
184
|
-
.filter(campaign => campaign.endTimestamp > (campaign?.CampaignStatus?.[0]?.computedUntil ?? 0n))
|
185
|
-
?.sort((a, b) => Number((a.CampaignStatus?.[0]?.processingStarted ?? 0n) - (b.CampaignStatus?.[0]?.processingStarted ?? 0n)));
|
190
|
+
.filter(campaign => campaign.endTimestamp > (campaign?.CampaignStatus?.[0]?.computedUntil ?? 0n)) // Filter out campaigns that have already been processed
|
191
|
+
?.sort((a, b) => Number((a.CampaignStatus?.[0]?.processingStarted ?? 0n) - (b.CampaignStatus?.[0]?.processingStarted ?? 0n))); // Sort by processingStarted, that is to say campaigns that were processed the most long ago
|
186
192
|
}
|
187
193
|
static async findNextCampaignToProcess(chainId) {
|
188
194
|
const campaigns = await CampaignService.findCampaignsToProcess(chainId);
|
@@ -202,31 +208,37 @@ export class CampaignService {
|
|
202
208
|
}
|
203
209
|
throw new Error(`No campaign to process found on ${NETWORK_LABELS[chainId]}`);
|
204
210
|
}
|
205
|
-
static async
|
211
|
+
static async findEngineCampaigns(campaigns) {
|
206
212
|
const campaignsFromEngine = await CampaignRepository.getFromEngineDbWithId(campaigns);
|
207
213
|
for (const campaign of campaigns) {
|
208
214
|
if (campaignsFromEngine.findIndex(c => c.campaignId === campaign.campaignId) === -1) {
|
209
215
|
log.warn(`Campaign ${campaign.campaignId} on ${NETWORK_LABELS[campaign.distributionChain]} not found in engine db`);
|
210
216
|
}
|
211
217
|
}
|
218
|
+
return campaignsFromEngine.map(campaign => {
|
219
|
+
return {
|
220
|
+
amount: campaign.amount,
|
221
|
+
chainId: campaign.chainId,
|
222
|
+
computeChainId: campaign.computeChainId,
|
223
|
+
creator: campaign.creator,
|
224
|
+
endTimestamp: campaign.endTimestamp.toString(),
|
225
|
+
campaignId: campaign.campaignId,
|
226
|
+
opportunityIdentifier: campaign.mainParameter,
|
227
|
+
params: JSON.stringify(campaign.campaignParameters),
|
228
|
+
rewardTokenAddress: campaign.rewardToken,
|
229
|
+
startTimestamp: campaign.startTimestamp.toString(),
|
230
|
+
type: campaign.campaignType,
|
231
|
+
subType: campaign.campaignSubType,
|
232
|
+
};
|
233
|
+
});
|
234
|
+
}
|
235
|
+
static async fill(campaigns) {
|
236
|
+
const campaignsFromEngine = await CampaignService.findEngineCampaigns(campaigns);
|
212
237
|
let success = 0;
|
213
238
|
let fail = 0;
|
214
239
|
for (const engineCampaign of campaignsFromEngine) {
|
215
240
|
try {
|
216
|
-
await CampaignService.create(
|
217
|
-
amount: engineCampaign.amount,
|
218
|
-
chainId: engineCampaign.chainId,
|
219
|
-
computeChainId: engineCampaign.computeChainId,
|
220
|
-
creator: engineCampaign.creator,
|
221
|
-
endTimestamp: engineCampaign.endTimestamp.toString(),
|
222
|
-
campaignId: engineCampaign.campaignId,
|
223
|
-
opportunityIdentifier: engineCampaign.mainParameter,
|
224
|
-
params: JSON.stringify(engineCampaign.campaignParameters),
|
225
|
-
rewardTokenAddress: engineCampaign.rewardToken,
|
226
|
-
startTimestamp: engineCampaign.startTimestamp.toString(),
|
227
|
-
type: engineCampaign.campaignType,
|
228
|
-
subType: engineCampaign.campaignSubType,
|
229
|
-
});
|
241
|
+
await CampaignService.create(engineCampaign);
|
230
242
|
success++;
|
231
243
|
}
|
232
244
|
catch {
|
@@ -209,7 +209,9 @@ export class OpportunityRepository {
|
|
209
209
|
Chain: { connect: { id: newOpp.chainId } },
|
210
210
|
MainProtocol: !!newOpp.mainProtocol
|
211
211
|
? { connect: { id: newOpp.mainProtocol } }
|
212
|
-
:
|
212
|
+
: !!previousOpportunity?.mainProtocolId
|
213
|
+
? { disconnect: { id: previousOpportunity?.mainProtocolId } }
|
214
|
+
: undefined,
|
213
215
|
Protocols: {
|
214
216
|
connect: (newOpp.protocols ?? []).map((protocol) => {
|
215
217
|
return { id: protocol };
|
@@ -26,34 +26,12 @@ export declare abstract class OpportunityService {
|
|
26
26
|
apr: number;
|
27
27
|
dailyRewards: number;
|
28
28
|
} | null>;
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
status: "PAST" | "LIVE" | "SOON";
|
36
|
-
action: OpportunityAction;
|
37
|
-
tokens: ({
|
38
|
-
symbol: string;
|
39
|
-
id: string;
|
40
|
-
name: string | null;
|
41
|
-
icon: string;
|
42
|
-
address: string;
|
43
|
-
chainId: number;
|
44
|
-
decimals: number;
|
45
|
-
verified: boolean;
|
46
|
-
isTest: boolean;
|
47
|
-
isPoint: boolean;
|
48
|
-
isNative: boolean;
|
49
|
-
} & {
|
50
|
-
price?: number | null | undefined;
|
51
|
-
})[][];
|
52
|
-
mainProtocol: "splice" | "morpho" | "euler" | "ambient" | "uniswap" | "arthswap" | "base-swap" | "camelot" | "crust" | "fenix" | "horiza" | "izumi" | "kim" | "pancake-swap" | "quick-swap" | "ramses" | "retro" | "stryke" | "sushiswap" | "swapr" | "thruster" | "voltage" | "zero" | "koi" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "velodrome" | "aerodrome" | "balancer" | "curve" | "cross_curve" | "curveNPool" | "aura" | "akron" | "beefy" | "dragonswap" | "poolside" | "syncswap" | "neptune" | "zkSwapThreePool" | "rfx" | "ra" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "fraxlend" | "ironclad" | "gearbox" | "compound" | "sturdy" | "frax" | "ionic" | "moonwell" | "fluid" | "silo" | "dolomite" | "badger" | "ajna" | "layerbank" | "ion" | "venus" | "woofi" | "reactor_fusion" | "eigenlayer" | "vest" | "zerolend" | "hyperdrive" | "gamma" | "oku" | "hourglass" | "veda" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "angles" | "enzyme" | "toros" | "vicuna" | "bunni" | "beratrax" | "concrete" | "cian" | "pendle" | "yei" | "filament" | "gammaswap" | "maha" | "tempest" | "uranium" | "holdstation" | "katana" | "satlayer" | undefined;
|
53
|
-
depositUrl: any;
|
54
|
-
tags: string[];
|
55
|
-
}>;
|
56
|
-
static createFromCampaign(campaign: Omit<CreateCampaignModel, "id">, upsert?: boolean): Promise<{
|
29
|
+
/**
|
30
|
+
* @param upsert whether to update the opportunity if it already exists in database
|
31
|
+
* @param dryRun whether to skip the opportunity table interaction and just return the computed opportunity
|
32
|
+
* @returns the opportunity entity computed
|
33
|
+
*/
|
34
|
+
static createFromCampaign(campaign: Omit<CreateCampaignModel, "id">, upsert?: boolean, dryRun?: boolean): Promise<{
|
57
35
|
id: string;
|
58
36
|
chainId: number;
|
59
37
|
type: string;
|
@@ -36,50 +36,12 @@ export class OpportunityService {
|
|
36
36
|
const distributionChainId = campaign.chainId;
|
37
37
|
return await metadataBuilderFactory(campaignType).build(computeChainId, campaignParams, campaign.subType, campaign.rewardTokenAddress, distributionChainId, campaign.campaignId, campaign.creator);
|
38
38
|
}
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
identifier: campaign.opportunityIdentifier,
|
46
|
-
type: campaignType,
|
47
|
-
});
|
48
|
-
const protocol = (await ProtocolService.findMany({ id: metadata.mainProtocol }))?.[0];
|
49
|
-
const tokens = await Promise.all(metadata.tokens.map(async (t) => {
|
50
|
-
return await TokenService.findMany(t);
|
51
|
-
}));
|
52
|
-
const params = JSON.parse(campaign.params);
|
53
|
-
const now = moment().unix();
|
54
|
-
const opportunity = {
|
55
|
-
id: opportunityId,
|
56
|
-
chainId: campaign.computeChainId,
|
57
|
-
type: campaignType,
|
58
|
-
identifier: campaign.opportunityIdentifier, // mainParameter
|
59
|
-
name: metadata.name,
|
60
|
-
status: now >= +campaign.startTimestamp && now < +campaign.endTimestamp
|
61
|
-
? Status.LIVE
|
62
|
-
: now > +campaign.endTimestamp
|
63
|
-
? Status.PAST
|
64
|
-
: Status.SOON,
|
65
|
-
action: metadata.action,
|
66
|
-
tokens,
|
67
|
-
mainProtocol: metadata.mainProtocol,
|
68
|
-
// If creator has specified a deposit URL, use it
|
69
|
-
// Else if we have the specific logic to handle the deposit URL, use it
|
70
|
-
// Else if the protocol has a deposit URL, use it
|
71
|
-
depositUrl: !!params.url
|
72
|
-
? params.url
|
73
|
-
: !!metadata.depositUrl
|
74
|
-
? metadata.depositUrl
|
75
|
-
: !!metadata.mainProtocol && !!protocol.url
|
76
|
-
? protocol.url
|
77
|
-
: undefined,
|
78
|
-
tags,
|
79
|
-
};
|
80
|
-
return opportunity;
|
81
|
-
}
|
82
|
-
static async createFromCampaign(campaign, upsert = false) {
|
39
|
+
/**
|
40
|
+
* @param upsert whether to update the opportunity if it already exists in database
|
41
|
+
* @param dryRun whether to skip the opportunity table interaction and just return the computed opportunity
|
42
|
+
* @returns the opportunity entity computed
|
43
|
+
*/
|
44
|
+
static async createFromCampaign(campaign, upsert = false, dryRun = false) {
|
83
45
|
const campaignType = CampaignService.getTypeFromV3(campaign.type);
|
84
46
|
const metadata = await OpportunityService.#getMetadata(campaign);
|
85
47
|
const tags = [...((await UserService.findUnique(campaign.creator))?.tags ?? []), ...(campaign?.tags ?? [])];
|
@@ -118,7 +80,8 @@ export class OpportunityService {
|
|
118
80
|
: undefined,
|
119
81
|
tags,
|
120
82
|
};
|
121
|
-
|
83
|
+
if (!dryRun)
|
84
|
+
await OpportunityRepository.create(opportunity, upsert);
|
122
85
|
return opportunity;
|
123
86
|
}
|
124
87
|
static async updateStatus(opportunityId, status) {
|
@@ -5,27 +5,6 @@ import { ProtocolRepository } from "./protocol.repository";
|
|
5
5
|
// ─── Protocols Services ──────────────────────────────────────────────────────
|
6
6
|
export class ProtocolService {
|
7
7
|
static async findMany(query) {
|
8
|
-
if (process.env.CLEAN_PROTOCOLS === "true") {
|
9
|
-
await ProtocolRepository.changeId("uniswap-v3", "uniswap");
|
10
|
-
await ProtocolRepository.changeId("balancerpool", "balancer");
|
11
|
-
await ProtocolRepository.changeId("syncswap-v3", "syncswap");
|
12
|
-
await ProtocolRepository.changeId("akronv2", "akron");
|
13
|
-
await ProtocolRepository.changeId("aerodromev2", "aerodrome");
|
14
|
-
await ProtocolRepository.changeId("velodromev2", "velodrome");
|
15
|
-
await ProtocolRepository.changeId("fenixv2", "fenix");
|
16
|
-
await ProtocolRepository.changeId("supswap-v3", "supswap");
|
17
|
-
await ProtocolRepository.changeId("stryke-sushi", "stryke");
|
18
|
-
await ProtocolRepository.changeId("stryke-pcs", "stryke");
|
19
|
-
await ProtocolRepository.changeId("quickswap-algebra-v1_2", "quickswap");
|
20
|
-
await ProtocolRepository.changeId("quickswap-uni", "quickswap");
|
21
|
-
await ProtocolRepository.changeId("quickswap-algebra", "quickswap");
|
22
|
-
await ProtocolRepository.changeId("quickswap-2", "quickswap");
|
23
|
-
await ProtocolRepository.changeId("pancake-swap-v3", "pancakeswap");
|
24
|
-
await ProtocolRepository.changeId("baseswapv2", "base-swap");
|
25
|
-
await ProtocolRepository.changeId("baseswap", "base-swap");
|
26
|
-
await ProtocolRepository.changeId("sushi-swap-v3", "sushi-swap");
|
27
|
-
await ProtocolRepository.changeId("sushiswap", "sushi-swap");
|
28
|
-
}
|
29
8
|
const protocols = await ProtocolRepository.findMany(query);
|
30
9
|
const enrichedProtocols = protocols.map(({ MainOpportunities, ...protocol }) => ({
|
31
10
|
...protocol,
|
@@ -1144,13 +1144,16 @@ export declare const v4: Elysia<"/v4", false, {
|
|
1144
1144
|
} & {
|
1145
1145
|
"dry-run": {
|
1146
1146
|
":campaignId": {
|
1147
|
-
|
1147
|
+
metadata: {
|
1148
1148
|
get: {
|
1149
1149
|
body: unknown;
|
1150
1150
|
params: {
|
1151
1151
|
campaignId: string;
|
1152
1152
|
};
|
1153
|
-
query:
|
1153
|
+
query: {
|
1154
|
+
campaignId: string;
|
1155
|
+
distributionChain: number;
|
1156
|
+
};
|
1154
1157
|
headers: {
|
1155
1158
|
authorization: string;
|
1156
1159
|
};
|
@@ -1177,7 +1180,7 @@ export declare const v4: Elysia<"/v4", false, {
|
|
1177
1180
|
isNative: boolean;
|
1178
1181
|
} & {
|
1179
1182
|
price?: number | null | undefined;
|
1180
|
-
})[]
|
1183
|
+
})[];
|
1181
1184
|
mainProtocol: "splice" | "morpho" | "euler" | "ambient" | "uniswap" | "arthswap" | "base-swap" | "camelot" | "crust" | "fenix" | "horiza" | "izumi" | "kim" | "pancake-swap" | "quick-swap" | "ramses" | "retro" | "stryke" | "sushiswap" | "swapr" | "thruster" | "voltage" | "zero" | "koi" | "supswap" | "zk-swap" | "thirdtrade" | "swap-x" | "velodrome" | "aerodrome" | "balancer" | "curve" | "cross_curve" | "curveNPool" | "aura" | "akron" | "beefy" | "dragonswap" | "poolside" | "syncswap" | "neptune" | "zkSwapThreePool" | "rfx" | "ra" | "maverick" | "trader-joe" | "hanji" | "radiant" | "aave" | "fraxlend" | "ironclad" | "gearbox" | "compound" | "sturdy" | "frax" | "ionic" | "moonwell" | "fluid" | "silo" | "dolomite" | "badger" | "ajna" | "layerbank" | "ion" | "venus" | "woofi" | "reactor_fusion" | "eigenlayer" | "vest" | "zerolend" | "hyperdrive" | "gamma" | "oku" | "hourglass" | "veda" | "kyo" | "sonex" | "lendle" | "tako-tako" | "equalizer" | "spectra" | "beraborrow" | "superlend" | "avalon" | "angles" | "enzyme" | "toros" | "vicuna" | "bunni" | "beratrax" | "concrete" | "cian" | "pendle" | "yei" | "filament" | "gammaswap" | "maha" | "tempest" | "uranium" | "holdstation" | "katana" | "satlayer" | undefined;
|
1182
1185
|
depositUrl: any;
|
1183
1186
|
tags: string[];
|