@merkl/api 0.20.111 → 0.20.113

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.
@@ -3162,6 +3162,17 @@ declare const eden: {
3162
3162
  })[];
3163
3163
  }>>;
3164
3164
  };
3165
+ terms: {
3166
+ get: (options: {
3167
+ headers?: Record<string, unknown> | undefined;
3168
+ query: {
3169
+ chainId: number;
3170
+ };
3171
+ fetch?: RequestInit | undefined;
3172
+ }) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
3173
+ 200: boolean;
3174
+ }>>;
3175
+ };
3165
3176
  tags: {
3166
3177
  patch: (body: {
3167
3178
  tags: string[];
@@ -8887,6 +8898,26 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
8887
8898
  };
8888
8899
  };
8889
8900
  };
8901
+ } & {
8902
+ users: {
8903
+ ":address": {
8904
+ terms: {
8905
+ get: {
8906
+ body: unknown;
8907
+ params: {
8908
+ address: string;
8909
+ };
8910
+ query: {
8911
+ chainId: number;
8912
+ };
8913
+ headers: unknown;
8914
+ response: {
8915
+ 200: boolean;
8916
+ };
8917
+ };
8918
+ };
8919
+ };
8920
+ };
8890
8921
  } & {
8891
8922
  users: {
8892
8923
  ":address": {
@@ -14289,6 +14320,17 @@ export declare const MerklApi: (domain: string | import("elysia").default<"", fa
14289
14320
  })[];
14290
14321
  }>>;
14291
14322
  };
