@merkl/api 0.17.6 → 0.17.8
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/src/backgroundJobs/jobs/opportunityUpdater.js +2 -0
- package/dist/src/jobs/etl/update-dynamic-data.js +103 -101
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/hardcoded.js +3 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.d.ts +2 -1
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/tokenType.js +2 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/processorMapping.js +2 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/xU308Processor.d.ts +37 -0
- package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/xU308Processor.js +49 -0
- package/dist/src/libs/positions/clamm/index.js +1 -1
- package/dist/src/modules/v4/campaign/campaign.controller.js +1 -1
- package/dist/src/modules/v4/campaign/campaign.repository.d.ts +67 -2
- package/dist/src/modules/v4/campaign/campaign.repository.js +46 -6
- package/dist/src/modules/v4/campaign/campaign.service.d.ts +55 -2
- package/dist/src/modules/v4/campaign/campaign.service.js +5 -2
- package/dist/src/modules/v4/claims/claims.controller.js +1 -1
- package/dist/src/modules/v4/interaction/interaction.service.d.ts +1 -1
- package/dist/src/modules/v4/interaction/interaction.service.js +3 -3
- package/dist/src/modules/v4/merklRoot/merklRoot.service.js +1 -1
- package/dist/src/modules/v4/opportunity/subservices/getEulerMetadata.service.js +4 -1
- package/dist/src/modules/v4/protocol/protocol.service.js +1 -1
- package/dist/src/modules/v4/reward/reward.service.js +1 -1
- package/dist/src/modules/v4/user/user.model.js +1 -1
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/dist/src/modules/v4/chain/index.d.ts +0 -4
- package/dist/src/modules/v4/chain/index.js +0 -8
- package/dist/src/modules/v4/chainInteraction/index.d.ts +0 -1
- package/dist/src/modules/v4/chainInteraction/index.js +0 -1
@@ -53,8 +53,10 @@ export const opportunityUpdater = (app) => {
|
|
53
53
|
await Redis.safeSet("Opportunities", opportunities);
|
54
54
|
await Redis.safeSet("OpportunitiesWithTest", opportunitiesWithTest);
|
55
55
|
log.info("✅ opportunity cache updated successfully");
|
56
|
+
await OpportunityConvertorService.logKeyAndTTLV3Opportunities(true, false, undefined, undefined);
|
56
57
|
await OpportunityConvertorService.setV3Opportunities(true, false, undefined, undefined);
|
57
58
|
log.info("✅ opportunity v3 cache updated successfully");
|
59
|
+
await OpportunityConvertorService.logKeyAndTTLV3Opportunities(true, true, undefined, undefined);
|
58
60
|
await OpportunityConvertorService.setV3Opportunities(true, true, undefined, undefined);
|
59
61
|
log.info("✅ opportunity v3 test cache updated successfully");
|
60
62
|
return new Response(JSON.stringify({
|
@@ -6,7 +6,8 @@ import { OpportunityRepository } from "../../modules/v4/opportunity/opportunity.
|
|
6
6
|
import { RewardService } from "../../modules/v4/reward";
|
7
7
|
import { TvlService } from "../../modules/v4/tvl";
|
8
8
|
import { executeSimple } from "../../utils/execute";
|
9
|
-
import {
|
9
|
+
import { log } from "../../utils/logger";
|
10
|
+
import { Campaign as CampaignEnum } from "@sdk";
|
10
11
|
import moment from "moment";
|
11
12
|
// ─── Required Env Variables ──────────────────────────────────────────────────
|
12
13
|
const chainId = Number(process.env.CHAIN_ID);
|
@@ -14,74 +15,52 @@ if (!chainId)
|
|
14
15
|
throw new Error("Environment variable CHAIN_ID is required.");
|
15
16
|
// ─── Update Dynamic Data (APR / TVL / Daily Rewards) ─────────────────────────
|
16
17
|
async function updateDynamicData(liveCampaigns, campaignType) {
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
oppMap[`${data.campaignType}_${data.mainParameter}`][data.campaignId] = data;
|
40
|
-
}
|
41
|
-
}
|
42
|
-
for (const entry of Object.entries(oppMap)) {
|
43
|
-
const [type, mainParameter] = entry[0].split("_");
|
44
|
-
try {
|
45
|
-
const apr = AprService.extractFromDynamicData(+type, Object.values(entry[1]));
|
46
|
-
const tvl = TvlService.extractFromDynamicData(+type, Object.values(entry[1]));
|
47
|
-
const dailyRewards = await RewardService.extractDailyRewardsRecordFromDynamicData(+type, Object.values(entry[1]));
|
48
|
-
const opportunityId = OpportunityService.hashId({
|
49
|
-
chainId,
|
50
|
-
identifier: mainParameter,
|
51
|
-
type: type,
|
52
|
-
});
|
53
|
-
await OpportunityRepository.updateRecords(opportunityId, apr, tvl, dailyRewards);
|
54
|
-
}
|
55
|
-
catch (err) {
|
56
|
-
console.log(mainParameter);
|
57
|
-
console.error(err);
|
58
|
-
}
|
18
|
+
// Input: list of campaigns of same type
|
19
|
+
// Output: for each campaign, APR, TVL, Daily Rewards
|
20
|
+
// Constraint: needs to use multicalls to reduce RPC calls and speed
|
21
|
+
// - Needs to be robust to a single campaign's call failing
|
22
|
+
// - Needs to be quite easy for the engine team to setup new campaign types
|
23
|
+
// abstract GenericDynamicDataComputer
|
24
|
+
// compute(chainId, type, campaigns) => { apr, tvl, dailyRewards } with breakdowns
|
25
|
+
// UNISWAP V4
|
26
|
+
// Round 1 - (chainId, type, campaigns) -> tokens of the pools
|
27
|
+
// Round 2 - (chainId, type, campaigns, output of previous round) -> balance in tokens of forwarders
|
28
|
+
// Round 3 - ...
|
29
|
+
// Round Final - (chainId, type, campaigns, output of previous round) -> { apr, tvl, dailyRewards }
|
30
|
+
const dynamicData = await executeSimple(chainId, campaignsDynamicData(chainId, liveCampaigns, campaignType));
|
31
|
+
const oppMap = {};
|
32
|
+
for (const data of dynamicData) {
|
33
|
+
if (!!data) {
|
34
|
+
// Main Parameter OVERRIDING
|
35
|
+
if (data.campaignType === CampaignEnum.SILO && data.campaignParameters.whitelist?.length === 1)
|
36
|
+
data.mainParameter = `${data.mainParameter}-${data.campaignParameters.whitelist[0]}`;
|
37
|
+
if (!oppMap[`${data.campaignType}_${data.mainParameter}`])
|
38
|
+
oppMap[`${data.campaignType}_${data.mainParameter}`] = {};
|
39
|
+
oppMap[`${data.campaignType}_${data.mainParameter}`][data.campaignId] = data;
|
59
40
|
}
|
60
41
|
}
|
61
|
-
|
62
|
-
|
42
|
+
for (const entry of Object.entries(oppMap)) {
|
43
|
+
const [type, mainParameter] = entry[0].split("_");
|
44
|
+
try {
|
45
|
+
const apr = AprService.extractFromDynamicData(+type, Object.values(entry[1]));
|
46
|
+
const tvl = TvlService.extractFromDynamicData(+type, Object.values(entry[1]));
|
47
|
+
const dailyRewards = await RewardService.extractDailyRewardsRecordFromDynamicData(+type, Object.values(entry[1]));
|
48
|
+
const opportunityId = OpportunityService.hashId({
|
49
|
+
chainId,
|
50
|
+
identifier: mainParameter,
|
51
|
+
type: type,
|
52
|
+
});
|
53
|
+
await OpportunityRepository.updateRecords(opportunityId, apr, tvl, dailyRewards);
|
54
|
+
}
|
55
|
+
catch (err) {
|
56
|
+
console.error(err);
|
57
|
+
}
|
63
58
|
}
|
64
59
|
}
|
65
60
|
// ─── Get And Transform Live Campaigns Into A Map ─────────────────────────────
|
66
|
-
const
|
67
|
-
const liveCampaigns = (await CampaignService.getLiveCampaigns({ computeChainId: chainId })).map(c => {
|
68
|
-
return {
|
69
|
-
amount: c.amount,
|
70
|
-
campaignId: c.campaignId,
|
71
|
-
mainParameter: c.Opportunity.identifier,
|
72
|
-
campaignParameters: c.params,
|
73
|
-
campaignSubType: c.subType,
|
74
|
-
campaignType: c.type,
|
75
|
-
chainId: c.distributionChainId,
|
76
|
-
computeChainId: c.computeChainId,
|
77
|
-
creator: c.creatorAddress,
|
78
|
-
endTimestamp: c.endTimestamp,
|
79
|
-
rewardToken: c.rewardTokenId,
|
80
|
-
startTimestamp: c.startTimestamp,
|
81
|
-
};
|
82
|
-
});
|
61
|
+
const buildMapByType = async (campaignsToUpdate) => {
|
83
62
|
const campaignTypeToCampaigns = new Map();
|
84
|
-
for (const campaign of
|
63
|
+
for (const campaign of campaignsToUpdate) {
|
85
64
|
const type = campaign.campaignType;
|
86
65
|
let campaigns = campaignTypeToCampaigns.get(campaign.campaignType);
|
87
66
|
if (!campaigns)
|
@@ -93,46 +72,69 @@ const getLiveCampaignsByType = async (chainId) => {
|
|
93
72
|
return campaignTypeToCampaigns;
|
94
73
|
};
|
95
74
|
// ─── Main function / entry point ─────────────────────────────────────────────
|
96
|
-
const
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
// 3.1 Get current live opportunities
|
105
|
-
const liveOpportunities = await OpportunityService.findLiveWithCampaigns(chainId);
|
106
|
-
// 3.2 For each currently live opportunities, infer its updated status by looping through its campaigns
|
107
|
-
const now = moment().unix();
|
108
|
-
for (const opportunity of liveOpportunities) {
|
109
|
-
let status = "NONE";
|
110
|
-
const campaigns = opportunity.campaigns;
|
111
|
-
for (const campaign of campaigns) {
|
112
|
-
if (status !== "LIVE" && campaign.endTimestamp < now)
|
113
|
-
status = "PAST";
|
114
|
-
else if (campaign.startTimestamp < now && campaign.endTimestamp > now)
|
115
|
-
status = "LIVE";
|
116
|
-
else if (status !== "LIVE" && campaign.startTimestamp > now)
|
117
|
-
status = "SOON";
|
118
|
-
}
|
119
|
-
await OpportunityService.updateStatus(opportunity.id, status);
|
75
|
+
const updateCampaigns = async (campaignsToUpdate) => {
|
76
|
+
// 1. Get a map of campaigns by campaign type
|
77
|
+
const campaignTypeToCampaigns = await buildMapByType(campaignsToUpdate);
|
78
|
+
// 2. Call updateDynamicData with each entries of the map (process by campaign type)
|
79
|
+
for (const [campaignType, campaigns] of campaignTypeToCampaigns.entries()) {
|
80
|
+
log.info(`updating dynamic data for ${campaigns.length} campaigns of type ${CampaignEnum[campaignType]}`);
|
81
|
+
try {
|
82
|
+
await updateDynamicData(campaigns, campaignType);
|
120
83
|
}
|
121
|
-
|
122
|
-
|
123
|
-
for (const [type, campaigns] of liveCampaigns.entries()) {
|
124
|
-
for (const campaign of campaigns) {
|
125
|
-
const opportunityId = OpportunityService.hashId({ chainId, identifier: campaign.mainParameter, type });
|
126
|
-
opportunities.add(opportunityId);
|
127
|
-
}
|
84
|
+
catch (err) {
|
85
|
+
console.error(`Failed to update dynamic data for campaign type ${CampaignEnum[campaignType]}`, err);
|
128
86
|
}
|
129
|
-
// 5. Update the status of the liveCampaigns opportunities
|
130
|
-
await OpportunityService.updateMany(Array.from(opportunities), { status: "LIVE" });
|
131
|
-
process.exit(0);
|
132
87
|
}
|
133
|
-
|
134
|
-
|
135
|
-
|
88
|
+
};
|
89
|
+
const main = async () => {
|
90
|
+
const liveCampaigns = (await CampaignService.getLiveCampaigns({ computeChainId: chainId })).map(c => {
|
91
|
+
return {
|
92
|
+
amount: c.amount,
|
93
|
+
campaignId: c.campaignId,
|
94
|
+
mainParameter: c.Opportunity.identifier,
|
95
|
+
campaignParameters: c.params,
|
96
|
+
campaignSubType: c.subType,
|
97
|
+
campaignType: CampaignEnum[c.type],
|
98
|
+
chainId: c.distributionChainId,
|
99
|
+
computeChainId: c.computeChainId,
|
100
|
+
creator: c.creatorAddress,
|
101
|
+
endTimestamp: Number(c.endTimestamp),
|
102
|
+
rewardToken: c.rewardTokenId,
|
103
|
+
startTimestamp: Number(c.startTimestamp),
|
104
|
+
index: 0,
|
105
|
+
};
|
106
|
+
});
|
107
|
+
await updateCampaigns(liveCampaigns);
|
108
|
+
// Update status of opportunities
|
109
|
+
// 1. Get current live opportunities
|
110
|
+
const liveOpportunities = await OpportunityService.findLiveWithCampaigns(chainId);
|
111
|
+
// 2. For each currently live opportunities, infer its updated status by looping through its campaigns
|
112
|
+
const now = moment().unix();
|
113
|
+
for (const opportunity of liveOpportunities) {
|
114
|
+
let status = "NONE";
|
115
|
+
const campaigns = opportunity.campaigns;
|
116
|
+
for (const campaign of campaigns) {
|
117
|
+
if (status !== "LIVE" && campaign.endTimestamp < now)
|
118
|
+
status = "PAST";
|
119
|
+
else if (campaign.startTimestamp < now && campaign.endTimestamp > now)
|
120
|
+
status = "LIVE";
|
121
|
+
else if (status !== "LIVE" && campaign.startTimestamp > now)
|
122
|
+
status = "SOON";
|
123
|
+
}
|
124
|
+
await OpportunityService.updateStatus(opportunity.id, status);
|
136
125
|
}
|
126
|
+
// 3. Update the status of the opportunities associated to future campaigns
|
127
|
+
const futureOpportunityIds = (await CampaignService.getFutureCampaigns({ computeChainId: chainId })).map(c => c.Opportunity.id);
|
128
|
+
await OpportunityService.updateMany(futureOpportunityIds, { status: "SOON" });
|
129
|
+
// 4. Update the status of the opportunities associated to live campaigns
|
130
|
+
const liveOpportunityIds = (await CampaignService.getLiveCampaigns({ computeChainId: chainId })).map(c => c.Opportunity.id);
|
131
|
+
await OpportunityService.updateMany(liveOpportunityIds, { status: "LIVE" });
|
137
132
|
};
|
138
|
-
|
133
|
+
try {
|
134
|
+
await main();
|
135
|
+
process.exit(0);
|
136
|
+
}
|
137
|
+
catch (err) {
|
138
|
+
console.error(err);
|
139
|
+
process.exit(1);
|
140
|
+
}
|
@@ -20,6 +20,9 @@ const chainAddressToType = {
|
|
20
20
|
[ChainId.BOB]: {
|
21
21
|
"0x9998e05030Aee3Af9AD3df35A34F5C51e1628779": tokenType.veda,
|
22
22
|
},
|
23
|
+
[ChainId.ETHERLINK]: {
|
24
|
+
"0x79052Ab3C166D4899a1e0DD033aC3b379AF0B1fD": tokenType.xU308,
|
25
|
+
},
|
23
26
|
};
|
24
27
|
export function getTypeFromAddressChain(chain, token) {
|
25
28
|
if (!!chainAddressToType[chain] && !!chainAddressToType[chain][token]) {
|
@@ -89,7 +89,8 @@ export declare enum tokenType {
|
|
89
89
|
hourglass = "hourglass",
|
90
90
|
katana = "katana",
|
91
91
|
balancerV3 = "balancerV3",
|
92
|
-
hanji_liquidity_vault_token = "hanji_liquidity_vault_token"
|
92
|
+
hanji_liquidity_vault_token = "hanji_liquidity_vault_token",
|
93
|
+
xU308 = "xU308"
|
93
94
|
}
|
94
95
|
export declare const tokenTypeToProtocol: {
|
95
96
|
[key in tokenType]: {
|
@@ -91,6 +91,7 @@ export var tokenType;
|
|
91
91
|
tokenType["katana"] = "katana";
|
92
92
|
tokenType["balancerV3"] = "balancerV3";
|
93
93
|
tokenType["hanji_liquidity_vault_token"] = "hanji_liquidity_vault_token";
|
94
|
+
tokenType["xU308"] = "xU308";
|
94
95
|
})(tokenType || (tokenType = {}));
|
95
96
|
export const tokenTypeToProtocol = {
|
96
97
|
[tokenType.aave_borrowing]: { protocol: "Aave", action: OpportunityAction.BORROW },
|
@@ -182,4 +183,5 @@ export const tokenTypeToProtocol = {
|
|
182
183
|
[tokenType.katana]: { protocol: "Katana", action: OpportunityAction.POOL },
|
183
184
|
[tokenType.balancerV3]: { protocol: "Balancer", action: OpportunityAction.POOL },
|
184
185
|
[tokenType.hanji_liquidity_vault_token]: { protocol: "Hanji", action: OpportunityAction.POOL },
|
186
|
+
[tokenType.xU308]: { protocol: "Uranium", action: OpportunityAction.HOLD },
|
185
187
|
};
|
package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/processorMapping.js
CHANGED
@@ -42,6 +42,7 @@ import { ZkSwapThreePoolProcessor } from "./ZkSwapThreePoolProcessor";
|
|
42
42
|
import { CurveNPoolProcessor } from "./curveNPoolProcessor";
|
43
43
|
import { CurveProcessor } from "./curveProcessor";
|
44
44
|
import { StakedCurveProcessor } from "./stakedCurveProcessor";
|
45
|
+
import { xU308Processor } from "./xU308Processor";
|
45
46
|
export const processorMapping = {
|
46
47
|
[tokenType.uniswapv2]: UniswapProcessor,
|
47
48
|
[tokenType.balancerGauge]: BalancerGaugeProcessor,
|
@@ -132,4 +133,5 @@ export const processorMapping = {
|
|
132
133
|
[tokenType.katana]: UniswapProcessor,
|
133
134
|
[tokenType.balancerV3]: BalancerV3PoolProcessor,
|
134
135
|
[tokenType.hanji_liquidity_vault_token]: HanjiVaultProcessor,
|
136
|
+
[tokenType.xU308]: xU308Processor,
|
135
137
|
};
|
package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/xU308Processor.d.ts
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
import type { Pricer } from "../../../../../utils/pricer";
|
2
|
+
import { type Campaign, type CampaignParameters } from "@sdk";
|
3
|
+
import { GenericProcessor, type dataType, type mandatoryCallKeys } from "../GenericProcessor";
|
4
|
+
import type { tokenType } from "../helpers/tokenType";
|
5
|
+
type callType = {
|
6
|
+
key: keyof dataRawxU308;
|
7
|
+
call: string;
|
8
|
+
target: keyof callKeysxU308;
|
9
|
+
metaData?: keyof callKeysxU308;
|
10
|
+
};
|
11
|
+
type callKeysxU308 = mandatoryCallKeys & {
|
12
|
+
pool: string;
|
13
|
+
token0: string;
|
14
|
+
token1: string;
|
15
|
+
symbolToken0: string;
|
16
|
+
symbolToken1: string;
|
17
|
+
decimalsToken0: string;
|
18
|
+
decimalsToken1: string;
|
19
|
+
balanceToken0: string;
|
20
|
+
balanceToken1: string;
|
21
|
+
totalAssets: string;
|
22
|
+
};
|
23
|
+
type dataRawxU308 = callKeysxU308 & {};
|
24
|
+
type dataTypexU308 = dataType & {
|
25
|
+
pool: string;
|
26
|
+
};
|
27
|
+
export declare class xU308Processor extends GenericProcessor<callKeysxU308, dataRawxU308, dataTypexU308> {
|
28
|
+
rounds: {
|
29
|
+
round1: callType[];
|
30
|
+
round2: callType[];
|
31
|
+
round3: callType[];
|
32
|
+
round4: callType[];
|
33
|
+
};
|
34
|
+
processingRound2(typeInfo: dataRawxU308): void;
|
35
|
+
processingRound5(_index: number, type: tokenType, typeInfo: dataRawxU308, _calls: string[], campaign: CampaignParameters<Campaign.ERC20> | CampaignParameters<Campaign.EULER>, pricer: Pricer): Promise<dataTypexU308>;
|
36
|
+
}
|
37
|
+
export {};
|
@@ -0,0 +1,49 @@
|
|
1
|
+
import { generateCardName } from "../../../../../utils/generateCardName";
|
2
|
+
import { BN2Number } from "@sdk";
|
3
|
+
import { GenericProcessor } from "../GenericProcessor";
|
4
|
+
export class xU308Processor extends GenericProcessor {
|
5
|
+
rounds = {
|
6
|
+
round1: [],
|
7
|
+
round2: [
|
8
|
+
{ key: "token0", call: "token0", target: "pool" },
|
9
|
+
{ key: "token1", call: "token1", target: "pool" },
|
10
|
+
],
|
11
|
+
round3: [
|
12
|
+
{ key: "symbolToken0", call: "symbol", target: "token0" },
|
13
|
+
{ key: "symbolToken1", call: "symbol", target: "token1" },
|
14
|
+
{ key: "decimalsToken0", call: "decimals", target: "token0" },
|
15
|
+
{ key: "decimalsToken1", call: "decimals", target: "token1" },
|
16
|
+
{ key: "balanceToken0", call: "balanceOf", target: "token0", metaData: "pool" },
|
17
|
+
{ key: "balanceToken1", call: "balanceOf", target: "token1", metaData: "pool" },
|
18
|
+
],
|
19
|
+
round4: [{ key: "totalSupply", call: "totalSupply", target: "tokenAddress" }],
|
20
|
+
};
|
21
|
+
// override computeRound1(): void {}
|
22
|
+
processingRound2(typeInfo) {
|
23
|
+
typeInfo.pool = "0xB387D0A73619791420De4a1e5e710023Cb0f49c0";
|
24
|
+
}
|
25
|
+
async processingRound5(_index, type, typeInfo, _calls, campaign, pricer) {
|
26
|
+
const { whitelistedSupplyTargetToken, totalSupply, blacklistedSupply } = this.handleWhiteListBlacklistRound5(typeInfo, campaign);
|
27
|
+
let priceTargetToken = 0;
|
28
|
+
if (typeInfo.token0 !== typeInfo.tokenAddress) {
|
29
|
+
const priceToken0 = (await pricer.get({ symbol: typeInfo.symbolToken0 })) ?? 0;
|
30
|
+
priceTargetToken =
|
31
|
+
(priceToken0 * BN2Number(typeInfo.balanceToken0, Number(typeInfo.decimalsToken0))) /
|
32
|
+
BN2Number(typeInfo.balanceToken1, Number(typeInfo.decimalsToken1));
|
33
|
+
}
|
34
|
+
const priceToken1 = (await pricer.get({ symbol: typeInfo.symbolToken1 })) ?? 0;
|
35
|
+
priceTargetToken =
|
36
|
+
(priceToken1 * BN2Number(typeInfo.balanceToken1, Number(typeInfo.decimalsToken1))) /
|
37
|
+
BN2Number(typeInfo.balanceToken0, Number(typeInfo.decimalsToken0));
|
38
|
+
const tvl = priceTargetToken * totalSupply;
|
39
|
+
return {
|
40
|
+
...typeInfo,
|
41
|
+
tvl,
|
42
|
+
whitelistedSupplyTargetToken,
|
43
|
+
blacklistedSupply,
|
44
|
+
priceTargetToken,
|
45
|
+
totalSupply,
|
46
|
+
cardName: generateCardName(type, typeInfo, campaign),
|
47
|
+
};
|
48
|
+
}
|
49
|
+
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { CacheService } from "../../../modules/v4/cache";
|
2
2
|
import { TTLPresets } from "../../../modules/v4/cache/cache.model";
|
3
|
-
import { ChainInteractionService } from "../../../modules/v4/chainInteraction";
|
3
|
+
import { ChainInteractionService } from "../../../modules/v4/chainInteraction/chainInteraction.service";
|
4
4
|
import { ALM, AMMAlgorithmMapping, BN2Number, NETWORK_LABELS, NFTManagerAddress, NonFungiblePositionManagerInterface, PoolInterface, PoolState, SqrtPrice, YEAR, getAmountsForLiquidity, getSupportedNFPWrapperMapping, getTickAtSqrtRatio, spNFTInterface, } from "@sdk";
|
5
5
|
import { BigNumber, Contract, utils } from "ethers";
|
6
6
|
import JSBI from "jsbi";
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import { NotFoundError } from "../../../errors";
|
2
2
|
import { BackOfficeGuard } from "../../../guards/BackOffice.guard";
|
3
3
|
import { AuthorizationHeadersDto, EngineGuard } from "../../../guards/Engine.guard";
|
4
|
+
import { ChainUniqueDto } from "../chain/chain.model";
|
4
5
|
import Elysia, { t } from "elysia";
|
5
6
|
import { throwOnUnsupportedChainId } from "src/utils/throw";
|
6
|
-
import { ChainUniqueDto } from "../chain";
|
7
7
|
import { CampaignResourceDto, CreateCampaignDto, GetCampaignQueryDto, UpdateCampaignDto, UpdateMetaDataCampaignDto, } from "./campaign.model";
|
8
8
|
import { CampaignService } from "./campaign.service";
|
9
9
|
// ─── Campaigns Controller ────────────────────────────────────────────────────
|
@@ -71,8 +71,29 @@ export declare abstract class CampaignRepository {
|
|
71
71
|
* A campaign is considered past if the current timestamp is greater than the campaign's end timestamp.
|
72
72
|
*
|
73
73
|
* @returns A promise that resolves to an array of past campaigns.
|
74
|
+
*
|
75
|
+
* @dev Excludes test campaigns
|
74
76
|
*/
|
75
|
-
static getPastCampaigns(
|
77
|
+
static getPastCampaigns(query?: {
|
78
|
+
computeChainId?: number;
|
79
|
+
type?: string;
|
80
|
+
}): Promise<({
|
81
|
+
Opportunity: {
|
82
|
+
name: string;
|
83
|
+
type: string;
|
84
|
+
id: string;
|
85
|
+
status: import("../../../../database/api/.generated").$Enums.Status;
|
86
|
+
tags: string[];
|
87
|
+
identifier: string;
|
88
|
+
chainId: number;
|
89
|
+
action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
|
90
|
+
depositUrl: string | null;
|
91
|
+
mainProtocolId: string | null;
|
92
|
+
tvl: number;
|
93
|
+
apr: number;
|
94
|
+
dailyRewards: number;
|
95
|
+
};
|
96
|
+
} & {
|
76
97
|
type: string;
|
77
98
|
id: string;
|
78
99
|
params: Prisma.JsonValue;
|
@@ -86,12 +107,56 @@ export declare abstract class CampaignRepository {
|
|
86
107
|
amount: string;
|
87
108
|
opportunityId: string;
|
88
109
|
creatorAddress: string;
|
89
|
-
}[]>;
|
110
|
+
})[]>;
|
111
|
+
/**
|
112
|
+
* Retrieves all past campaigns from the database.
|
113
|
+
* A campaign is considered past if the current timestamp is greater than the campaign's end timestamp.
|
114
|
+
*
|
115
|
+
* @returns A promise that resolves to an array of past campaigns.
|
116
|
+
*
|
117
|
+
* @dev Excludes test campaigns
|
118
|
+
*/
|
119
|
+
static getFutureCampaigns(query?: {
|
120
|
+
computeChainId?: number;
|
121
|
+
type?: string;
|
122
|
+
}): Promise<({
|
123
|
+
Opportunity: {
|
124
|
+
name: string;
|
125
|
+
type: string;
|
126
|
+
id: string;
|
127
|
+
status: import("../../../../database/api/.generated").$Enums.Status;
|
128
|
+
tags: string[];
|
129
|
+
identifier: string;
|
130
|
+
chainId: number;
|
131
|
+
action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
|
132
|
+
depositUrl: string | null;
|
133
|
+
mainProtocolId: string | null;
|
134
|
+
tvl: number;
|
135
|
+
apr: number;
|
136
|
+
dailyRewards: number;
|
137
|
+
};
|
138
|
+
} & {
|
139
|
+
type: string;
|
140
|
+
id: string;
|
141
|
+
params: Prisma.JsonValue;
|
142
|
+
subType: number | null;
|
143
|
+
startTimestamp: bigint;
|
144
|
+
endTimestamp: bigint;
|
145
|
+
computeChainId: number;
|
146
|
+
distributionChainId: number;
|
147
|
+
campaignId: string;
|
148
|
+
rewardTokenId: string;
|
149
|
+
amount: string;
|
150
|
+
opportunityId: string;
|
151
|
+
creatorAddress: string;
|
152
|
+
})[]>;
|
90
153
|
/**
|
91
154
|
* Retrieves all live campaigns from the database.
|
92
155
|
* A campaign is considered live if the current timestamp is between the campaign's start and end timestamps.
|
93
156
|
*
|
94
157
|
* @returns A promise that resolves to an array of live campaigns.
|
158
|
+
*
|
159
|
+
* @dev Excludes test campaigns
|
95
160
|
*/
|
96
161
|
static getLiveCampaigns(query?: {
|
97
162
|
computeChainId?: number;
|
@@ -54,15 +54,50 @@ export class CampaignRepository {
|
|
54
54
|
* A campaign is considered past if the current timestamp is greater than the campaign's end timestamp.
|
55
55
|
*
|
56
56
|
* @returns A promise that resolves to an array of past campaigns.
|
57
|
+
*
|
58
|
+
* @dev Excludes test campaigns
|
57
59
|
*/
|
58
|
-
static async getPastCampaigns(
|
60
|
+
static async getPastCampaigns(query) {
|
59
61
|
const now = moment().unix();
|
62
|
+
const where = {
|
63
|
+
...query,
|
64
|
+
endTimestamp: {
|
65
|
+
lt: now,
|
66
|
+
},
|
67
|
+
RewardToken: {
|
68
|
+
isTest: false,
|
69
|
+
},
|
70
|
+
};
|
60
71
|
return await apiDbClient.campaign.findMany({
|
61
|
-
where
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
72
|
+
where,
|
73
|
+
include: {
|
74
|
+
Opportunity: true,
|
75
|
+
},
|
76
|
+
});
|
77
|
+
}
|
78
|
+
/**
|
79
|
+
* Retrieves all past campaigns from the database.
|
80
|
+
* A campaign is considered past if the current timestamp is greater than the campaign's end timestamp.
|
81
|
+
*
|
82
|
+
* @returns A promise that resolves to an array of past campaigns.
|
83
|
+
*
|
84
|
+
* @dev Excludes test campaigns
|
85
|
+
*/
|
86
|
+
static async getFutureCampaigns(query) {
|
87
|
+
const now = moment().unix();
|
88
|
+
const where = {
|
89
|
+
...query,
|
90
|
+
startTimestamp: {
|
91
|
+
gt: now,
|
92
|
+
},
|
93
|
+
RewardToken: {
|
94
|
+
isTest: false,
|
95
|
+
},
|
96
|
+
};
|
97
|
+
return await apiDbClient.campaign.findMany({
|
98
|
+
where,
|
99
|
+
include: {
|
100
|
+
Opportunity: true,
|
66
101
|
},
|
67
102
|
});
|
68
103
|
}
|
@@ -71,6 +106,8 @@ export class CampaignRepository {
|
|
71
106
|
* A campaign is considered live if the current timestamp is between the campaign's start and end timestamps.
|
72
107
|
*
|
73
108
|
* @returns A promise that resolves to an array of live campaigns.
|
109
|
+
*
|
110
|
+
* @dev Excludes test campaigns
|
74
111
|
*/
|
75
112
|
static async getLiveCampaigns(query) {
|
76
113
|
const now = moment().unix();
|
@@ -78,6 +115,9 @@ export class CampaignRepository {
|
|
78
115
|
...query,
|
79
116
|
endTimestamp: { gte: now },
|
80
117
|
startTimestamp: { lte: now },
|
118
|
+
RewardToken: {
|
119
|
+
isTest: false,
|
120
|
+
},
|
81
121
|
};
|
82
122
|
return await apiDbClient.campaign.findMany({
|
83
123
|
where,
|
@@ -4,7 +4,26 @@ import { CampaignRepository } from "./campaign.repository";
|
|
4
4
|
export declare abstract class CampaignService {
|
5
5
|
static hashId(campaign: CampaignUnique): string;
|
6
6
|
static splitIdOrThrow(chainAndCampaignId: `${number}-${string}` | string): CampaignUnique;
|
7
|
-
static getPastCampaigns(
|
7
|
+
static getPastCampaigns(query?: {
|
8
|
+
computeChainId?: number;
|
9
|
+
type?: string;
|
10
|
+
}): Promise<({
|
11
|
+
Opportunity: {
|
12
|
+
name: string;
|
13
|
+
type: string;
|
14
|
+
id: string;
|
15
|
+
status: import("../../../../database/api/.generated").$Enums.Status;
|
16
|
+
tags: string[];
|
17
|
+
identifier: string;
|
18
|
+
chainId: number;
|
19
|
+
action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
|
20
|
+
depositUrl: string | null;
|
21
|
+
mainProtocolId: string | null;
|
22
|
+
tvl: number;
|
23
|
+
apr: number;
|
24
|
+
dailyRewards: number;
|
25
|
+
};
|
26
|
+
} & {
|
8
27
|
type: string;
|
9
28
|
id: string;
|
10
29
|
params: import("database/api/.generated/runtime/library").JsonValue;
|
@@ -18,7 +37,41 @@ export declare abstract class CampaignService {
|
|
18
37
|
amount: string;
|
19
38
|
opportunityId: string;
|
20
39
|
creatorAddress: string;
|
21
|
-
}[]>;
|
40
|
+
})[]>;
|
41
|
+
static getFutureCampaigns(query?: {
|
42
|
+
computeChainId?: number;
|
43
|
+
type?: string;
|
44
|
+
}): Promise<({
|
45
|
+
Opportunity: {
|
46
|
+
name: string;
|
47
|
+
type: string;
|
48
|
+
id: string;
|
49
|
+
status: import("../../../../database/api/.generated").$Enums.Status;
|
50
|
+
tags: string[];
|
51
|
+
identifier: string;
|
52
|
+
chainId: number;
|
53
|
+
action: import("../../../../database/api/.generated").$Enums.OpportunityAction;
|
54
|
+
depositUrl: string | null;
|
55
|
+
mainProtocolId: string | null;
|
56
|
+
tvl: number;
|
57
|
+
apr: number;
|
58
|
+
dailyRewards: number;
|
59
|
+
};
|
60
|
+
} & {
|
61
|
+
type: string;
|
62
|
+
id: string;
|
63
|
+
params: import("database/api/.generated/runtime/library").JsonValue;
|
64
|
+
subType: number | null;
|
65
|
+
startTimestamp: bigint;
|
66
|
+
endTimestamp: bigint;
|
67
|
+
computeChainId: number;
|
68
|
+
distributionChainId: number;
|
69
|
+
campaignId: string;
|
70
|
+
rewardTokenId: string;
|
71
|
+
amount: string;
|
72
|
+
opportunityId: string;
|
73
|
+
creatorAddress: string;
|
74
|
+
})[]>;
|
22
75
|
static getLiveCampaigns(query?: {
|
23
76
|
computeChainId?: number;
|
24
77
|
type?: string;
|
@@ -21,8 +21,11 @@ export class CampaignService {
|
|
21
21
|
const [chainId, campaignId] = chainAndCampaignId.split("-");
|
22
22
|
return { distributionChain: +chainId, campaignId };
|
23
23
|
}
|
24
|
-
static async getPastCampaigns(
|
25
|
-
return await CampaignRepository.getPastCampaigns(
|
24
|
+
static async getPastCampaigns(query) {
|
25
|
+
return await CampaignRepository.getPastCampaigns(query);
|
26
|
+
}
|
27
|
+
static async getFutureCampaigns(query) {
|
28
|
+
return await CampaignRepository.getFutureCampaigns(query);
|
26
29
|
}
|
27
30
|
static async getLiveCampaigns(query) {
|
28
31
|
return await CampaignRepository.getLiveCampaigns(query);
|