@merkl/api 0.10.186 → 0.10.187

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.
@@ -1282,7 +1282,7 @@ declare const eden: {
1282
1282
  } | null;
1283
1283
  }>>;
1284
1284
  rewards: {
1285
- full: {
1285
+ breakdowns: {
1286
1286
  get: (options?: {
1287
1287
  headers?: Record<string, unknown> | undefined;
1288
1288
  query?: Record<string, unknown> | undefined;
@@ -3606,10 +3606,11 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
3606
3606
  users: {
3607
3607
  ":address": {
3608
3608
  rewards: {
3609
- full: {
3609
+ breakdowns: {
3610
3610
  get: {
3611
3611
  body: unknown;
3612
3612
  params: {
3613
+ chainId?: number | undefined;
3613
3614
  address: string;
3614
3615
  };
3615
3616
  query: unknown;
@@ -5716,7 +5717,7 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
5716
5717
  } | null;
5717
5718
  }>>;
5718
5719
  rewards: {
5719
- full: {
5720
+ breakdowns: {
5720
5721
  get: (options?: {
5721
5722
  headers?: Record<string, unknown> | undefined;
5722
5723
  query?: Record<string, unknown> | undefined;
@@ -1631,10 +1631,11 @@ declare const app: Elysia<"", false, {
1631
1631
  users: {
1632
1632
  ":address": {
1633
1633
  rewards: {
1634
- full: {
1634
+ breakdowns: {
1635
1635
  get: {
1636
1636
  body: unknown;
1637
1637
  params: {
1638
+ chainId?: number | undefined;
1638
1639
  address: string;
1639
1640
  };
1640
1641
  query: unknown;
@@ -1,6 +1,6 @@
1
1
  import type { CacheKeys } from "../../../cache/keys";
2
2
  import type { Chain } from "../../../../database/api/.generated";
3
- import { Campaign, type CampaignDynamicData, type ChainId } from "@sdk";
3
+ import { Campaign, type CampaignDynamicData, type ChainId, type MerklChainId } from "@sdk";
4
4
  import { type LightOpportunityFromDB, type Opportunity } from "../opportunity";
5
5
  import type { CampaignIdModel, CampaignIdWithoutPageModel, CreateManyBreakdownModel, CreateManyRewardModel, DailyRewardsRecord, RegisterClaimsModel, RewardBreakdown, UpdatePendingModel } from "./reward.model";
6
6
  import { RewardRepository } from "./reward.repository";
@@ -537,7 +537,7 @@ export declare abstract class RewardService {
537
537
  root: string;
538
538
  proofs: string[];
539
539
  })[]>;
540
- static getUserRewardsByChain(user: string, withToken: boolean, chainFilter?: ChainId[]): Promise<{
540
+ static getUserRewardsByChain(user: string, withToken: boolean, chainFilter?: ChainId[], connectedChainId?: MerklChainId | null): Promise<{
541
541
  chain: Chain;
542
542
  rewards: Awaited<ReturnType<(typeof RewardService)["format"]>>;
543
543
  }[]>;
@@ -1,5 +1,5 @@
1
1
  import { log } from "../../../utils/logger";
2
- import { Campaign, DistributorService, NETWORK_LABELS } from "@sdk";
2
+ import { Campaign, DistributorService, NETWORK_LABELS, } from "@sdk";
3
3
  import moment from "moment";
4
4
  import { BlacklistService } from "../blacklist";
5
5
  import { CacheService } from "../cache";
@@ -150,7 +150,10 @@ export class RewardService {
150
150
  // -> claim is on the current root (chainData.merklRoot) -> claimed === accumulated
151
151
  if (merklRootClaimedOn === roots.live) {
152
152
  for (const breakdown of reward.Breakdown) {
153
+ if (BigInt(breakdown.claimed) === BigInt(breakdown.amount))
154
+ continue;
153
155
  breakdown.claimed = breakdown.amount; // Set unclaim to 0
156
+ await RewardRepository.updateClaimed(user, TokenService.hashId(reward.RewardToken), reward.Breakdown[0].campaignId, reward.Breakdown[0].reason, reward.Breakdown[0].amount);
154
157
  }
155
158
  }
156
159
  // -> claim is on a tree we have in db -> claimed === accumulated of the rewards of lastTree
@@ -169,7 +172,7 @@ export class RewardService {
169
172
  }
170
173
  return rewards;
171
174
  }
172
- static async getUserRewardsByChain(user, withToken, chainFilter = []) {
175
+ static async getUserRewardsByChain(user, withToken, chainFilter = [], connectedChainId = null) {
173
176
  const chains = await ChainService.findMany();
174
177
  let chainIds = chains.map(({ id }) => id).filter(id => !chainFilter.length || chainFilter.includes(id));
175
178
  /** Check if the user is blacklisted */
@@ -193,8 +196,13 @@ export class RewardService {
193
196
  throw new Error(`Chain ${chainId} not found`);
194
197
  const chainRewards = rewards.filter(reward => reward.RewardToken.chainId === chainId);
195
198
  /** Check when the last claim happened */
196
- if (chainRewards.length > 0) {
197
- promises.push(RewardService.checkLastClaim(chainId, user, merkleRoots[index], chainRewards).then(r => res.push({ chain, rewards: RewardService.format(r) })));
199
+ if ((!connectedChainId || chain.id === connectedChainId) && chainRewards.length > 0) {
200
+ promises.push(RewardService.checkLastClaim(chainId, user, merkleRoots[index], chainRewards).then(r => {
201
+ return { chain, rewards: r };
202
+ }));
203
+ }
204
+ else {
205
+ promises.push(Promise.resolve({ chain, rewards: chainRewards }));
198
206
  }
199
207
  }
200
208
  const settledPromises = await Promise.allSettled(promises);
@@ -202,6 +210,9 @@ export class RewardService {
202
210
  if (promise.status === "rejected") {
203
211
  log.error("checkLastClaim failed", promise.reason);
204
212
  }
213
+ else {
214
+ res.push({ chain: promise.value.chain, rewards: RewardService.format(promise.value.rewards) });
215
+ }
205
216
  }
206
217
  return res;
207
218
  }
@@ -1613,10 +1613,11 @@ export declare const v4: Elysia<"/v4", false, {
1613
1613
  users: {
1614
1614
  ":address": {
1615
1615
  rewards: {
1616
- full: {
1616
+ breakdowns: {
1617
1617
  get: {
1618
1618
  body: unknown;
1619
1619
  params: {
1620
+ chainId?: number | undefined;
1620
1621
  address: string;
1621
1622
  };
1622
1623
  query: unknown;
@@ -76,10 +76,11 @@ export declare const UserController: Elysia<"/users", false, {
76
76
  users: {
77
77
  ":address": {
78
78
  rewards: {
79
- full: {
79
+ breakdowns: {
80
80
  get: {
81
81
  body: unknown;
82
82
  params: {
83
+ chainId?: number | undefined;
83
84
  address: string;
84
85
  };
85
86
  query: unknown;
@@ -3,7 +3,7 @@ import { throwOnInvalidRequiredAddress, throwOnUnsupportedChainId } from "../../
3
3
  import { Elysia } from "elysia";
4
4
  import { ChainArrayDto } from "../chain";
5
5
  import { RewardService } from "../reward";
6
- import { GetManyUserQuery, UpdateUserTagsDto, UserDto, UserUniqueDto } from "./user.model";
6
+ import { GetManyUserQuery, UpdateUserTagsDto, UserDto, UserUniqueDto, UserUniqueWithChainIdDto } from "./user.model";
7
7
  import { UserService } from "./user.service";
8
8
  // ─── Users Controller ────────────────────────────────────────────────────────
9
9
  export const UserController = new Elysia({ prefix: "/users", detail: { tags: ["Users"] } })
@@ -20,13 +20,11 @@ export const UserController = new Elysia({ prefix: "/users", detail: { tags: ["U
20
20
  return await UserService.findUnique(params.address);
21
21
  })
22
22
  // ─── Get User's Rewards With Breakdown And Details for our FE ────────
23
- .get(
24
- // TODO: redefine as /:address/rewards/breakdowns to follow REST standard (URI components should be nouns)
25
- "/:address/rewards/full", async ({ params }) => {
26
- const rewardsByChain = await RewardService.getUserRewardsByChain(params.address, true);
23
+ .get("/:address/rewards/breakdowns", async ({ params }) => {
24
+ const rewardsByChain = await RewardService.getUserRewardsByChain(params.address, true, [], params.chainId ?? null);
27
25
  return RewardService.splitRewardsBreakdownByOpportunity(rewardsByChain);
28
26
  }, {
29
- params: UserUniqueDto,
27
+ params: UserUniqueWithChainIdDto,
30
28
  beforeHandle: ({ params }) => {
31
29
  params.address = throwOnInvalidRequiredAddress(params.address);
32
30
  },
@@ -8,6 +8,10 @@ export type User = Resource<"User">;
8
8
  export declare const UserUniqueDto: import("@sinclair/typebox").TObject<{
9
9
  address: import("@sinclair/typebox").TString;
10
10
  }>;
11
+ export declare const UserUniqueWithChainIdDto: import("@sinclair/typebox").TObject<{
12
+ address: import("@sinclair/typebox").TString;
13
+ chainId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
14
+ }>;
11
15
  export declare const UserDto: import("@sinclair/typebox").TObject<{
12
16
  address: import("@sinclair/typebox").TString;
13
17
  tags: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
@@ -23,4 +27,5 @@ export declare const UpdateUserTagsDto: import("@sinclair/typebox").TObject<{
23
27
  }>;
24
28
  export type UserUniqueModel = typeof UserUniqueDto.static;
25
29
  export type UserModel = typeof UserDto.static;
30
+ export type UserWithChainIdModel = typeof UserUniqueWithChainIdDto.static;
26
31
  export type GetManyUserModel = typeof GetManyUserQuery.static;
@@ -3,6 +3,10 @@ import { t } from "elysia";
3
3
  export const UserUniqueDto = t.Object({
4
4
  address: t.String(),
5
5
  });
6
+ export const UserUniqueWithChainIdDto = t.Object({
7
+ address: t.String(),
8
+ chainId: t.Optional(t.Numeric()),
9
+ });
6
10
  export const UserDto = t.Object({
7
11
  address: t.String(),
8
12
  tags: t.Array(t.String()),
@@ -1637,10 +1637,11 @@ declare const _default: (app: App) => import("elysia").default<"", false, {
1637
1637
  users: {
1638
1638
  ":address": {
1639
1639
  rewards: {
1640
- full: {
1640
+ breakdowns: {
1641
1641
  get: {
1642
1642
  body: unknown;
1643
1643
  params: {
1644
+ chainId?: number | undefined;
1644
1645
  address: string;
1645
1646
  };
1646
1647
  query: unknown;
@@ -1640,10 +1640,11 @@ declare const _default: (app: App) => import("elysia").default<"", false, {
1640
1640
  users: {
1641
1641
  ":address": {
1642
1642
  rewards: {
1643
- full: {
1643
+ breakdowns: {
1644
1644
  get: {
1645
1645
  body: unknown;
1646
1646
  params: {
1647
+ chainId?: number | undefined;
1647
1648
  address: string;
1648
1649
  };
1649
1650
  query: unknown;
@@ -1631,10 +1631,11 @@ declare const _default: (app: App) => import("elysia").default<"", false, {
1631
1631
  users: {
1632
1632
  ":address": {
1633
1633
  rewards: {
1634
- full: {
1634
+ breakdowns: {
1635
1635
  get: {
1636
1636
  body: unknown;
1637
1637
  params: {
1638
+ chainId?: number | undefined;
1638
1639
  address: string;
1639
1640
  };
1640
1641
  query: unknown;
@@ -1636,10 +1636,11 @@ declare const _default: (app: App) => import("elysia").default<"", false, {
1636
1636
  users: {
1637
1637
  ":address": {
1638
1638
  rewards: {
1639
- full: {
1639
+ breakdowns: {
1640
1640
  get: {
1641
1641
  body: unknown;
1642
1642
  params: {
1643
+ chainId?: number | undefined;
1643
1644
  address: string;
1644
1645
  };
1645
1646
  query: unknown;
@@ -1654,10 +1654,11 @@ declare const _default: (app: App) => import("elysia").default<"", false, {
1654
1654
  users: {
1655
1655
  ":address": {
1656
1656
  rewards: {
1657
- full: {
1657
+ breakdowns: {
1658
1658
  get: {
1659
1659
  body: unknown;
1660
1660
  params: {
1661
+ chainId?: number | undefined;
1661
1662
  address: string;
1662
1663
  };
1663
1664
  query: unknown;
@@ -1655,10 +1655,11 @@ declare const _default: (app: App) => import("elysia").default<"", false, {
1655
1655
  users: {
1656
1656
  ":address": {
1657
1657
  rewards: {
1658
- full: {
1658
+ breakdowns: {
1659
1659
  get: {
1660
1660
  body: unknown;
1661
1661
  params: {
1662
+ chainId?: number | undefined;
1662
1663
  address: string;
1663
1664
  };
1664
1665
  query: unknown;
@@ -1637,10 +1637,11 @@ declare const _default: (app: App) => import("elysia").default<"", false, {
1637
1637
  users: {
1638
1638
  ":address": {
1639
1639
  rewards: {
1640
- full: {
1640
+ breakdowns: {
1641
1641
  get: {
1642
1642
  body: unknown;
1643
1643
  params: {
1644
+ chainId?: number | undefined;
1644
1645
  address: string;
1645
1646
  };
1646
1647
  query: unknown;
@@ -1638,10 +1638,11 @@ declare const _default: (app: App) => import("elysia").default<"", false, {
1638
1638
  users: {
1639
1639
  ":address": {
1640
1640
  rewards: {
1641
- full: {
1641
+ breakdowns: {
1642
1642
  get: {
1643
1643
  body: unknown;
1644
1644
  params: {
1645
+ chainId?: number | undefined;
1645
1646
  address: string;
1646
1647
  };
1647
1648
  query: unknown;
@@ -1640,10 +1640,11 @@ declare const _default: (app: App) => import("elysia").default<"", false, {
1640
1640
  users: {
1641
1641
  ":address": {
1642
1642
  rewards: {
1643
- full: {
1643
+ breakdowns: {
1644
1644
  get: {
1645
1645
  body: unknown;
1646
1646
  params: {
1647
+ chainId?: number | undefined;
1647
1648
  address: string;
1648
1649
  };
1649
1650
  query: unknown;