14323
+ terms: {
14324
+ get: (options: {
14325
+ headers?: Record<string, unknown> | undefined;
14326
+ query: {
14327
+ chainId: number;
14328
+ };
14329
+ fetch?: RequestInit | undefined;
14330
+ }) => Promise<import("@elysiajs/eden").Treaty.TreatyResponse<{
14331
+ 200: boolean;
14332
+ }>>;
14333
+ };
14292
14334
  tags: {
14293
14335
  patch: (body: {
14294
14336
  tags: string[];
@@ -3932,6 +3932,26 @@ declare const app: Elysia<"", false, {
3932
3932
  };
3933
3933
  };
3934
3934
  };
3935
+ } & {
3936
+ users: {
3937
+ ":address": {
3938
+ terms: {
3939
+ get: {
3940
+ body: unknown;
3941
+ params: {
3942
+ address: string;
3943
+ };
3944
+ query: {
3945
+ chainId: number;
3946
+ };
3947
+ headers: unknown;
3948
+ response: {
3949
+ 200: boolean;
3950
+ };
3951
+ };
3952
+ };
3953
+ };
3954
+ };
3935
3955
  } & {
3936
3956
  users: {
3937
3957
  ":address": {
@@ -3802,6 +3802,26 @@ export declare const v4: Elysia<"/v4", false, {
3802
3802
  };
3803
3803
  };
3804
3804
  };
3805
+ } & {
3806
+ users: {
3807
+ ":address": {
3808
+ terms: {
3809
+ get: {
3810
+ body: unknown;
3811
+ params: {
3812
+ address: string;
3813
+ };
3814
+ query: {
3815
+ chainId: number;
3816
+ };
3817
+ headers: unknown;
3818
+ response: {
3819
+ 200: boolean;
3820
+ };
3821
+ };
3822
+ };
3823
+ };
3824
+ };
3805
3825
  } & {
3806
3826
  users: {
3807
3827
  ":address": {
@@ -379,6 +379,26 @@ export declare const UserController: Elysia<"/users", false, {
379
379
  };
380
380
  };
381
381
  };
382
+ } & {
383
+ users: {
384
+ ":address": {
385
+ terms: {
386
+ get: {
387
+ body: unknown;
388
+ params: {
389
+ address: string;
390
+ };
391
+ query: {
392
+ chainId: number;
393
+ };
394
+ headers: unknown;
395
+ response: {
396
+ 200: boolean;
397
+ };
398
+ };
399
+ };
400
+ };
401
+ };
382
402
  } & {
383
403
  users: {
384
404
  ":address": {
@@ -3,7 +3,7 @@ import { throwOnInvalidRequiredAddress, throwOnUnsupportedChainId } from "@/util
3
3
  import { Elysia, t } from "elysia";
4
4
  import { CreatorService } from "../creator";
5
5
  import { RewardService } from "../reward";
6
- import { GetManyUserQuery, OptionalChainIdDto, UpdateUserTagsDto, UserDto, UserRewardRouteDto, UserRewardsResourceDto, UserUniqueDto, } from "./user.model";
6
+ import { CheckTerms, GetManyUserQuery, OptionalChainIdDto, UpdateUserTagsDto, UserDto, UserRewardRouteDto, UserRewardsResourceDto, 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"] } })
@@ -78,6 +78,13 @@ export const UserController = new Elysia({ prefix: "/users", detail: { tags: ["U
78
78
  headers: AuthorizationHeadersDto,
79
79
  beforeHandle: BackOfficeGuard,
80
80
  detail: { hide: true },
81
+ })
82
+ // ─── Check if user has signed terms ─────────────────────────────────
83
+ .get("/:address/terms", async ({ query, params }) => await UserService.checkTerms(params?.address, query?.chainId), {
84
+ query: CheckTerms,
85
+ detail: {
86
+ description: "Check if a user address has signed Merkl's terms.",
87
+ },
81
88
  })
82
89
  // ─── Update User's Tags ──────────────────────────────────────────────
83
90
  .patch("/:address/tags", async ({ params, body }) => UserService.updateTags(params.address, body.tags), {
@@ -63,6 +63,9 @@ export declare const GetManyUserQuery: import("@sinclair/typebox").TObject<{
63
63
  page: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
64
64
  items: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
65
65
  }>;
66
+ export declare const CheckTerms: import("@sinclair/typebox").TObject<{
67
+ chainId: import("@sinclair/typebox").TNumber;
68
+ }>;
66
69
  export declare const UpdateUserTagsDto: import("@sinclair/typebox").TObject<{
67
70
  tags: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>;
68
71
  }>;
@@ -64,6 +64,9 @@ export const GetManyUserQuery = t.Object({
64
64
  page: t.Optional(t.Number()),
65
65
  items: t.Optional(t.Number()),
66
66
  });
67
+ export const CheckTerms = t.Object({
68
+ chainId: t.Numeric(),
69
+ });
67
70
  export const UpdateUserTagsDto = t.Object({
68
71
  tags: t.Array(t.String()),
69
72
  });
@@ -26,6 +26,7 @@ export declare abstract class UserService {
26
26
  address: string;
27
27
  creatorId: string | null;
28
28
  }>;
29
+ static checkTerms(userAddress: string, chainId: number): Promise<boolean>;
29
30
  static syncTags(): Promise<void>;
30
31
  static syncOpportunityTags(): Promise<void>;
31
32
  }
@@ -1,5 +1,6 @@
1
1
  import { log } from "@/utils/logger";
2
2
  import { engineDbClient } from "@db";
3
+ import { ChainInteractionService, DistributionCreatorInterface, registry } from "@sdk";
3
4
  import { OpportunityService } from "../opportunity";
4
5
  import { UserRepository } from "./user.repository";
5
6
  // ─── Users Services ──────────────────────────────────────────────────────────
@@ -25,6 +26,37 @@ export class UserService {
25
26
  }
26
27
  return await UserRepository.updateTags(user, tags);
27
28
  }
29
+ static async checkTerms(userAddress, chainId) {
30
+ const distributorAddress = registry(chainId)?.Merkl?.DistributionCreator;
31
+ if (!distributorAddress)
32
+ throw new Error(`Distributor address not found for chainId ${chainId}`);
33
+ const calls = [
34
+ {
35
+ callData: DistributionCreatorInterface.encodeFunctionData("userSignatureWhitelist", [userAddress]),
36
+ target: distributorAddress,
37
+ allowFailure: false,
38
+ },
39
+ {
40
+ callData: DistributionCreatorInterface.encodeFunctionData("userSignatures", [userAddress]),
41
+ target: distributorAddress,
42
+ allowFailure: false,
43
+ },
44
+ {
45
+ callData: DistributionCreatorInterface.encodeFunctionData("messageHash"),
46
+ target: distributorAddress,
47
+ allowFailure: false,
48
+ },
49
+ ];
50
+ const decoders = (r) => [
51
+ DistributionCreatorInterface.decodeFunctionResult("userSignatureWhitelist", r[0].returnData)[0].toString(),
52
+ DistributionCreatorInterface.decodeFunctionResult("userSignatures", r[1].returnData)[0].toString(),
53
+ DistributionCreatorInterface.decodeFunctionResult("messageHash", r[2].returnData)[0].toString(),
54
+ ];
55
+ const result = await ChainInteractionService(chainId).fetchAndDecodeMultiple(calls, decoders);
56
+ const [signatureWhitelist, userSignature, messageHash] = result;
57
+ const hasNotSigned = signatureWhitelist === "0" && userSignature !== messageHash;
58
+ return !hasNotSigned;
59
+ }
28
60
  static async syncTags() {
29
61
  // 1 - engine -> api db
30
62
  const creatorTags = await engineDbClient.campaignCreators.findMany();