@merkl/api 0.16.19 → 0.16.21

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.
@@ -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.getMany, { items: 50, page: 0 });
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.getMany({});
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
- getMany<T extends CacheKey, Key extends T | NonNullable<CacheArg[T]>>(keys: Key[]): Promise<CacheKeys[T]["returns"][]>;
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
@@ -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 getMany(keys) {
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.getMany(actualKeys);
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.getMany(cacheKeys)).reduce((prev, allData, index) => {
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.getMany(cacheKeys);
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.getMany(chainIds.map(chainId => `MerklChainData_${chainId}`));
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.getMany(query), {
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 getMany(query: GetTransactionsQueryModel): Promise<{
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 getMany(query) {
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.getMany(query);
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 readMany(query: ChainSearchDto): Promise<({
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 readMany(query) {
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.getMany(query), {
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 getMany(query: GetOpportunitiesQueryModel): Promise<{
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 getMany(query) {
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.getMany({ creatorAddress: user.address });
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.getMany(cacheKeys);
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) => {