@merkl/api 0.18.14 → 0.19.1

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.
Files changed (68) hide show
  1. package/dist/database/api/.generated/drizzle/schema.d.ts +2 -2
  2. package/dist/database/api/.generated/drizzle/schema.js +2 -2
  3. package/dist/database/api/.generated/drizzle/schema.ts +2 -2
  4. package/dist/database/api/.generated/edge.js +3 -3
  5. package/dist/database/api/.generated/index.d.ts +12 -12
  6. package/dist/database/api/.generated/index.js +3 -3
  7. package/dist/database/api/.generated/package.json +1 -1
  8. package/dist/database/api/.generated/schema.prisma +2 -2
  9. package/dist/src/backgroundJobs/index.js +0 -4
  10. package/dist/src/eden/index.d.ts +35 -30
  11. package/dist/src/factories/opportunityMetadata/implementations/EventBased.d.ts +1 -1
  12. package/dist/src/index.d.ts +7 -6
  13. package/dist/src/jobs/{etl/dynamic-data.js → dynamic-data.js} +1 -1
  14. package/dist/src/jobs/set-dungeon-keeper.js +82 -0
  15. package/dist/src/jobs/update-dynamic-data.d.ts +1 -0
  16. package/dist/src/jobs/update-uniswap-v4-pools.d.ts +1 -0
  17. package/dist/src/jobs/update-uniswap-v4-pools.js +14 -0
  18. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/helpers/hardcoded.js +2 -4
  19. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/HourglassProcessor.d.ts +1 -1
  20. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/HourglassProcessor.js +3 -0
  21. package/dist/src/libs/campaigns/campaignTypes/ERC20SubTypes/implementations/SpliceProcessor.js +1 -0
  22. package/dist/src/libs/campaigns/campaignTypes/SILODynamicData.js +2 -2
  23. package/dist/src/libs/campaigns/utils/fetchAmbientInfo.d.ts +2 -2
  24. package/dist/src/libs/campaigns/utils/getDolomiteMarkets.js +1 -1
  25. package/dist/src/libs/positions/dolomite/index.js +2 -0
  26. package/dist/src/modules/v4/opportunity/opportunity.controller.d.ts +5 -5
  27. package/dist/src/modules/v4/programPayload/programPayload.repository.d.ts +52 -1
  28. package/dist/src/modules/v4/programPayload/programPayload.repository.js +48 -13
  29. package/dist/src/modules/v4/programPayload/programPayload.service.d.ts +5 -4
  30. package/dist/src/modules/v4/programPayload/programPayload.service.js +24 -10
  31. package/dist/src/modules/v4/router.d.ts +7 -6
  32. package/dist/src/modules/v4/status/status.repository.js +1 -0
  33. package/dist/src/modules/v4/token/token.controller.d.ts +2 -1
  34. package/dist/src/modules/v4/token/token.repository.d.ts +15 -1
  35. package/dist/src/modules/v4/token/token.service.d.ts +19 -5
  36. package/dist/src/modules/v4/token/token.service.js +7 -10
  37. package/dist/src/modules/v4/uniswapV4/uniswapV4.controller.d.ts +2 -2
  38. package/dist/src/modules/v4/uniswapV4/uniswapV4.model.d.ts +9 -0
  39. package/dist/src/modules/v4/uniswapV4/uniswapV4.repository.d.ts +11 -0
  40. package/dist/src/modules/v4/uniswapV4/uniswapV4.repository.js +10 -0
  41. package/dist/src/modules/v4/uniswapV4/uniswapV4.service.d.ts +4 -2
  42. package/dist/src/modules/v4/uniswapV4/uniswapV4.service.js +175 -1
  43. package/dist/src/utils/prices/services/coinGeckoService.js +3 -3
  44. package/dist/src/utils/prices/services/defillamaService.js +3 -3
  45. package/dist/src/utils/prices/services/erc4626Service.js +6 -4
  46. package/dist/tsconfig.package.tsbuildinfo +1 -1
  47. package/package.json +11 -8
  48. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.controller.d.ts +0 -34
  49. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.controller.js +0 -8
  50. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.model.d.ts +0 -0
  51. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.model.js +0 -1
  52. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.repository.d.ts +0 -5
  53. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.repository.js +0 -71
  54. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.service.d.ts +0 -3
  55. package/dist/src/modules/v4/dungeonKeeper/dungeonKeeper.service.js +0 -15
  56. /package/dist/src/jobs/{etl/dynamic-data.d.ts → dynamic-data.d.ts} +0 -0
  57. /package/dist/src/jobs/{etl/pendings.d.ts → pendings.d.ts} +0 -0
  58. /package/dist/src/jobs/{etl/pendings.js → pendings.js} +0 -0
  59. /package/dist/src/jobs/{etl/prices.d.ts → prices.d.ts} +0 -0
  60. /package/dist/src/jobs/{etl/prices.js → prices.js} +0 -0
  61. /package/dist/src/jobs/{etl/reward-breakdowns.d.ts → reward-breakdowns.d.ts} +0 -0
  62. /package/dist/src/jobs/{etl/reward-breakdowns.js → reward-breakdowns.js} +0 -0
  63. /package/dist/src/jobs/{etl/rewards.d.ts → rewards.d.ts} +0 -0
  64. /package/dist/src/jobs/{etl/rewards.js → rewards.js} +0 -0
  65. /package/dist/src/jobs/{etl/update-dynamic-data.d.ts → set-dungeon-keeper.d.ts} +0 -0
  66. /package/dist/src/jobs/{etl/update-dynamic-data.js → update-dynamic-data.js} +0 -0
  67. /package/dist/src/jobs/{etl/update-euler-vaults.d.ts → update-euler-vaults.d.ts} +0 -0
  68. /package/dist/src/jobs/{etl/update-euler-vaults.js → update-euler-vaults.js} +0 -0
