@merkl/api 0.10.186 → 0.10.188

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,12 +1282,14 @@ declare const eden: {
1282
1282
  } | null;
1283
1283
  }>>;
1284
1284
  rewards: {
1285
- full: {
1286
- get: (options?: {
1285
+ breakdowns: {
1286
+ get: (options: {
1287
1287
  headers?: Record<string, unknown> | undefined;
1288
- query?: Record<string, unknown> | undefined;
1288
+ query: {
1289
+ chainId?: number | undefined;
1290
+ };
1289
1291
  fetch?: RequestInit | undefined;
1290
- } | undefined) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
1292
+ }) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
1291
1293
  200: (Omit<{
1292
1294
  chain: import("../../database/api/.generated").Chain;
1293
1295
  rewards: Awaited<ReturnType<typeof import("../modules/v4/reward").RewardService["format"]>>;
@@ -3606,13 +3608,15 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
3606
3608
  users: {
3607
3609
  ":address": {
3608
3610
  rewards: {
3609
- full: {
3611
+ breakdowns: {
3610
3612
  get: {
3611
3613
  body: unknown;
3612
3614
  params: {
3613
3615
  address: string;
3614
3616
  };
3615
- query: unknown;
3617
+ query: {
3618
+ chainId?: number | undefined;
3619
+ };
3616
3620
  headers: unknown;
3617
3621
  response: {
3618
3622
  200: (Omit<{
@@ -5716,12 +5720,14 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
5716
5720
  } | null;
5717
5721
  }>>;
5718
5722
  rewards: {
5719
- full: {
5720
- get: (options?: {
5723
+ breakdowns: {
5724
+ get: (options: {
5721
5725
  headers?: Record<string, unknown> | undefined;
5722
- query?: Record<string, unknown> | undefined;
5726
+ query: {
5727
+ chainId?: number | undefined;
5728
+ };
5723
5729
  fetch?: RequestInit | undefined;
5724
- } | undefined) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
5730
+ }) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
5725
5731
  200: (Omit<{
5726
5732
  chain: import("../../database/api/.generated").Chain;
5727
5733
  rewards: Awaited<ReturnType<typeof import("../modules/v4/reward").RewardService["format"]>>;
@@ -1631,13 +1631,15 @@ 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
1638
  address: string;
1639
1639
  };
1640
- query: unknown;
1640
+ query: {
1641
+ chainId?: number | undefined;
1642
+ };
1641
1643
  headers: unknown;
1642
1644
  response: {
1643
1645
  200: (Omit<{
@@ -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,13 +1613,15 @@ 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
1620
  address: string;
1621
1621
  };
1622
- query: unknown;
1622
+ query: {
1623
+ chainId?: number | undefined;
1624
+ };
1623
1625
  headers: unknown;
1624
1626
  response: {
1625
1627
  200: (Omit<{
@@ -76,13 +76,15 @@ 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
83
  address: string;
84
84
  };
85
- query: unknown;
85
+ query: {
86
+ chainId?: number | undefined;
87
+ };
86
88
  headers: unknown;
87
89
  response: {
88
90
  200: (Omit<{
@@ -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, OptionalChainIdDto, UpdateUserTagsDto, UserDto, UserUniqueDto } 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,15 +20,16 @@ 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, query }) => {
24
+ const rewardsByChain = await RewardService.getUserRewardsByChain(params.address, true, [], query.chainId ?? null);
27
25
  return RewardService.splitRewardsBreakdownByOpportunity(rewardsByChain);
28
26
  }, {
29
27
  params: UserUniqueDto,
30
- beforeHandle: ({ params }) => {
28
+ query: OptionalChainIdDto,
29
+ beforeHandle: ({ params, query }) => {
31
30
  params.address = throwOnInvalidRequiredAddress(params.address);
31
+ if (!!query.chainId)
32
+ throwOnUnsupportedChainId(query.chainId);
32
33
  },
33
34
  detail: { hide: true },
34
35
  })
@@ -8,6 +8,9 @@ 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 OptionalChainIdDto: import("@sinclair/typebox").TObject<{
12
+ chainId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
13
+ }>;
11
14
  export declare const UserDto: import("@sinclair/typebox").TObject<{
12
15
  address: import("@sinclair/typebox").TString;
13
16
  tags: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
@@ -23,4 +26,5 @@ export declare const UpdateUserTagsDto: import("@sinclair/typebox").TObject<{
23
26
  }>;
24
27
  export type UserUniqueModel = typeof UserUniqueDto.static;
25
28
  export type UserModel = typeof UserDto.static;
29
+ export type OptionalChainIdModel = typeof OptionalChainIdDto.static;
26
30
  export type GetManyUserModel = typeof GetManyUserQuery.static;
@@ -3,6 +3,9 @@ import { t } from "elysia";
3
3
  export const UserUniqueDto = t.Object({
4
4
  address: t.String(),
5
5
  });
6
+ export const OptionalChainIdDto = t.Object({
7
+ chainId: t.Optional(t.Numeric()),
8
+ });
6
9
  export const UserDto = t.Object({
7
10
  address: t.String(),
8
11
  tags: t.Array(t.String()),
@@ -1637,13 +1637,15 @@ 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
1644
  address: string;
1645
1645
  };
1646
- query: unknown;
1646
+ query: {
1647
+ chainId?: number | undefined;
1648
+ };
1647
1649
  headers: unknown;
1648
1650
  response: {
1649
1651
  200: (Omit<{
@@ -1640,13 +1640,15 @@ 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
1647
  address: string;
1648
1648
  };
1649
- query: unknown;
1649
+ query: {
1650
+ chainId?: number | undefined;
1651
+ };
1650
1652
  headers: unknown;
1651
1653
  response: {
1652
1654
  200: (Omit<{
@@ -1631,13 +1631,15 @@ 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
1638
  address: string;
1639
1639
  };
1640
- query: unknown;
1640
+ query: {
1641
+ chainId?: number | undefined;
1642
+ };
1641
1643
  headers: unknown;
1642
1644
  response: {
1643
1645
  200: (Omit<{
@@ -1636,13 +1636,15 @@ 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
1643
  address: string;
1644
1644
  };
1645
- query: unknown;
1645
+ query: {
1646
+ chainId?: number | undefined;
1647
+ };
1646
1648
  headers: unknown;
1647
1649
  response: {
1648
1650
  200: (Omit<{
@@ -1654,13 +1654,15 @@ 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
1661
  address: string;
1662
1662
  };
1663
- query: unknown;
1663
+ query: {
1664
+ chainId?: number | undefined;
1665
+ };
1664
1666
  headers: unknown;
1665
1667
  response: {
1666
1668
  200: (Omit<{
@@ -1655,13 +1655,15 @@ 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
1662
  address: string;
1663
1663
  };
1664
- query: unknown;
1664
+ query: {
1665
+ chainId?: number | undefined;
1666
+ };
1665
1667
  headers: unknown;
1666
1668
  response: {
1667
1669
  200: (Omit<{
@@ -1637,13 +1637,15 @@ 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
1644
  address: string;
1645
1645
  };
1646
- query: unknown;
1646
+ query: {
1647
+ chainId?: number | undefined;
1648
+ };
1647
1649
  headers: unknown;
1648
1650
  response: {
1649
1651
  200: (Omit<{
@@ -1638,13 +1638,15 @@ 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
1645
  address: string;
1646
1646
  };
1647
- query: unknown;
1647
+ query: {
1648
+ chainId?: number | undefined;
1649
+ };
1648
1650
  headers: unknown;
1649
1651
  response: {
1650
1652
  200: (Omit<{
@@ -1640,13 +1640,15 @@ 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
1647
  address: string;
1648
1648
  };
1649
- query: unknown;
1649
+ query: {
1650
+ chainId?: number | undefined;
1651
+ };
1650
1652
  headers: unknown;
1651
1653
  response: {
1652
1654
  200: (Omit<{