@merkl/api 0.16.19 → 0.16.20
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/campaignsCacheUpdater.js +1 -1
- package/dist/src/backgroundJobs/jobs/sync.js +1 -1
- package/dist/src/cache/index.d.ts +1 -1
- package/dist/src/cache/index.js +2 -2
- package/dist/src/entities/campaign.js +1 -1
- package/dist/src/libs/deprecated-merklv3/index.js +2 -2
- package/dist/src/modules/v4/accounting/accounting.controller.js +1 -1
- package/dist/src/modules/v4/accounting/accounting.service.d.ts +1 -1
- package/dist/src/modules/v4/accounting/accounting.service.js +1 -1
- package/dist/src/modules/v4/campaign/campaign.repository.js +1 -1
- package/dist/src/modules/v4/chain/chain.controller.js +1 -1
- package/dist/src/modules/v4/chain/chain.repository.d.ts +1 -6
- package/dist/src/modules/v4/chain/chain.repository.js +2 -5
- package/dist/src/modules/v4/chain/chain.service.d.ts +1 -6
- package/dist/src/modules/v4/chain/chain.service.js +2 -5
- package/dist/src/modules/v4/opportunity/opportunity.controller.js +1 -1
- package/dist/src/modules/v4/opportunity/opportunity.service.d.ts +1 -1
- package/dist/src/modules/v4/opportunity/opportunity.service.js +1 -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.service.js +1 -1
- package/dist/src/routes/v3/multiChainPositions.js +1 -1
- package/dist/src/routes/v3/opportunity.js +5 -0
- package/dist/tsconfig.package.tsbuildinfo +1 -1
- package/package.json +1 -1
@@ -141,7 +141,7 @@ export const campaignCacheUpdate = async (rawChainId, queryCampaignTypes, highCa
|
|
141
141
|
}
|
142
142
|
await OpportunityService.updateMetadata(chainId);
|
143
143
|
// ─── Refresh Cache For GET /opportunities ────
|
144
|
-
await CacheService.set(TTLPresets.MIN_5, OpportunityService.
|
144
|
+
await CacheService.set(TTLPresets.MIN_5, OpportunityService.findMany, { items: 50, page: 0 });
|
145
145
|
log.info(`✅ ${NETWORK_LABELS[chainId]} DB records updated successfully`);
|
146
146
|
}
|
147
147
|
else {
|
@@ -4,7 +4,7 @@ import { ChainService } from "../../modules/v4/chain";
|
|
4
4
|
import { log } from "../../utils/logger";
|
5
5
|
import Elysia from "elysia";
|
6
6
|
export const sync = new Elysia({ prefix: "/jobs" }).get("/api/sync-with-engine", async () => {
|
7
|
-
const chains = await ChainService.
|
7
|
+
const chains = await ChainService.findMany({});
|
8
8
|
for (const chain of chains) {
|
9
9
|
log.info(`fetching campaigns on ${chain.name} (chainId: ${chain.id})`);
|
10
10
|
const campaignsV3 = await CampaignService.getFromEngineDb(chain.id, 0);
|
@@ -32,7 +32,7 @@ export declare class Cache {
|
|
32
32
|
* @param key cache key
|
33
33
|
* @returns the uncompressed (if enabled), parsed and typed data from the cache for all keys
|
34
34
|
*/
|
35
|
-
|
35
|
+
findMany<T extends CacheKey, Key extends T | NonNullable<CacheArg[T]>>(keys: Key[]): Promise<CacheKeys[T]["returns"][]>;
|
36
36
|
/**
|
37
37
|
* Get many data from cache with argument
|
38
38
|
* @param key cache key
|
package/dist/src/cache/index.js
CHANGED
@@ -98,7 +98,7 @@ export class Cache {
|
|
98
98
|
* @param key cache key
|
99
99
|
* @returns the uncompressed (if enabled), parsed and typed data from the cache for all keys
|
100
100
|
*/
|
101
|
-
async
|
101
|
+
async findMany(keys) {
|
102
102
|
const nonLocalKeys = keys.filter(key => !this.isLocallyCached(key)); // Keys not stored locally
|
103
103
|
const cached = !!nonLocalKeys.length ? await this.getManyRaw(nonLocalKeys) : [];
|
104
104
|
const res = keys.map(key => {
|
@@ -122,7 +122,7 @@ export class Cache {
|
|
122
122
|
*/
|
123
123
|
async getManyWithArgs(key, args) {
|
124
124
|
const actualKeys = args.map(arg => `${key}_${arg}`);
|
125
|
-
return this.
|
125
|
+
return this.findMany(actualKeys);
|
126
126
|
}
|
127
127
|
/**
|
128
128
|
* Get data from cache or set it using the callback
|
@@ -7,7 +7,7 @@ export const removeTestTokens = (v) => !["aglamerkl", "test"].includes(v.campaig
|
|
7
7
|
export async function getCampaignsFor(chainIds, filters = { onlyLive: false }) {
|
8
8
|
const cachePrefix = filters?.onlyLive ? "LiveCampaigns" : "Campaigns";
|
9
9
|
const cacheKeys = chainIds.map(chain => `${cachePrefix}_${chain}`);
|
10
|
-
return (await Redis.
|
10
|
+
return (await Redis.findMany(cacheKeys)).reduce((prev, allData, index) => {
|
11
11
|
if (!!allData) {
|
12
12
|
const chain = chainIds[index];
|
13
13
|
prev[chain] = Object.keys(allData).reduce((acc, curr) => {
|
@@ -9,7 +9,7 @@ const fetchCachedData = async (chainIds, onlyLive) => {
|
|
9
9
|
onlyLive = false;
|
10
10
|
}
|
11
11
|
const cacheKeys = chainIds.map(chainId => onlyLive ? `LiveCampaignsOldFormat_${chainId}` : `CampaignsOldFormat_${chainId}`);
|
12
|
-
return await Redis.
|
12
|
+
return await Redis.findMany(cacheKeys);
|
13
13
|
};
|
14
14
|
export async function getClamsInfo(chainIds, AMMs, user, onlyLive) {
|
15
15
|
if (!chainIds && !user && !AMMs) {
|
@@ -34,7 +34,7 @@ export async function getClamsInfo(chainIds, AMMs, user, onlyLive) {
|
|
34
34
|
const cachedData = await fetchCachedData(chainIds, onlyLive);
|
35
35
|
let chainData = [];
|
36
36
|
if (!!user) {
|
37
|
-
chainData = await Redis.
|
37
|
+
chainData = await Redis.findMany(chainIds.map(chainId => `MerklChainData_${chainId}`));
|
38
38
|
}
|
39
39
|
/** Parallel computation of data for each chain */
|
40
40
|
const result = {};
|
@@ -3,7 +3,7 @@ import { AccountingService, ChainDto, DateDto, GetTransactionsQueryModel, Revenu
|
|
3
3
|
import { throwOnInvalidRequiredAddress, throwOnUnsupportedChainId } from "../../../utils/throw";
|
4
4
|
import Elysia from "elysia";
|
5
5
|
export const AccountingController = new Elysia({ prefix: "/accounting", detail: { tags: ["Accounting"], hide: true } })
|
6
|
-
.get("/", async ({ query }) => await AccountingService.
|
6
|
+
.get("/", async ({ query }) => await AccountingService.findMany(query), {
|
7
7
|
query: GetTransactionsQueryModel,
|
8
8
|
headers: AuthorizationHeadersDto,
|
9
9
|
beforeHandle: async ({ headers }) => {
|
@@ -3,7 +3,7 @@ import { ChainId } from "@sdk";
|
|
3
3
|
export declare class AccountingService {
|
4
4
|
static hashId(chainId: ChainId, fromTokenId: string, toTokenId: string, timestamp: number): string;
|
5
5
|
static getTokenId(chainId: number, address: string): string;
|
6
|
-
static
|
6
|
+
static findMany(query: GetTransactionsQueryModel): Promise<{
|
7
7
|
id: string;
|
8
8
|
timestamp: number;
|
9
9
|
chainId: number;
|
@@ -8,7 +8,7 @@ export class AccountingService {
|
|
8
8
|
static getTokenId(chainId, address) {
|
9
9
|
return TokenService.hashId({ chainId, address });
|
10
10
|
}
|
11
|
-
static async
|
11
|
+
static async findMany(query) {
|
12
12
|
return await AccountingRepository.findMany(query);
|
13
13
|
}
|
14
14
|
static async getRevenue() {
|
@@ -237,7 +237,7 @@ export class CampaignRepository {
|
|
237
237
|
status: {
|
238
238
|
not: RunStatus.PROCESSING,
|
239
239
|
},
|
240
|
-
computedUntil: { lt: currentTime }, // more than 10 min ago
|
240
|
+
computedUntil: { lt: currentTime - 10 * 60 }, // more than 10 min ago
|
241
241
|
},
|
242
242
|
{
|
243
243
|
status: RunStatus.PROCESSING,
|
@@ -17,7 +17,7 @@ export const ChainController = new Elysia({ prefix: "/chains", detail: { tags: [
|
|
17
17
|
})
|
18
18
|
// ─── Get All Supported Chains ────────────────────────────────────────
|
19
19
|
.get("/", async ({ query }) => {
|
20
|
-
const chains = await ChainService.
|
20
|
+
const chains = await ChainService.findMany(query);
|
21
21
|
return chains.map(({ Explorer, ...chain }) => ({ explorers: Explorer, ...chain }));
|
22
22
|
}, {
|
23
23
|
query: GetChainQueryDto,
|
@@ -22,7 +22,7 @@ export declare abstract class ChainRepository {
|
|
22
22
|
* @param query object with fields to search for
|
23
23
|
* @returns
|
24
24
|
*/
|
25
|
-
static
|
25
|
+
static findMany(query: ChainSearchDto): Promise<({
|
26
26
|
Explorer: {
|
27
27
|
type: import("../../../../database/api/.generated").$Enums.ExplorerType;
|
28
28
|
url: string;
|
@@ -53,11 +53,6 @@ export declare abstract class ChainRepository {
|
|
53
53
|
chainId: number;
|
54
54
|
}[];
|
55
55
|
}>;
|
56
|
-
static findMany(): Promise<{
|
57
|
-
name: string;
|
58
|
-
id: number;
|
59
|
-
icon: string;
|
60
|
-
}[]>;
|
61
56
|
static findUniqueOrThrow(id: number): Promise<{
|
62
57
|
Explorer: {
|
63
58
|
type: import("../../../../database/api/.generated").$Enums.ExplorerType;
|
@@ -13,14 +13,14 @@ export class ChainRepository {
|
|
13
13
|
}
|
14
14
|
static #transformQueryToPrismaFilters(query) {
|
15
15
|
return {
|
16
|
-
where: { name: { contains: query.name, mode: "insensitive" } },
|
16
|
+
where: { name: query.name ? { contains: query.name, mode: "insensitive" } : undefined },
|
17
17
|
};
|
18
18
|
}
|
19
19
|
/** Returns many chains based on query
|
20
20
|
* @param query object with fields to search for
|
21
21
|
* @returns
|
22
22
|
*/
|
23
|
-
static async
|
23
|
+
static async findMany(query) {
|
24
24
|
const args = ChainRepository.#transformQueryToPrismaFilters(query);
|
25
25
|
return apiDbClient.chain.findMany({
|
26
26
|
include: { Explorer: { take: 5 } },
|
@@ -56,9 +56,6 @@ export class ChainRepository {
|
|
56
56
|
await ExplorerRepository.create(data.id, data.explorerType, data.explorerUrl);
|
57
57
|
return await ChainRepository.findUniqueOrThrow(data.id);
|
58
58
|
}
|
59
|
-
static async findMany() {
|
60
|
-
return apiDbClient.chain.findMany();
|
61
|
-
}
|
62
59
|
static async findUniqueOrThrow(id) {
|
63
60
|
return apiDbClient.chain.findUniqueOrThrow({
|
64
61
|
where: {
|
@@ -12,12 +12,7 @@ export declare abstract class ChainService {
|
|
12
12
|
id: number;
|
13
13
|
icon: string;
|
14
14
|
}) | null>;
|
15
|
-
static findMany(): Promise<{
|
16
|
-
name: string;
|
17
|
-
id: number;
|
18
|
-
icon: string;
|
19
|
-
}[]>;
|
20
|
-
static getMany(query: ChainSearchDto): Promise<({
|
15
|
+
static findMany(query: ChainSearchDto): Promise<({
|
21
16
|
Explorer: {
|
22
17
|
type: import("../../../../database/api/.generated").$Enums.ExplorerType;
|
23
18
|
url: string;
|
@@ -7,11 +7,8 @@ export class ChainService {
|
|
7
7
|
return ChainRepository.read(chainId);
|
8
8
|
}
|
9
9
|
//TODO: determine find vs get nomenclature and cache handling
|
10
|
-
static async findMany() {
|
11
|
-
return await CacheService.wrap(TTLPresets.HOUR_4, ChainRepository.findMany);
|
12
|
-
}
|
13
|
-
static async getMany(query) {
|
14
|
-
return ChainRepository.readMany(query);
|
10
|
+
static async findMany(query) {
|
11
|
+
return await CacheService.wrap(TTLPresets.HOUR_4, ChainRepository.findMany, query);
|
15
12
|
}
|
16
13
|
static async countMany(query) {
|
17
14
|
return ChainRepository.countMany(query);
|
@@ -45,7 +45,7 @@ export const OpportunityController = new Elysia({
|
|
45
45
|
detail: { hide: true },
|
46
46
|
})
|
47
47
|
// ─── Get All Opportunities ───────────────────────────────────────────
|
48
|
-
.get("/", async ({ query }) => await OpportunityService.
|
48
|
+
.get("/", async ({ query }) => await OpportunityService.findMany(query), {
|
49
49
|
query: GetOpportunitiesQueryDto,
|
50
50
|
detail: {
|
51
51
|
description: `**Retrieve Multiple Opportunities**
|
@@ -266,7 +266,7 @@ export declare abstract class OpportunityService {
|
|
266
266
|
* @param query
|
267
267
|
* @returns A list of opportunities
|
268
268
|
*/
|
269
|
-
static
|
269
|
+
static findMany(query: GetOpportunitiesQueryModel): Promise<{
|
270
270
|
apr: number;
|
271
271
|
aprRecord: {
|
272
272
|
cumulated: number;
|
@@ -271,7 +271,7 @@ export class OpportunityService {
|
|
271
271
|
* @param query
|
272
272
|
* @returns A list of opportunities
|
273
273
|
*/
|
274
|
-
static async
|
274
|
+
static async findMany(query) {
|
275
275
|
return await CacheService.wrap(TTLPresets.MIN_5, async (query) => {
|
276
276
|
const opportunities = await OpportunityRepository.findMany(query);
|
277
277
|
return opportunities.map(OpportunityService.formatResponse);
|
@@ -44,7 +44,7 @@ export class ProtocolService {
|
|
44
44
|
log.info(`Updated protocol ${protocol.id} icon`);
|
45
45
|
}
|
46
46
|
}
|
47
|
-
const chains = await ChainService.findMany();
|
47
|
+
const chains = await ChainService.findMany({});
|
48
48
|
for (const chain of chains) {
|
49
49
|
if (chain.icon.includes(oldUrl)) {
|
50
50
|
await ChainService.update(chain.id, { icon: chain.icon.replace(oldUrl, newUrl) });
|
@@ -174,7 +174,7 @@ export class RewardService {
|
|
174
174
|
return rewards;
|
175
175
|
}
|
176
176
|
static async getUserRewardsByChain(user, withToken, chainFilter = [], connectedChainId = null, withTestTokens = false) {
|
177
|
-
const chains = await ChainService.findMany();
|
177
|
+
const chains = await ChainService.findMany({});
|
178
178
|
let chainIds = !chainFilter || !chainFilter.length
|
179
179
|
? chains.map(({ id }) => id)
|
180
180
|
: chains.map(({ id }) => id).filter(id => chainFilter.includes(id));
|
@@ -54,7 +54,7 @@ export class UserService {
|
|
54
54
|
static async syncOpportunityTags() {
|
55
55
|
const users = await UserRepository.findManyWithTags();
|
56
56
|
for (const user of users) {
|
57
|
-
const opportunities = await OpportunityService.
|
57
|
+
const opportunities = await OpportunityService.findMany({ creatorAddress: user.address });
|
58
58
|
for (const opportunity of opportunities) {
|
59
59
|
if (!user.tags.every(tag => opportunity.tags.includes(tag))) {
|
60
60
|
log.local(`updating tags for opportunity ${opportunity.id}: adding ${user.tags.join(",")}`);
|
@@ -33,7 +33,7 @@ export default (app) => app.use(checkQueryAddressValidity()).get("/multiChainPos
|
|
33
33
|
for (const chainId of chainIds)
|
34
34
|
throwOnUnsupportedChainId(chainId);
|
35
35
|
const cacheKeys = chainIds.map(chainId => `LiveCampaigns_${chainId}`);
|
36
|
-
const cacheData = await Redis.
|
36
|
+
const cacheData = await Redis.findMany(cacheKeys);
|
37
37
|
const promises = [];
|
38
38
|
let i = 0;
|
39
39
|
for (const chainId of chainIds) {
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { Redis } from "../../cache";
|
2
|
+
import { OpportunityService } from "../../modules/v4/opportunity";
|
2
3
|
import { t } from "elysia";
|
3
4
|
import { fillCampaigns } from "../../entities/opportunity";
|
4
5
|
import param from "../../types/parameters";
|
@@ -25,6 +26,10 @@ export const response = t.Record(t.TemplateLiteral([param.Type.type, t.Literal("
|
|
25
26
|
}));
|
26
27
|
export default (app) => {
|
27
28
|
return app.get("/opportunity", async ({ query: { campaigns: showCampaigns, ...filters } }) => {
|
29
|
+
if (process.env.FF_OPPORTUNITY === "true") {
|
30
|
+
const opportunities = await OpportunityService.findMany({ items: 10_000 });
|
31
|
+
return {};
|
32
|
+
}
|
28
33
|
const opportunities = await Redis.get(filters?.testTokens ? "OpportunitiesWithTest" : "Opportunities");
|
29
34
|
const returnedOpportunities = {};
|
30
35
|
const corresponds = (opp) => {
|