@@ -122,9 +122,9 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
122
122
  chainId?: string | undefined;
123
123
  mainProtocolId?: string | undefined;
124
124
  campaigns?: boolean | undefined;
125
+ test?: boolean | undefined;
125
126
  rewardTokenSymbol?: string | undefined;
126
127
  order?: string | undefined;
127
- test?: boolean | undefined;
128
128
  minimumTvl?: number | undefined;
129
129
  };
130
130
  headers: unknown;
@@ -315,9 +315,9 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
315
315
  chainId?: string | undefined;
316
316
  mainProtocolId?: string | undefined;
317
317
  campaigns?: boolean | undefined;
318
+ test?: boolean | undefined;
318
319
  rewardTokenSymbol?: string | undefined;
319
320
  order?: string | undefined;
320
- test?: boolean | undefined;
321
321
  minimumTvl?: number | undefined;
322
322
  };
323
323
  headers: unknown;
@@ -803,9 +803,9 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
803
803
  chainId?: string | undefined;
804
804
  mainProtocolId?: string | undefined;
805
805
  campaigns?: boolean | undefined;
806
+ test?: boolean | undefined;
806
807
  rewardTokenSymbol?: string | undefined;
807
808
  order?: string | undefined;
808
- test?: boolean | undefined;
809
809
  minimumTvl?: number | undefined;
810
810
  };
811
811
  headers: unknown;
@@ -843,9 +843,9 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
843
843
  chainId?: string | undefined;
844
844
  mainProtocolId?: string | undefined;
845
845
  campaigns?: boolean | undefined;
846
+ test?: boolean | undefined;
846
847
  rewardTokenSymbol?: string | undefined;
847
848
  order?: string | undefined;
848
- test?: boolean | undefined;
849
849
  minimumTvl?: number | undefined;
850
850
  };
851
851
  headers: unknown;
@@ -884,9 +884,9 @@ export declare const OpportunityController: Elysia<"/opportunities", false, {
884
884
  chainId?: string | undefined;
885
885
  mainProtocolId?: string | undefined;
886
886
  campaigns?: boolean | undefined;
887
+ test?: boolean | undefined;
887
888
  rewardTokenSymbol?: string | undefined;
888
889
  order?: string | undefined;
889
- test?: boolean | undefined;
890
890
  minimumTvl?: number | undefined;
891
891
  };
892
892
  headers: unknown;
