@merkl/api 0.10.186 → 0.10.188

Sign up to get free protection for your applications and to get access to all the features.
@@ -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<{