@@ -15,7 +15,9 @@ export declare enum program {
15
15
  export declare enum anglesCampaigns {
16
16
  Angles_supply_in_angles_liquid = "0x15E96CDecA34B9DE1B31586c1206206aDb92E69D",
17
17
  hold_anS = "0x0C4E186Eae8aCAA7F7de1315D5AD174BE39Ec987",
18
- hold_wANS = "0xfA85Fe5A8F5560e9039C04f2b0a90dE1415aBD70"
18
+ hold_wANS = "0xfA85Fe5A8F5560e9039C04f2b0a90dE1415aBD70",
19
+ pendle_YT = "0x081424EC3F4BFe0ad829297D6Cb73997656F56ac",
20
+ pendle_PT = "0x9700C4C218237550EAd3a78022d43215A717e5e7"
19
21
  }
20
22
  export declare enum etherlinkCampaigns {
21
23
  Superlend_Supply_WBTC_Etherlink = "Superlend Supply WBTC Etherlink 0xfCA0802cb10b3b134a91e07f03965f63eF4B23eA",
@@ -26,6 +28,7 @@ export declare enum etherlinkCampaigns {
26
28
  Iguana_WETH_WXTZ = "Iguana WETH/WXTZ Etherlink 0x478F067b0Ed73d120BBcd8c6f4f33438FC483912",
27
29
  Iguana_USDC_USDT = "Iguana USDC/USDT Etherlink 0x86456e2E2A203Da82E61ed34eF4137Fbe545f0DC",
28
30
  Iguana_XTZ_USDC = "Iguana XTZ/USDT Etherlink 0x508060A01f11d6a2Eb774B55aEba95931265E0cc",
31
+ Iguana_WBTC_XTZ = "Iguana WBTC/XTZ Etherlink 0x8930e315fa6D704A94bE6E14DaD66f6d66FfF7DF",
29
32
  Hanji_HJLP = "Hanji HJLP Etherlink 0x1cd88fBD530281Ad6c639E2B897c4E239003A930",
30
33
  Uranium_Hold_xU308_Etherlink = "Uranium Hold xU308 Etherlink 0x79052Ab3C166D4899a1e0DD033aC3b379AF0B1fD",
31
34
  referral_test = "referral test Etherlink 0x0",
@@ -414,6 +417,26 @@ declare const AnglesInterfaceCampaigns: {
414
417
  url: string;
415
418
  forwarders: never[];
416
419
  };
420
+ "0x9700C4C218237550EAd3a78022d43215A717e5e7": {
421
+ campaignType: any;
422
+ computeChainId: any;
423
+ hooks: never[];
424
+ targetToken: string;
425
+ whitelist: never[];
426
+ blacklist: never[];
427
+ url: string;
428
+ forwarders: never[];
429
+ };
430
+ "0x081424EC3F4BFe0ad829297D6Cb73997656F56ac": {
431
+ campaignType: any;
432
+ computeChainId: any;
433
+ hooks: never[];
434
+ targetToken: string;
435
+ whitelist: never[];
436
+ blacklist: never[];
437
+ url: string;
438
+ forwarders: never[];
439
+ };
417
440
  "0x0C4E186Eae8aCAA7F7de1315D5AD174BE39Ec987": {
418
441
  campaignType: any;
419
442
  computeChainId: any;
@@ -694,6 +717,34 @@ declare const EtherlinkInterfaceCampaigns: {
694
717
  weightToken0: number;
695
718
  weightToken1: number;
696
719
  };
720
+ "Iguana WBTC/XTZ Etherlink 0x8930e315fa6D704A94bE6E14DaD66f6d66FfF7DF": {
721
+ campaignType: any;
722
+ computeChainId: any;
723
+ hooks: {
724
+ hookType: any;
725
+ key: string;
726
+ chainId: any;
727
+ contractAddress: string;
728
+ contractState: any;
729
+ boostForReferrer: any;
730
+ valueForBoostForReferrer: number;
731
+ boostForInvited: any;
732
+ valueForBoostForInvited: number;
733
+ defaultBoost: any;
734
+ maximumBoostReferrer: number;
735
+ maximumBoostInvited: number;
736
+ cumulativeBoost: boolean;
737
+ }[];
738
+ poolAddress: string;
739
+ whitelist: never[];
740
+ blacklist: string[];
741
+ url: string;
742
+ forwarders: never[];
743
+ isOutOfRangeIncentivized: boolean;
744
+ weightFees: number;
745
+ weightToken0: number;
746
+ weightToken1: number;
747
+ };
697
748
  "referral test Etherlink 0x0": {
698
749
  campaignType: any;
699
750
  computeChainId: any;
@@ -19,8 +19,8 @@ export var anglesCampaigns;
19
19
  anglesCampaigns["Angles_supply_in_angles_liquid"] = "0x15E96CDecA34B9DE1B31586c1206206aDb92E69D";
20
20
  anglesCampaigns["hold_anS"] = "0x0C4E186Eae8aCAA7F7de1315D5AD174BE39Ec987";
21
21
  anglesCampaigns["hold_wANS"] = "0xfA85Fe5A8F5560e9039C04f2b0a90dE1415aBD70";
22
- // pendle_lp =
23
- // pendle PT
22
+ anglesCampaigns["pendle_YT"] = "0x081424EC3F4BFe0ad829297D6Cb73997656F56ac";
23
+ anglesCampaigns["pendle_PT"] = "0x9700C4C218237550EAd3a78022d43215A717e5e7";
24
24
  })(anglesCampaigns || (anglesCampaigns = {}));
25
25
  export var etherlinkCampaigns;
26
26
  (function (etherlinkCampaigns) {
@@ -32,6 +32,7 @@ export var etherlinkCampaigns;
32
32
  etherlinkCampaigns["Iguana_WETH_WXTZ"] = "Iguana WETH/WXTZ Etherlink 0x478F067b0Ed73d120BBcd8c6f4f33438FC483912";
33
33
  etherlinkCampaigns["Iguana_USDC_USDT"] = "Iguana USDC/USDT Etherlink 0x86456e2E2A203Da82E61ed34eF4137Fbe545f0DC";
34
34
  etherlinkCampaigns["Iguana_XTZ_USDC"] = "Iguana XTZ/USDT Etherlink 0x508060A01f11d6a2Eb774B55aEba95931265E0cc";
35
+ etherlinkCampaigns["Iguana_WBTC_XTZ"] = "Iguana WBTC/XTZ Etherlink 0x8930e315fa6D704A94bE6E14DaD66f6d66FfF7DF";
35
36
  etherlinkCampaigns["Hanji_HJLP"] = "Hanji HJLP Etherlink 0x1cd88fBD530281Ad6c639E2B897c4E239003A930";
36
37
  etherlinkCampaigns["Uranium_Hold_xU308_Etherlink"] = "Uranium Hold xU308 Etherlink 0x79052Ab3C166D4899a1e0DD033aC3b379AF0B1fD";
37
38
  etherlinkCampaigns["referral_test"] = "referral test Etherlink 0x0";
@@ -449,6 +450,26 @@ const AnglesInterfaceCampaigns = {
449
450
  url: "https://sonicscan.org/token/0x15E96CDecA34B9DE1B31586c1206206aDb92E69D#readContract",
450
451
  forwarders: [],
451
452
  },
453
+ [anglesCampaigns.pendle_PT]: {
454
+ campaignType: Campaign.ERC20_FIX_APR,
455
+ computeChainId: ChainId.SONIC,
456
+ hooks: [],
457
+ targetToken: "0x9700C4C218237550EAd3a78022d43215A717e5e7",
458
+ whitelist: [],
459
+ blacklist: [],
460
+ url: "https://app.pendle.finance/trade/pools/0x9700C4C218237550EAd3a78022d43215A717e5e7/zap/in?chain=sonic",
461
+ forwarders: [],
462
+ },
463
+ [anglesCampaigns.pendle_YT]: {
464
+ campaignType: Campaign.ERC20_FIX_APR,
465
+ computeChainId: ChainId.SONIC,
466
+ hooks: [],
467
+ targetToken: "0x081424EC3F4BFe0ad829297D6Cb73997656F56ac",
468
+ whitelist: [],
469
+ blacklist: [],
470
+ url: "https://app.pendle.finance/trade/pools/0x081424EC3F4BFe0ad829297D6Cb73997656F56ac/zap/in?chain=sonic",
471
+ forwarders: [],
472
+ },
452
473
  [anglesCampaigns.hold_anS]: {
453
474
  campaignType: Campaign.ERC20REBASEFIXAPR,
454
475
  computeChainId: ChainId.SONIC,
@@ -557,9 +578,9 @@ const EtherlinkInterfaceCampaigns = {
557
578
  url: "https://www.iguanadex.com/info/v3/pairs/0x478f067b0ed73d120bbcd8c6f4f33438fc483912?chain=etherlink",
558
579
  forwarders: [],
559
580
  isOutOfRangeIncentivized: false,
560
- weightFees: 2000,
561
- weightToken0: 4000,
562
- weightToken1: 4000,
581
+ weightFees: 6000,
582
+ weightToken0: 2000,
583
+ weightToken1: 2000,
563
584
  },
564
585
  [etherlinkCampaigns.Iguana_USDC_USDT]: {
565
586
  campaignType: Campaign.CLAMM,
@@ -571,8 +592,8 @@ const EtherlinkInterfaceCampaigns = {
571
592
  url: "https://www.iguanadex.com/info/v3/pairs/0x86456e2e2a203da82e61ed34ef4137fbe545f0dc?chain=etherlink",
572
593
  forwarders: [],
573
594
  isOutOfRangeIncentivized: false,
574
- weightFees: 2000,
575
- weightToken0: 4000,
595
+ weightFees: 6000,
596
+ weightToken0: 0,
576
597
  weightToken1: 4000,
577
598
  },
578
599
  [etherlinkCampaigns.Iguana_XTZ_USDC]: {
@@ -585,9 +606,23 @@ const EtherlinkInterfaceCampaigns = {
585
606
  url: "https://www.iguanadex.com/info/v3/pairs/0x508060A01f11d6a2Eb774B55aEba95931265E0cc?chain=etherlink",
586
607
  forwarders: [],
587
608
  isOutOfRangeIncentivized: false,
588
- weightFees: 2000,
589
- weightToken0: 4000,
590
- weightToken1: 4000,
609
+ weightFees: 6000,
610
+ weightToken0: 2000,
611
+ weightToken1: 2000,
612
+ },
613
+ [etherlinkCampaigns.Iguana_WBTC_XTZ]: {
614
+ campaignType: Campaign.CLAMM,
615
+ computeChainId: ChainId.ETHERLINK,
616
+ hooks: [etherlinkReferralProgram],
617
+ poolAddress: "0x8930e315fa6D704A94bE6E14DaD66f6d66FfF7DF",
618
+ whitelist: [],
619
+ blacklist: blacklistEtherlink,
620
+ url: "https://www.iguanadex.com/info/v3/pairs/0x8930e315fa6D704A94bE6E14DaD66f6d66FfF7DF?chain=etherlink",
621
+ forwarders: [],
622
+ isOutOfRangeIncentivized: false,
623
+ weightFees: 6000,
624
+ weightToken0: 2000,
625
+ weightToken1: 2000,
591
626
  },
592
627
  [etherlinkCampaigns.referral_test]: {
593
628
  campaignType: Campaign.ERC20,
@@ -5001,11 +5036,11 @@ const PufferInterfaceCampaigns = {
5001
5036
  url: "https://app.zircuit.com/stake",
5002
5037
  forwarders: [
5003
5038
  {
5004
- forwarderType: Forwarder.INCOMING_TRANSFERS,
5039
+ forwarderType: Forwarder.VAULT,
5005
5040
  priority: 0,
5006
5041
  sender: "0xF047ab4c75cebf0eB9ed34Ae2c186f3611aEAfa6",
5007
- token: "0xD9A442856C234a39a81a089C06451EBAa4306a72", // Token to use transfer of. If priority is 0, it is the target token
5008
- senderType: StandardType.ERC20,
5042
+ balanceCallType: BalanceCallType.ZtakingPool,
5043
+ callDataKey: "0xD9A442856C234a39a81a089C06451EBAa4306a72",
5009
5044
  },
5010
5045
  ],
5011
5046
  },
@@ -16,10 +16,11 @@ export declare class ProgramPayloadService {
16
16
  safePayload: safePayload;
17
17
  nonEncodedConfig: any;
18
18
  }>;
19
- static createSafePayloadForCampaign(args: CampaignParametersStruct, distributionChainId: ChainId, rewardToken: string, distributionCreator: string, withApproval?: boolean): [approvalTransaction, createCampaignTransaction] | [createCampaignTransaction];
19
+ static checkMinimumAmount(rewardToken: string, args: CampaignParametersStruct, distributionChainId: ChainId): Promise<boolean>;
20
+ static createSafePayloadForCampaign(args: CampaignParametersStruct, distributionChainId: ChainId, rewardToken: string, distributionCreator: string, withApproval?: boolean): Promise<[approvalTransaction, createCampaignTransaction] | [createCampaignTransaction]>;
20
21
  static initiateSafePayload(distributionChainId: ChainId, distributionCreator: string, rewardToken: string, approvalAmount?: string): safePayload;
21
- static buildPayload(query: CampaignPayloadInputModel, initialCampaignPayload?: safePayload | null, totalAmount?: string): safePayload;
22
- static buildProgramPayload(query: ProgramPayloadInputModel): safePayload | null;
23
- static buildProgramPayloadWithAmounts(query: ProgramPayloadInputModel, body: CampaignAmountsInputModel): safePayload | null;
22
+ static buildPayload(query: CampaignPayloadInputModel, initialCampaignPayload?: safePayload | null, totalAmount?: string): Promise<safePayload>;
23
+ static buildProgramPayload(query: ProgramPayloadInputModel): Promise<safePayload | null>;
24
+ static buildProgramPayloadWithAmounts(query: ProgramPayloadInputModel, body: CampaignAmountsInputModel): Promise<safePayload | null>;
24
25
  static buildConfigFromCampaignData(body: CampaignDataDtoModel): Promise<any>;
25
26
  }
@@ -1,5 +1,6 @@
1
1
  import { CampaignTypeConfigResourceMapping, ChainId, NULL_ADDRESS, NULL_ROOT, buildCampaignPayload, encodeForwarderData, parseCampaign, registry, } from "@sdk";
2
2
  import _ from "lodash";
3
+ import { TokenService } from "../token/token.service";
3
4
  import { safeTemplate, } from "./programPayload.model";
4
5
  import { MerklInterfaceCampaigns } from "./programPayload.repository";
5
6
  export class ProgramPayloadService {
@@ -70,17 +71,30 @@ export class ProgramPayloadService {
70
71
  // Small hack to avoid the need to parse the config again
71
72
  const args = buildCampaignPayload(parsedConfig, distributionChainId).args;
72
73
  const safePayload = ProgramPayloadService.initiateSafePayload(distributionChainId, distributionCreator, rewardToken);
73
- const transactions = ProgramPayloadService.createSafePayloadForCampaign(args, distributionChainId, rewardToken, distributionCreator ?? NULL_ADDRESS);
74
+ const transactions = await ProgramPayloadService.createSafePayloadForCampaign(args, distributionChainId, rewardToken, distributionCreator ?? NULL_ADDRESS);
74
75
  safePayload.transactions.push(...transactions);
75
76
  if (debug) {
76
77
  return { safePayload, nonEncodedConfig };
77
78
  }
78
79
  return safePayload;
79
80
  }
80
- static createSafePayloadForCampaign(args, distributionChainId, rewardToken, distributionCreator, withApproval = true) {
81
+ static async checkMinimumAmount(rewardToken, args, distributionChainId) {
82
+ const tokenList = await TokenService.getValidRewardTokens(distributionChainId);
83
+ const minimumAmountPerHour = tokenList.find(token => token.address.toLowerCase() === rewardToken.toLowerCase())?.minimumAmountPerHour;
84
+ if (!minimumAmountPerHour) {
85
+ throw new Error("Token not found");
86
+ }
87
+ const tokenAmount = BigInt(args?.amount.toString());
88
+ const numberOfHours = BigInt(args?.duration.toString()) / 3600n;
89
+ return tokenAmount / numberOfHours >= BigInt(minimumAmountPerHour);
90
+ }
91
+ static async createSafePayloadForCampaign(args, distributionChainId, rewardToken, distributionCreator, withApproval = true) {
81
92
  const safePayload = _.cloneDeep(safeTemplate);
82
93
  safePayload.chainId = distributionChainId.toString();
83
94
  safePayload.createdAt = Math.floor(Date.now() / 1000);
95
+ if (!(await ProgramPayloadService.checkMinimumAmount(rewardToken, args, distributionChainId))) {
96
+ throw new Error("Amount is less than minimum");
97
+ }
84
98
  safePayload.transactions[0].to = rewardToken;
85
99
  safePayload.transactions[0].contractInputsValues = {
86
100
  amount: args?.amount.toString(),
@@ -132,25 +146,25 @@ export class ProgramPayloadService {
132
146
  }
133
147
  return safePayload;
134
148
  }
135
- static buildPayload(query, initialCampaignPayload = null, totalAmount = "0") {
149
+ static async buildPayload(query, initialCampaignPayload = null, totalAmount = "0") {
136
150
  const withApproval = Boolean(totalAmount === "0");
137
151
  const rewardToken = query.rewardToken;
138
152
  const distributionChainId = query.distributionChainId ? query.distributionChainId : ChainId.MAINNET;
139
153
  const registryInitialized = registry(distributionChainId);
140
154
  const distributionCreator = registryInitialized?.Merkl?.DistributionCreator ?? NULL_ADDRESS;
141
- function generatePayloadFile(query, withApproval = true) {
155
+ async function generatePayloadFile(query, withApproval = true) {
142
156
  const args = buildCampaignPayload(ProgramPayloadService.buildConfig(query), distributionChainId).args;
143
- const safePayload = ProgramPayloadService.createSafePayloadForCampaign(args, distributionChainId, rewardToken, distributionCreator, withApproval);
157
+ const safePayload = await ProgramPayloadService.createSafePayloadForCampaign(args, distributionChainId, rewardToken, distributionCreator, withApproval);
144
158
  return safePayload;
145
159
  }
146
160
  const campaignPayloads = initialCampaignPayload === null
147
161
  ? ProgramPayloadService.initiateSafePayload(distributionChainId, distributionCreator, rewardToken, totalAmount)
148
162
  : initialCampaignPayload;
149
- const transactions = generatePayloadFile(query, withApproval);
163
+ const transactions = await generatePayloadFile(query, withApproval);
150
164
  campaignPayloads.transactions.push(...transactions);
151
165
  return campaignPayloads;
152
166
  }
153
- static buildProgramPayload(query) {
167
+ static async buildProgramPayload(query) {
154
168
  let campaignPayloads = null;
155
169
  query.amount = query.amount ? query.amount : "0";
156
170
  for (const campaign of Object.keys(MerklInterfaceCampaigns[query.program])) {
@@ -159,17 +173,17 @@ export class ProgramPayloadService {
159
173
  campaign,
160
174
  amount: query.amount,
161
175
  };
162
- campaignPayloads = ProgramPayloadService.buildPayload(queryCampaign, campaignPayloads);
176
+ campaignPayloads = await ProgramPayloadService.buildPayload(queryCampaign, campaignPayloads);
163
177
  }
164
178
  return campaignPayloads;
165
179
  }
166
- static buildProgramPayloadWithAmounts(query, body) {
180
+ static async buildProgramPayloadWithAmounts(query, body) {
167
181
  let campaignPayloads = null;
168
182
  const totalAmount = Object.values(body).reduce((sum, amount) => sum + BigInt(amount), 0n);
169
183
  for (const [campaign, amount] of Object.entries(body)) {
170
184
  if (Object.keys(MerklInterfaceCampaigns[query.program]).includes(campaign)) {
171
185
  const queryCampaign = { ...query, campaign, amount: amount };
172
- campaignPayloads = ProgramPayloadService.buildPayload(queryCampaign, campaignPayloads, totalAmount.toString());
186
+ campaignPayloads = await ProgramPayloadService.buildPayload(queryCampaign, campaignPayloads, totalAmount.toString());
173
187
  }
174
188
  else {
175
189
  throw new Error(`Campaign ${campaign} not found`);
@@ -137,9 +137,9 @@ export declare const v4: Elysia<"/v4", false, {
137
137
  chainId?: string | undefined;
138
138
  mainProtocolId?: string | undefined;
139
139
  campaigns?: boolean | undefined;
140
+ test?: boolean | undefined;
140
141
  rewardTokenSymbol?: string | undefined;
141
142
  order?: string | undefined;
142
- test?: boolean | undefined;
143
143
  minimumTvl?: number | undefined;
144
144
  };
145
145
  headers: unknown;
@@ -330,9 +330,9 @@ export declare const v4: Elysia<"/v4", false, {
330
330
  chainId?: string | undefined;
331
331
  mainProtocolId?: string | undefined;
332
332
  campaigns?: boolean | undefined;
333
+ test?: boolean | undefined;
333
334
  rewardTokenSymbol?: string | undefined;
334
335
  order?: string | undefined;
335
- test?: boolean | undefined;
336
336
  minimumTvl?: number | undefined;
337
337
  };
338
338
  headers: unknown;
@@ -818,9 +818,9 @@ export declare const v4: Elysia<"/v4", false, {
818
818
  chainId?: string | undefined;
819
819
  mainProtocolId?: string | undefined;
820
820
  campaigns?: boolean | undefined;
821
+ test?: boolean | undefined;
821
822
  rewardTokenSymbol?: string | undefined;
822
823
  order?: string | undefined;
823
- test?: boolean | undefined;
824
824
  minimumTvl?: number | undefined;
825
825
  };
826
826
  headers: unknown;
@@ -858,9 +858,9 @@ export declare const v4: Elysia<"/v4", false, {
858
858
  chainId?: string | undefined;
859
859
  mainProtocolId?: string | undefined;
860
860
  campaigns?: boolean | undefined;
861
+ test?: boolean | undefined;
861
862
  rewardTokenSymbol?: string | undefined;
862
863
  order?: string | undefined;
863
- test?: boolean | undefined;
864
864
  minimumTvl?: number | undefined;
865
865
  };
866
866
  headers: unknown;
@@ -899,9 +899,9 @@ export declare const v4: Elysia<"/v4", false, {
899
899
  chainId?: string | undefined;
900
900
  mainProtocolId?: string | undefined;
901
901
  campaigns?: boolean | undefined;
902
+ test?: boolean | undefined;
902
903
  rewardTokenSymbol?: string | undefined;
903
904
  order?: string | undefined;
904
- test?: boolean | undefined;
905
905
  minimumTvl?: number | undefined;
906
906
  };
907
907
  headers: unknown;
@@ -1773,11 +1773,12 @@ export declare const v4: Elysia<"/v4", false, {
1773
1773
  address: string;
1774
1774
  chainId: number;
1775
1775
  decimals: number;
1776
+ displaySymbol: string;
1776
1777
  verified: boolean;
1777
1778
  isTest: boolean;
1778
1779
  isPoint: boolean;
1779
1780
  isNative: boolean;
1780
- price?: number | null | undefined;
1781
+ price: number | null;
1781
1782
  } | undefined;
1782
1783
  };
1783
1784
  };
@@ -42,6 +42,7 @@ export class StatusRepository {
42
42
  data: {
43
43
  campaignId: CampaignService.hashId(campaign),
44
44
  computedUntil: startTimestamp,
45
+ processingStarted: startTimestamp,
45
46
  },
46
47
  });
47
48
  }
@@ -224,11 +224,12 @@ export declare const TokenController: Elysia<"/tokens", false, {
224
224
  address: string;
225
225
  chainId: number;
226
226
  decimals: number;
227
+ displaySymbol: string;
227
228
  verified: boolean;
228
229
  isTest: boolean;
229
230
  isPoint: boolean;
230
231
  isNative: boolean;
231
- price?: number | null | undefined;
232
+ price: number | null;
232
233
  } | undefined;
233
234
  };
234
235
  };
@@ -59,7 +59,21 @@ export declare abstract class TokenRepository {
59
59
  * upsert a token on database
60
60
  * @param token
61
61
  */
62
- static upsert(token: Token["model"]): Promise<Token["model"] | undefined>;
62
+ static upsert(token: Token["model"]): Promise<{
63
+ symbol: string;
64
+ id: string;
65
+ name: string | null;
66
+ icon: string;
67
+ address: string;
68
+ chainId: number;
69
+ decimals: number;
70
+ displaySymbol: string;
71
+ verified: boolean;
72
+ isTest: boolean;
73
+ isPoint: boolean;
74
+ isNative: boolean;
75
+ price: number | null;
76
+ }>;
63
77
  /**
64
78
  * Updates price of tokens that share the same symbol
65
79
  * @param symbol
@@ -174,7 +174,21 @@ export declare abstract class TokenService {
174
174
  * @param chainId
175
175
  * @param address
176
176
  */
177
- static findManyOrCreate(tokens: TokenModel[]): Promise<(Token["model"] | undefined)[]>;
177
+ static findManyOrCreate(tokens: TokenModel[]): Promise<({
178
+ symbol: string;
179
+ id: string;
180
+ name: string | null;
181
+ icon: string;
182
+ address: string;
183
+ chainId: number;
184
+ decimals: number;
185
+ verified: boolean;
186
+ isTest: boolean;
187
+ isPoint: boolean;
188
+ isNative: boolean;
189
+ } & {
190
+ price?: number | null | undefined;
191
+ })[]>;
178
192
  static getValidRewardTokens(chainId: number): Promise<{
179
193
  minimumAmountPerHour: any;
180
194
  symbol: string;
@@ -226,7 +240,7 @@ export declare abstract class TokenService {
226
240
  * @param chainId
227
241
  * @param address
228
242
  */
229
- static fillAndCreate(token: CreateTokenModel): Promise<({
243
+ static fillAndCreate(token: CreateTokenModel): Promise<{
230
244
  symbol: string;
231
245
  id: string;
232
246
  name: string | null;
@@ -234,13 +248,13 @@ export declare abstract class TokenService {
234
248
  address: string;
235
249
  chainId: number;
236
250
  decimals: number;
251
+ displaySymbol: string;
237
252
  verified: boolean;
238
253
  isTest: boolean;
239
254
  isPoint: boolean;
240
255
  isNative: boolean;
241
- } & {
242
- price?: number | null | undefined;
243
- }) | undefined>;
256
+ price: number | null;
257
+ } | undefined>;
244
258
  /**
245
259
  * @deprecated Should be useless now that the token list is not used anymore
246
260
  * Get all tokens from https://github.com/AngleProtocol/angle-token-list and override icons from it
@@ -52,7 +52,7 @@ export class TokenService {
52
52
  */
53
53
  static async fetchTokensAndBalances(chainId, userAddress, addresses) {
54
54
  const tokens = await TokenService.findManyOrCreate(addresses?.map(address => ({ chainId, address })));
55
- return TokenService.fetchBalances(chainId, userAddress, tokens.filter(t => t !== undefined));
55
+ return TokenService.fetchBalances(chainId, userAddress, tokens);
56
56
  }
57
57
  /**
58
58
  * Fetches balances of verified tokens
@@ -61,13 +61,11 @@ export class TokenService {
61
61
  */
62
62
  static async fetchVerifiedAndNativeBalances(chainId, userAddress, additionalTokenAddresses) {
63
63
  const verifiedTokens = await TokenService.findMany({ chainId: chainId, verified: true });
64
- const nativeTokens = await TokenService.findMany({ chainId: chainId, isNative: true });
64
+ const nativeTokens = (await TokenService.findMany({ chainId: chainId, isNative: true })).filter(t => !!t);
65
65
  const additionalTokens = !!additionalTokenAddresses?.length
66
66
  ? await TokenService.findManyOrCreate(additionalTokenAddresses?.map(address => ({ chainId, address })))
67
67
  : [];
68
- const allTokens = verifiedTokens
69
- .concat(additionalTokens.filter(t => t !== undefined))
70
- .concat(nativeTokens.filter(t => t !== undefined));
68
+ const allTokens = verifiedTokens.concat(additionalTokens).concat(nativeTokens);
71
69
  return TokenService.fetchBalances(chainId, userAddress, allTokens);
72
70
  }
73
71
  static async fetchOnChain(token) {
@@ -193,9 +191,7 @@ export class TokenService {
193
191
  static async getValue(tokenAmounts) {
194
192
  const tokens = await TokenService.findManyOrCreate(tokenAmounts.map(({ address, chainId }) => ({ address, chainId })));
195
193
  return tokenAmounts.reduce((sum, { amount, address, chainId }) => {
196
- const token = tokens
197
- .filter(t => t !== undefined)
198
- .find(({ address: addr, chainId: chain }) => addr === address && chainId === chain);
194
+ const token = tokens.find(({ address: addr, chainId: chain }) => addr === address && chainId === chain);
199
195
  if (!token)
200
196
  return sum;
201
197
  const value = (bigIntToNumber(amount ?? 0n, token.decimals) ?? 0) * (token.price ?? 0);
@@ -241,9 +237,10 @@ export class TokenService {
241
237
  if (!newToken) {
242
238
  throw new HttpError(`Failed to fetch on-chain data for token ${token.address} on chain ${token.chainId}).`);
243
239
  }
244
- return await TokenRepository.upsert(newToken);
240
+ return TokenService.format(await TokenRepository.upsert(newToken));
245
241
  }
246
242
  }
243
+ throw new HttpError(`Failed to fetch or create token ${token.address} on chain ${token.chainId}.`);
247
244
  }));
248
245
  }
249
246
  static async getValidRewardTokens(chainId) {
@@ -276,7 +273,7 @@ export class TokenService {
276
273
  const displaySymbol = properties.Symbol.rich_text[0]?.plain_text;
277
274
  const isVerified = properties.Verified.checkbox;
278
275
  const coingeckoApiId = properties["CoinGecko API ID"].rich_text[0]?.plain_text;
279
- const byteArray = await iconFile.bytes();
276
+ const byteArray = await iconFile.bytes(); // Unknown type error here probably due to bun/types
280
277
  const [token] = await TokenService.findManyOrCreate([
281
278
  {
282
279
  chainId,
@@ -27,10 +27,10 @@ export declare const uniswapV4Controller: Elysia<"uniswap-v4", false, {
27
27
  poolId: string;
28
28
  poolKey: {
29
29
  hooks: string;
30
- fee: number;
31
- tickSpacing: number;
32
30
  currency0: string;
33
31
  currency1: string;
32
+ fee: number;
33
+ tickSpacing: number;
34
34
  };
35
35
  decimalsCurrency0: number;
36
36
  decimalsCurrency1: number;
@@ -1,3 +1,6 @@
1
+ import type { apiDbClient } from "@db";
2
+ import type { Prisma } from "@db/api";
3
+ import type { MerklChainId, UniswapV4PoolType } from "@sdk";
1
4
  export declare const UniswapV4PoolsDto: import("@sinclair/typebox").TRecord<import("@sinclair/typebox").TString, import("@sinclair/typebox").TObject<{
2
5
  poolKey: import("@sinclair/typebox").TObject<{
3
6
  currency0: import("@sinclair/typebox").TString;
@@ -12,4 +15,10 @@ export declare const UniswapV4PoolsDto: import("@sinclair/typebox").TRecord<impo
12
15
  symbolCurrency0: import("@sinclair/typebox").TString;
13
16
  symbolCurrency1: import("@sinclair/typebox").TString;
14
17
  }>>;
18
+ export type UniswapV4PoolsReturnType = {
19
+ [chainId in MerklChainId]?: {
20
+ [poolId: string]: UniswapV4PoolType;
21
+ };
22
+ };
15
23
  export type UniswapV4PoolsEntity = typeof UniswapV4PoolsDto.static;
24
+ export type LoggedCreateBody = Prisma.Args<typeof apiDbClient.logged, "createMany">["data"];
@@ -1,2 +1,13 @@
1
+ import type { LoggedCreateBody } from "./uniswapV4.model";
1
2
  export declare abstract class UniswapV4Repository {
3
+ static getStoredPools(): Promise<{
4
+ id: string;
5
+ type: import("@db/api").$Enums.LoggedEntityType;
6
+ address: string | null;
7
+ chainId: number;
8
+ fetchAtBlock: number;
9
+ caughtFromAddress: string;
10
+ entityData: import("database/api/.generated/runtime/library").JsonValue;
11
+ }[]>;
12
+ static createMany(data: LoggedCreateBody): Promise<import("database/api/.generated/runtime/library").GetBatchResult>;
2
13
  }
@@ -1,2 +1,12 @@
1
+ import { apiDbClient } from "@db";
2
+ import { LoggedEntityType } from "@db/api";
1
3
  export class UniswapV4Repository {
4
+ static async getStoredPools() {
5
+ return await apiDbClient.logged.findMany({
6
+ where: { type: LoggedEntityType.UNISWAP_V4 },
7
+ });
8
+ }
9
+ static async createMany(data) {
10
+ return await apiDbClient.logged.createMany({ data });
11
+ }
2
12
  }