@paraswap/dex-lib 4.7.18-before-multi-route.0 → 4.7.18

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 (170) hide show
  1. package/build/abi/PendleRouterStatic.json +19 -0
  2. package/build/abi/apex-defi/ApexDefiFactory.abi.json +1749 -0
  3. package/build/abi/apex-defi/ApexDefiRouter.abi.json +1120 -0
  4. package/build/abi/apex-defi/ApexDefiToken.abi.json +229 -0
  5. package/build/abi/apex-defi/ApexDefiWrapper.abi.json +92 -0
  6. package/build/abi/apex-defi/ApexDefiWrapperFactory.abi.json +1107 -0
  7. package/build/abi/pangolin-v3/PangolinV3StateMulticall.abi.json +796 -0
  8. package/build/abi/pendle/pendle-deployer.abi.json +520 -0
  9. package/build/abi/pendle/pendle-oracle.abi.json +413 -0
  10. package/build/abi/pharaoh-v3/PharaohV3Factory.abi.json +101 -0
  11. package/build/abi/ring-v2/few-wrapped-token.json +587 -0
  12. package/build/abi/ring-v2/ring-v2-factory.json +125 -0
  13. package/build/abi/ring-v2/ring-v2-pool.json +461 -0
  14. package/build/abi/ring-v2/ring-v2-router.json +332 -0
  15. package/build/abi/stabull/stabull-curve.json +738 -0
  16. package/build/abi/stabull/stabull-router.json +76 -0
  17. package/build/abi/uniswap-v4/hooks/SpotDynamicFeeManager.json +26 -0
  18. package/build/abi/uniswap-v4/hooks/SpotHook.json +54 -0
  19. package/build/abi/uniswap-v4/hooks/SpotPolicyManager.json +45 -0
  20. package/build/abi/uniswap-v4/hooks/cabalcoin-hook.abi.json +682 -0
  21. package/build/abi/uniswap-v4/hooks/fee-hook.abi.json +1335 -0
  22. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying-factory.d.ts +29 -0
  23. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying-factory.js +153 -0
  24. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying-factory.js.map +1 -0
  25. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying.d.ts +40 -0
  26. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying.js +323 -0
  27. package/build/dex/aave-pt-to-underlying/aave-pt-to-underlying.js.map +1 -0
  28. package/build/dex/aave-pt-to-underlying/config.d.ts +3 -0
  29. package/build/dex/aave-pt-to-underlying/config.js +24 -0
  30. package/build/dex/aave-pt-to-underlying/config.js.map +1 -0
  31. package/build/dex/aave-pt-to-underlying/constants.d.ts +2 -0
  32. package/build/dex/aave-pt-to-underlying/constants.js +6 -0
  33. package/build/dex/aave-pt-to-underlying/constants.js.map +1 -0
  34. package/build/dex/aave-pt-to-underlying/types.d.ts +24 -0
  35. package/build/dex/aave-pt-to-underlying/types.js +3 -0
  36. package/build/dex/aave-pt-to-underlying/types.js.map +1 -0
  37. package/build/dex/aave-pt-to-usdc/aave-pt-to-usdc.d.ts +39 -0
  38. package/build/dex/aave-pt-to-usdc/aave-pt-to-usdc.js +244 -0
  39. package/build/dex/aave-pt-to-usdc/aave-pt-to-usdc.js.map +1 -0
  40. package/build/dex/aave-pt-to-usdc/config.d.ts +3 -0
  41. package/build/dex/aave-pt-to-usdc/config.js +47 -0
  42. package/build/dex/aave-pt-to-usdc/config.js.map +1 -0
  43. package/build/dex/aave-pt-to-usdc/constants.d.ts +2 -0
  44. package/build/dex/aave-pt-to-usdc/constants.js +6 -0
  45. package/build/dex/aave-pt-to-usdc/constants.js.map +1 -0
  46. package/build/dex/aave-pt-to-usdc/types.d.ts +22 -0
  47. package/build/dex/aave-pt-to-usdc/types.js +3 -0
  48. package/build/dex/aave-pt-to-usdc/types.js.map +1 -0
  49. package/build/dex/apex-defi/apex-defi-factory.d.ts +26 -0
  50. package/build/dex/apex-defi/apex-defi-factory.js +53 -0
  51. package/build/dex/apex-defi/apex-defi-factory.js.map +1 -0
  52. package/build/dex/apex-defi/apex-defi-pool.d.ts +55 -0
  53. package/build/dex/apex-defi/apex-defi-pool.js +247 -0
  54. package/build/dex/apex-defi/apex-defi-pool.js.map +1 -0
  55. package/build/dex/apex-defi/apex-defi-wrapper-factory.d.ts +57 -0
  56. package/build/dex/apex-defi/apex-defi-wrapper-factory.js +250 -0
  57. package/build/dex/apex-defi/apex-defi-wrapper-factory.js.map +1 -0
  58. package/build/dex/apex-defi/apex-defi.d.ts +97 -0
  59. package/build/dex/apex-defi/apex-defi.js +1021 -0
  60. package/build/dex/apex-defi/apex-defi.js.map +1 -0
  61. package/build/dex/apex-defi/config.d.ts +4 -0
  62. package/build/dex/apex-defi/config.js +138 -0
  63. package/build/dex/apex-defi/config.js.map +1 -0
  64. package/build/dex/apex-defi/types.d.ts +32 -0
  65. package/build/dex/apex-defi/types.js +3 -0
  66. package/build/dex/apex-defi/types.js.map +1 -0
  67. package/build/dex/apex-defi/utils.d.ts +46 -0
  68. package/build/dex/apex-defi/utils.js +133 -0
  69. package/build/dex/apex-defi/utils.js.map +1 -0
  70. package/build/dex/idle-dao/idle-dao.d.ts +0 -1
  71. package/build/dex/idle-dao/idle-dao.js +11 -23
  72. package/build/dex/idle-dao/idle-dao.js.map +1 -1
  73. package/build/dex/maker-psm/maker-psm.d.ts +41 -4
  74. package/build/dex/maker-psm/maker-psm.js +143 -40
  75. package/build/dex/maker-psm/maker-psm.js.map +1 -1
  76. package/build/dex/miro-migrator/miro-migrator-state.d.ts +27 -0
  77. package/build/dex/miro-migrator/miro-migrator-state.js +89 -0
  78. package/build/dex/miro-migrator/miro-migrator-state.js.map +1 -0
  79. package/build/dex/simple-exchange.js +1 -7
  80. package/build/dex/simple-exchange.js.map +1 -1
  81. package/build/dex/stabull/config.d.ts +3 -0
  82. package/build/dex/stabull/config.js +177 -0
  83. package/build/dex/stabull/config.js.map +1 -0
  84. package/build/dex/stabull/stabull-pool.d.ts +46 -0
  85. package/build/dex/stabull/stabull-pool.js +113 -0
  86. package/build/dex/stabull/stabull-pool.js.map +1 -0
  87. package/build/dex/stabull/stabull.d.ts +55 -0
  88. package/build/dex/stabull/stabull.js +286 -0
  89. package/build/dex/stabull/stabull.js.map +1 -0
  90. package/build/dex/stabull/types.d.ts +21 -0
  91. package/build/dex/stabull/types.js +3 -0
  92. package/build/dex/stabull/types.js.map +1 -0
  93. package/build/dex/uniswap-v2/constants.js +2 -0
  94. package/build/dex/uniswap-v2/constants.js.map +1 -1
  95. package/build/dex/uniswap-v3/forks/pangolin-v3/utils.d.ts +4 -0
  96. package/build/dex/uniswap-v3/forks/pangolin-v3/utils.js +56 -0
  97. package/build/dex/uniswap-v3/forks/pangolin-v3/utils.js.map +1 -0
  98. package/build/dex/uniswap-v4/config.js +2 -0
  99. package/build/dex/uniswap-v4/config.js.map +1 -1
  100. package/build/dex/uniswap-v4/contract-math/uniswap-v4-pool-math.d.ts +2 -1
  101. package/build/dex/uniswap-v4/contract-math/uniswap-v4-pool-math.js +28 -9
  102. package/build/dex/uniswap-v4/contract-math/uniswap-v4-pool-math.js.map +1 -1
  103. package/build/dex/uniswap-v4/hooks/arena/arena-hook.js +4 -4
  104. package/build/dex/uniswap-v4/hooks/arena/arena-hook.js.map +1 -1
  105. package/build/dex/uniswap-v4/hooks/arena.d.ts +6 -0
  106. package/build/dex/uniswap-v4/hooks/arena.js +10 -0
  107. package/build/dex/uniswap-v4/hooks/arena.js.map +1 -0
  108. package/build/dex/uniswap-v4/hooks/base-fee/base-fee-hook.d.ts +0 -0
  109. package/build/dex/uniswap-v4/hooks/base-fee/base-fee-hook.js +2 -0
  110. package/build/dex/uniswap-v4/hooks/base-fee/base-fee-hook.js.map +1 -0
  111. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/cabalcoin-hook-pool.d.ts +7 -0
  112. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/cabalcoin-hook-pool.js +28 -0
  113. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/cabalcoin-hook-pool.js.map +1 -0
  114. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/types.d.ts +0 -0
  115. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/types.js +2 -0
  116. package/build/dex/uniswap-v4/hooks/cabalcoin-hook/types.js.map +1 -0
  117. package/build/dex/uniswap-v4/hooks/fee-hook/fee-hook-pool.d.ts +7 -0
  118. package/build/dex/uniswap-v4/hooks/fee-hook/fee-hook-pool.js +28 -0
  119. package/build/dex/uniswap-v4/hooks/fee-hook/fee-hook-pool.js.map +1 -0
  120. package/build/dex/uniswap-v4/hooks/fee-hook/types.d.ts +0 -0
  121. package/build/dex/uniswap-v4/hooks/fee-hook/types.js +2 -0
  122. package/build/dex/uniswap-v4/hooks/fee-hook/types.js.map +1 -0
  123. package/build/dex/uniswap-v4/hooks/index.d.ts +1 -0
  124. package/build/dex/uniswap-v4/hooks/index.js +18 -0
  125. package/build/dex/uniswap-v4/hooks/index.js.map +1 -0
  126. package/build/dex/uniswap-v4/hooks/spot.d.ts +15 -0
  127. package/build/dex/uniswap-v4/hooks/spot.js +109 -0
  128. package/build/dex/uniswap-v4/hooks/spot.js.map +1 -0
  129. package/build/dex/uniswap-v4/hooks/template.d.ts +150 -0
  130. package/build/dex/uniswap-v4/hooks/template.js +104 -0
  131. package/build/dex/uniswap-v4/hooks/template.js.map +1 -0
  132. package/build/dex/uniswap-v4/hooks/types.d.ts +4 -0
  133. package/build/dex/uniswap-v4/subgraph.d.ts +4 -4
  134. package/build/dex/uniswap-v4/subgraph.js +24 -21
  135. package/build/dex/uniswap-v4/subgraph.js.map +1 -1
  136. package/build/dex/uniswap-v4/types.d.ts +2 -0
  137. package/build/dex/uniswap-v4/uniswap-v4-pool-manager.d.ts +7 -1
  138. package/build/dex/uniswap-v4/uniswap-v4-pool-manager.js +54 -9
  139. package/build/dex/uniswap-v4/uniswap-v4-pool-manager.js.map +1 -1
  140. package/build/dex/uniswap-v4/uniswap-v4-pool.d.ts +3 -1
  141. package/build/dex/uniswap-v4/uniswap-v4-pool.js +3 -1
  142. package/build/dex/uniswap-v4/uniswap-v4-pool.js.map +1 -1
  143. package/build/dex/uniswap-v4/uniswap-v4.d.ts +3 -1
  144. package/build/dex/uniswap-v4/uniswap-v4.js +15 -5
  145. package/build/dex/uniswap-v4/uniswap-v4.js.map +1 -1
  146. package/build/dex/uniswap-v4/utils.d.ts +2 -1
  147. package/build/dex/uniswap-v4/utils.js +11 -0
  148. package/build/dex/uniswap-v4/utils.js.map +1 -1
  149. package/build/dex/usdc-transmuter/usdc-transmuter-pool.d.ts +26 -0
  150. package/build/dex/usdc-transmuter/usdc-transmuter-pool.js +75 -0
  151. package/build/dex/usdc-transmuter/usdc-transmuter-pool.js.map +1 -0
  152. package/build/dex/usual/usual-usdc-usdc.d.ts +17 -0
  153. package/build/dex/usual/usual-usdc-usdc.js +59 -0
  154. package/build/dex/usual/usual-usdc-usdc.js.map +1 -0
  155. package/build/dex/yo/config.d.ts +3 -0
  156. package/build/dex/yo/config.js +21 -0
  157. package/build/dex/yo/config.js.map +1 -0
  158. package/build/dex/yo/types.d.ts +13 -0
  159. package/build/dex/yo/types.js +3 -0
  160. package/build/dex/yo/types.js.map +1 -0
  161. package/build/dex/yo/yo-pool.d.ts +13 -0
  162. package/build/dex/yo/yo-pool.js +26 -0
  163. package/build/dex/yo/yo-pool.js.map +1 -0
  164. package/build/dex/yo/yo.d.ts +39 -0
  165. package/build/dex/yo/yo.js +248 -0
  166. package/build/dex/yo/yo.js.map +1 -0
  167. package/build/implementations/api-paraswap-sdk.d.ts +25 -0
  168. package/build/implementations/api-paraswap-sdk.js +102 -0
  169. package/build/implementations/api-paraswap-sdk.js.map +1 -0
  170. package/package.json +3 -2
@@ -0,0 +1,1021 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.ApexDefi = void 0;
40
+ const constants_1 = require("../../constants");
41
+ const CALLDATA_GAS_COST = __importStar(require("../../calldata-gas-cost"));
42
+ const utils_1 = require("../../utils");
43
+ const simple_exchange_1 = require("../simple-exchange");
44
+ const config_1 = require("./config");
45
+ const apex_defi_pool_1 = require("./apex-defi-pool");
46
+ const abi_1 = require("@ethersproject/abi");
47
+ const ApexDefiRouter_abi_json_1 = __importDefault(require("../../abi/apex-defi/ApexDefiRouter.abi.json"));
48
+ const ApexDefiToken_abi_json_1 = __importDefault(require("../../abi/apex-defi/ApexDefiToken.abi.json"));
49
+ const ApexDefiFactory_abi_json_1 = __importDefault(require("../../abi/apex-defi/ApexDefiFactory.abi.json"));
50
+ const ApexDefiWrapperFactory_abi_json_1 = __importDefault(require("../../abi/apex-defi/ApexDefiWrapperFactory.abi.json"));
51
+ const ApexDefiWrapper_abi_json_1 = __importDefault(require("../../abi/apex-defi/ApexDefiWrapper.abi.json"));
52
+ const erc20_json_1 = __importDefault(require("../../abi/erc20.json"));
53
+ const apex_defi_factory_1 = require("./apex-defi-factory");
54
+ const utils_2 = require("./utils");
55
+ const apex_defi_wrapper_factory_1 = require("./apex-defi-wrapper-factory");
56
+ const simple_exchange_2 = require("../simple-exchange");
57
+ class ApexDefi extends simple_exchange_1.SimpleExchange {
58
+ network;
59
+ dexKey;
60
+ dexHelper;
61
+ eventPools = {};
62
+ supportedTokensMap = {};
63
+ factory;
64
+ wrapperFactory;
65
+ routerIface;
66
+ erc20Iface;
67
+ tokenIface;
68
+ factoryIface;
69
+ wrapperFactoryIface;
70
+ wrapperIface;
71
+ feeFactor = 10000;
72
+ hasConstantPriceLargeAmounts = false;
73
+ needWrapNative = false;
74
+ isFeeOnTransferSupported = false;
75
+ static dexKeysWithNetwork = (0, utils_1.getDexKeysWithNetwork)(config_1.ApexDefiConfig);
76
+ logger;
77
+ constructor(network, dexKey, dexHelper) {
78
+ super(dexHelper, dexKey);
79
+ this.network = network;
80
+ this.dexKey = dexKey;
81
+ this.dexHelper = dexHelper;
82
+ this.routerIface = new abi_1.Interface(ApexDefiRouter_abi_json_1.default);
83
+ this.erc20Iface = new abi_1.Interface(erc20_json_1.default);
84
+ this.tokenIface = new abi_1.Interface(ApexDefiToken_abi_json_1.default);
85
+ this.factoryIface = new abi_1.Interface(ApexDefiFactory_abi_json_1.default);
86
+ this.wrapperFactoryIface = new abi_1.Interface(ApexDefiWrapperFactory_abi_json_1.default);
87
+ this.wrapperIface = new abi_1.Interface(ApexDefiWrapper_abi_json_1.default);
88
+ this.logger = dexHelper.getLogger(dexKey + '-' + network);
89
+ this.factory = this.getFactoryInstance();
90
+ this.wrapperFactory = this.getWrapperFactoryInstance();
91
+ }
92
+ getFactoryInstance() {
93
+ return new apex_defi_factory_1.ApexDefiFactory(this.dexHelper, this.dexKey, config_1.ApexDefiConfig[this.dexKey][this.network].factoryAddress, this.logger, this.onPoolCreated().bind(this));
94
+ }
95
+ getWrapperFactoryInstance() {
96
+ return new apex_defi_wrapper_factory_1.ApexDefiWrapperFactory(this.dexHelper, this.dexKey, config_1.ApexDefiConfig[this.dexKey][this.network].wrapperFactoryAddress, this.logger, this.onWrapperCreated().bind(this));
97
+ }
98
+ onPoolCreated() {
99
+ return async ({ pairAddress, blockNumber }) => {
100
+ const poolKey = this.getPoolIdentifier(pairAddress);
101
+ await this.fetchAndInitPool(pairAddress, blockNumber, poolKey);
102
+ this.logger.info(`[onPoolCreated] pool=${poolKey}; pairAddress=${pairAddress} initialized`);
103
+ };
104
+ }
105
+ onWrapperCreated() {
106
+ return async ({ wrapperInfo, blockNumber }) => {
107
+ this.logger.info(`[onWrapperCreated] wrapper=${wrapperInfo.wrapperAddress}; originalToken=${wrapperInfo.originalToken}; wrappedToken=${wrapperInfo.wrappedToken} initialized`);
108
+ };
109
+ }
110
+ // Initialize pricing is called once in the start of
111
+ // pricing service. It is intended to setup the integration
112
+ // for pricing requests. It is optional for a DEX to
113
+ // implement this function
114
+ async initializePricing(blockNumber) {
115
+ await this.factory.initialize(blockNumber);
116
+ await this.wrapperFactory.initialize(blockNumber);
117
+ }
118
+ // Legacy: was only used for V5
119
+ // Returns the list of contract adapters (name and index)
120
+ // for a buy/sell. Return null if there are no adapters.
121
+ getAdapters(side) {
122
+ return null;
123
+ }
124
+ // Returns list of pool identifiers that can be used
125
+ // for a given swap. poolIdentifiers must be unique
126
+ // across DEXes. It is recommended to use
127
+ // ${dexKey}_${poolAddress} as a poolIdentifier
128
+ async getPoolIdentifiers(srcToken, destToken, side, blockNumber) {
129
+ if (srcToken.address.toLowerCase() === destToken.address.toLowerCase()) {
130
+ return [];
131
+ }
132
+ // Check if tokens are wrappers and get their underlying tokens
133
+ const srcTokenToUse = this.getERC314Token(srcToken.address);
134
+ const destTokenToUse = this.getERC314Token(destToken.address);
135
+ // Check if this is a direct AVAX pair
136
+ const isDirectAVAXPair = (0, utils_1.isETHAddress)(srcTokenToUse.address) ||
137
+ (0, utils_1.isETHAddress)(destTokenToUse.address);
138
+ if (isDirectAVAXPair) {
139
+ // Direct AVAX pair - return single pool
140
+ const pairAddress = this.getPoolAddress(srcTokenToUse, destTokenToUse);
141
+ const poolIdentifier = this.getPoolIdentifier(pairAddress).toLowerCase();
142
+ return [poolIdentifier];
143
+ }
144
+ else {
145
+ // Token-to-token swap - return both AVAX pairs
146
+ const avaxToken = {
147
+ address: constants_1.ETHER_ADDRESS,
148
+ decimals: 18,
149
+ };
150
+ const srcPoolAddress = this.getPoolAddress(srcTokenToUse, avaxToken);
151
+ const destPoolAddress = this.getPoolAddress(destTokenToUse, avaxToken);
152
+ const srcPoolIdentifier = this.getPoolIdentifier(srcPoolAddress).toLowerCase();
153
+ const destPoolIdentifier = this.getPoolIdentifier(destPoolAddress).toLowerCase();
154
+ return [srcPoolIdentifier, destPoolIdentifier];
155
+ }
156
+ }
157
+ getPoolIdentifier(pairAddress) {
158
+ return `${this.dexKey}_${pairAddress}`.toLowerCase();
159
+ }
160
+ getPoolAddress(srcToken, destToken) {
161
+ // Only handle direct AVAX pairs
162
+ const isSrcNative = (0, utils_1.isETHAddress)(srcToken.address);
163
+ const isDestNative = (0, utils_1.isETHAddress)(destToken.address);
164
+ if (isSrcNative) {
165
+ // AVAX → Token: pool address is the token address
166
+ return destToken.address;
167
+ }
168
+ else if (isDestNative) {
169
+ // Token → AVAX: pool address is the token address
170
+ return srcToken.address;
171
+ }
172
+ else {
173
+ // This should never happen for direct pairs
174
+ throw new Error('getPoolAddress called for non-AVAX pair');
175
+ }
176
+ }
177
+ // Returns pool prices for amounts.
178
+ // If limitPools is defined only pools in limitPools
179
+ // should be used. If limitPools is undefined then
180
+ // any pools can be used.
181
+ async getPricesVolume(srcToken, destToken, amounts, side, blockNumber, limitPools) {
182
+ try {
183
+ // Check if this is a wrapper/unwrap operation
184
+ const isWrapperOperation = this.isWrapperOperation(srcToken, destToken);
185
+ if (isWrapperOperation) {
186
+ return this.getWrapperPrices(srcToken, destToken, amounts, side);
187
+ }
188
+ const [_srcAddress, _destAddress] = this._getLoweredAddresses(srcToken, destToken);
189
+ if (_srcAddress === _destAddress) {
190
+ return null;
191
+ }
192
+ // Get underlying ERC314 tokens for pool discovery and pricing
193
+ const srcTokenERC314 = this.getERC314Token(srcToken.address);
194
+ const destTokenERC314 = this.getERC314Token(destToken.address);
195
+ const poolIdentifiers = await this.getPoolIdentifiers(srcTokenERC314, destTokenERC314, side, blockNumber);
196
+ // Filter pools based on limitPools if provided
197
+ const validPoolIdentifiers = limitPools
198
+ ? poolIdentifiers.filter(id => limitPools.includes(id))
199
+ : poolIdentifiers;
200
+ if (validPoolIdentifiers.length === 0) {
201
+ this.logger.warn(`No valid pool identifiers found for ${srcToken.address} -> ${destToken.address}`);
202
+ return null;
203
+ }
204
+ // Check if this is a direct AVAX pair
205
+ const isDirectAVAXPair = (0, utils_1.isETHAddress)(srcTokenERC314.address) ||
206
+ (0, utils_1.isETHAddress)(destTokenERC314.address);
207
+ if (isDirectAVAXPair) {
208
+ return this.getDirectAVAXPairPrices(srcTokenERC314, destTokenERC314, amounts, side, blockNumber, validPoolIdentifiers[0], srcToken, destToken);
209
+ }
210
+ else {
211
+ return this.getCrossPairTokenToTokenPrices(srcTokenERC314, destTokenERC314, amounts, side, blockNumber, validPoolIdentifiers, srcToken, destToken);
212
+ }
213
+ }
214
+ catch (e) {
215
+ this.logger.error(`Error_getPricesVolume ${srcToken.symbol || srcToken.address}, ${destToken.symbol || destToken.address}, ${side}:`, e);
216
+ return null;
217
+ }
218
+ }
219
+ async getDirectAVAXPairPrices(srcTokenERC314, destTokenERC314, amounts, side, blockNumber, poolIdentifier, originalSrcToken, originalDestToken) {
220
+ try {
221
+ // Get or discover the pool
222
+ let pool = this.eventPools[poolIdentifier];
223
+ if (!pool) {
224
+ pool = await this.discoverPool(srcTokenERC314, destTokenERC314, blockNumber);
225
+ if (!pool) {
226
+ this.logger.warn(`Failed to discover pool for ${poolIdentifier}`);
227
+ return null;
228
+ }
229
+ }
230
+ const state = await pool.getStateOrGenerate(blockNumber);
231
+ if (!state) {
232
+ this.logger.warn(`Failed to get pool state for ${poolIdentifier}`);
233
+ return null;
234
+ }
235
+ if (!state.tradingEnabled) {
236
+ this.logger.warn(`Pool ${poolIdentifier} is not trading`);
237
+ return null;
238
+ }
239
+ const { prices, unit } = await this.calculatePrices(amounts, side, originalSrcToken, originalDestToken, async (amount) => side === constants_1.SwapSide.SELL
240
+ ? this.getSellPrice(state, amount, srcTokenERC314, destTokenERC314)
241
+ : this.getBuyPrice(state, amount, srcTokenERC314, destTokenERC314), async (unitAmount) => side === constants_1.SwapSide.SELL
242
+ ? this.getSellPrice(state, unitAmount, srcTokenERC314, destTokenERC314)
243
+ : this.getBuyPrice(state, unitAmount, srcTokenERC314, destTokenERC314));
244
+ const isERC314Pair = !this.wrapperFactory.getWrapperByOriginalToken(originalSrcToken.address) &&
245
+ !this.wrapperFactory.getWrapperByOriginalToken(originalDestToken.address);
246
+ return [
247
+ {
248
+ prices,
249
+ unit,
250
+ data: {
251
+ path: [
252
+ {
253
+ tokenIn: originalSrcToken.address.toLowerCase(),
254
+ tokenOut: originalDestToken.address.toLowerCase(),
255
+ },
256
+ ],
257
+ swapType: isERC314Pair ? 'direct' : 'router',
258
+ },
259
+ exchange: this.dexKey,
260
+ poolIdentifiers: [poolIdentifier],
261
+ gasCost: config_1.ApexDefiConfig[this.dexKey][this.network].poolGasCost,
262
+ poolAddresses: [pool.poolAddress],
263
+ },
264
+ ];
265
+ }
266
+ catch (e) {
267
+ this.logger.error(`Error in getDirectAVAXPairPrices for ${poolIdentifier}:`, e);
268
+ return null;
269
+ }
270
+ }
271
+ async getCrossPairTokenToTokenPrices(srcTokenERC314, destTokenERC314, amounts, side, blockNumber, poolIdentifiers, originalSrcToken, originalDestToken) {
272
+ const avaxToken = { address: constants_1.ETHER_ADDRESS, decimals: 18 };
273
+ // Get both pool states
274
+ const [srcPool, destPool] = await Promise.all([
275
+ this.getOrDiscoverPool(srcTokenERC314, avaxToken, blockNumber, poolIdentifiers[0]),
276
+ this.getOrDiscoverPool(destTokenERC314, avaxToken, blockNumber, poolIdentifiers[1]),
277
+ ]);
278
+ if (!srcPool || !destPool) {
279
+ return null;
280
+ }
281
+ const [srcState, destState] = await Promise.all([
282
+ srcPool.getStateOrGenerate(blockNumber),
283
+ destPool.getStateOrGenerate(blockNumber),
284
+ ]);
285
+ if (!srcState || !destState) {
286
+ return null;
287
+ }
288
+ if (!srcState.tradingEnabled || !destState.tradingEnabled) {
289
+ this.logger.warn('Pool is not trading');
290
+ return null;
291
+ }
292
+ const { prices, unit } = await this.calculatePrices(amounts, side, originalSrcToken, originalDestToken, async (amount) => side === constants_1.SwapSide.SELL
293
+ ? this.calculateCrossPairSellPrice(amount, srcTokenERC314, destTokenERC314, srcState, destState)
294
+ : this.calculateCrossPairBuyPrice(amount, srcTokenERC314, destTokenERC314, srcState, destState), async (unitAmount) => side === constants_1.SwapSide.SELL
295
+ ? this.calculateCrossPairSellPrice(unitAmount, srcTokenERC314, destTokenERC314, srcState, destState)
296
+ : this.calculateCrossPairBuyPrice(unitAmount, srcTokenERC314, destTokenERC314, srcState, destState));
297
+ const virtualPoolIdentifier = `${this.dexKey}_virtual_${srcTokenERC314.address}_${destTokenERC314.address}`.toLowerCase();
298
+ return [
299
+ {
300
+ prices,
301
+ unit,
302
+ data: {
303
+ path: [
304
+ {
305
+ tokenIn: originalSrcToken.address.toLowerCase(),
306
+ tokenOut: constants_1.ETHER_ADDRESS.toLowerCase(),
307
+ },
308
+ {
309
+ tokenIn: constants_1.ETHER_ADDRESS.toLowerCase(),
310
+ tokenOut: originalDestToken.address.toLowerCase(),
311
+ },
312
+ ],
313
+ swapType: 'router',
314
+ },
315
+ exchange: this.dexKey,
316
+ poolIdentifiers: [virtualPoolIdentifier],
317
+ gasCost: config_1.ApexDefiConfig[this.dexKey][this.network].poolGasCost * 2,
318
+ poolAddresses: [srcPool.poolAddress, destPool.poolAddress],
319
+ },
320
+ ];
321
+ }
322
+ async getOrDiscoverPool(token, avaxToken, blockNumber, poolIdentifier) {
323
+ let pool = this.eventPools[poolIdentifier];
324
+ if (!pool) {
325
+ pool = await this.discoverPool(token, avaxToken, blockNumber);
326
+ }
327
+ return pool;
328
+ }
329
+ /**
330
+ * Discover and add a pool for a given token pair
331
+ * This method is called when a pool is not found in the eventPools map
332
+ */
333
+ async discoverPool(srcToken, destToken, blockNumber) {
334
+ const pairAddress = this.getPoolAddress(srcToken, destToken);
335
+ const poolKey = this.getPoolIdentifier(pairAddress);
336
+ if (this.eventPools[poolKey]) {
337
+ return this.eventPools[poolKey];
338
+ }
339
+ return this.fetchAndInitPool(pairAddress, blockNumber, poolKey);
340
+ }
341
+ /**
342
+ * Calculate the output amount for a sell (exact input) swap
343
+ * Uses the constant product formula: amountOut = (amountIn * reserveOut) / (reserveIn + amountIn)
344
+ */
345
+ getSellPrice(state, amountIn, srcToken, _destToken) {
346
+ const { reserve0, reserve1, baseSwapRate, tradingFee, tradingEnabled } = state;
347
+ if (!tradingEnabled) {
348
+ this.logger.warn('Pool is not trading');
349
+ return 0n;
350
+ }
351
+ // Validate state
352
+ if (reserve0 == null ||
353
+ reserve1 == null ||
354
+ baseSwapRate == null ||
355
+ tradingFee == null) {
356
+ this.logger.warn('Invalid pool state for pricing calculation');
357
+ return 0n;
358
+ }
359
+ // Determine which reserve is for input and which is for output
360
+ const isSrcToken0 = (0, utils_1.isETHAddress)(srcToken.address);
361
+ const reserveIn = BigInt(isSrcToken0 ? reserve0 : reserve1);
362
+ const reserveOut = BigInt(isSrcToken0 ? reserve1 : reserve0);
363
+ if (reserveIn === 0n || reserveOut === 0n)
364
+ return 0n;
365
+ const totalFee = baseSwapRate + tradingFee;
366
+ // Validate fee range
367
+ if (totalFee >= this.feeFactor) {
368
+ this.logger.warn('Invalid fee rate detected');
369
+ return 0n;
370
+ }
371
+ const amountInWithFee = amountIn * BigInt(this.feeFactor - totalFee);
372
+ const numerator = amountInWithFee * reserveOut;
373
+ const denominator = reserveIn * BigInt(this.feeFactor) + amountInWithFee;
374
+ return denominator === 0n ? 0n : numerator / denominator;
375
+ }
376
+ /**
377
+ * Calculate the input amount for a buy (exact output) swap
378
+ * Uses the constant product formula: amountIn = (amountOut * reserveIn * feeFactor) / ((reserveOut - amountOut) * (feeFactor - totalFee))
379
+ */
380
+ getBuyPrice(state, amountOut, srcToken, _destToken) {
381
+ const { reserve0, reserve1, baseSwapRate, tradingFee, tradingEnabled } = state;
382
+ if (!tradingEnabled) {
383
+ this.logger.warn('Pool is not trading');
384
+ return 0n;
385
+ }
386
+ // Validate state
387
+ if (reserve0 == null ||
388
+ reserve1 == null ||
389
+ baseSwapRate == null ||
390
+ tradingFee == null) {
391
+ this.logger.warn('Invalid pool state for pricing calculation');
392
+ return 0n;
393
+ }
394
+ // Determine which reserve is for input and which is for output
395
+ const isSrcToken0 = (0, utils_1.isETHAddress)(srcToken.address);
396
+ const reserveIn = BigInt(isSrcToken0 ? reserve0 : reserve1);
397
+ const reserveOut = BigInt(isSrcToken0 ? reserve1 : reserve0);
398
+ if (reserveIn === 0n || reserveOut === 0n)
399
+ return 0n;
400
+ if (amountOut >= reserveOut)
401
+ return 0n;
402
+ const totalFee = baseSwapRate + tradingFee;
403
+ // Validate fee range
404
+ if (totalFee >= this.feeFactor) {
405
+ this.logger.warn('Invalid fee rate detected');
406
+ return 0n;
407
+ }
408
+ const numerator = reserveIn * amountOut * BigInt(this.feeFactor);
409
+ const denominator = (BigInt(this.feeFactor) - BigInt(totalFee)) * (reserveOut - amountOut);
410
+ if (denominator <= 0n)
411
+ return 0n;
412
+ return numerator === 0n ? 0n : 1n + numerator / denominator;
413
+ }
414
+ calculateCrossPairSellPrice(amountIn, srcToken, destToken, srcPoolState, destPoolState) {
415
+ const avaxToken = {
416
+ address: constants_1.ETHER_ADDRESS,
417
+ decimals: 18,
418
+ };
419
+ if (!srcPoolState.tradingEnabled || !destPoolState.tradingEnabled) {
420
+ this.logger.warn('Pool is not trading');
421
+ return 0n;
422
+ }
423
+ // Step 1: Calculate tokenA → AVAX (with fees)
424
+ const avaxReceived = this.getSellPrice(srcPoolState, amountIn, srcToken, avaxToken);
425
+ if (avaxReceived === 0n)
426
+ return 0n;
427
+ // Step 2: Calculate AVAX → tokenB (with fees)
428
+ const finalOutput = this.getSellPrice(destPoolState, avaxReceived, avaxToken, destToken);
429
+ return finalOutput;
430
+ }
431
+ calculateCrossPairBuyPrice(amountOut, srcToken, destToken, srcPoolState, destPoolState) {
432
+ const avaxToken = {
433
+ address: constants_1.ETHER_ADDRESS,
434
+ decimals: 18,
435
+ };
436
+ if (!srcPoolState.tradingEnabled || !destPoolState.tradingEnabled) {
437
+ this.logger.warn('Pool is not trading');
438
+ return 0n;
439
+ }
440
+ // Step 1: Calculate AVAX → tokenB (reverse with fees)
441
+ const avaxNeeded = this.getBuyPrice(destPoolState, amountOut, avaxToken, destToken);
442
+ if (avaxNeeded === 0n)
443
+ return 0n;
444
+ // Step 2: Calculate tokenA → AVAX (reverse with fees)
445
+ const finalInput = this.getBuyPrice(srcPoolState, avaxNeeded, srcToken, avaxToken);
446
+ return finalInput;
447
+ }
448
+ // Common pricing logic for both direct and cross-pair swaps
449
+ async calculatePrices(amounts, side, originalSrcToken, originalDestToken, priceCalculator, unitCalculator) {
450
+ // Convert input amounts to ERC314 decimals (18) for internal calculations
451
+ const erc314Amounts = this.convertAmountsToERC314(amounts, side === constants_1.SwapSide.SELL
452
+ ? originalSrcToken.decimals
453
+ : originalDestToken.decimals);
454
+ // Calculate prices in ERC314 space (18 decimals)
455
+ const erc314Prices = await Promise.all(erc314Amounts.map(amount => {
456
+ if (amount === 0n)
457
+ return 0n;
458
+ return priceCalculator(amount);
459
+ }));
460
+ // Convert prices back to original token decimals
461
+ const finalPrices = this.convertPricesFromERC314(erc314Prices, side === constants_1.SwapSide.SELL
462
+ ? originalDestToken.decimals
463
+ : originalSrcToken.decimals);
464
+ // Calculate unit price
465
+ const unitAmount = (0, utils_1.getBigIntPow)(side === constants_1.SwapSide.SELL
466
+ ? originalSrcToken.decimals
467
+ : originalDestToken.decimals);
468
+ const erc314UnitAmount = this.convertAmountToERC314(unitAmount, side === constants_1.SwapSide.SELL
469
+ ? originalSrcToken.decimals
470
+ : originalDestToken.decimals, 18);
471
+ const erc314Unit = await unitCalculator(erc314UnitAmount);
472
+ const finalUnit = this.convertAmountFromERC314(erc314Unit, 18, side === constants_1.SwapSide.SELL
473
+ ? originalDestToken.decimals
474
+ : originalSrcToken.decimals);
475
+ return { prices: finalPrices, unit: finalUnit };
476
+ }
477
+ getCalldataGasCost(_poolPrices) {
478
+ return (CALLDATA_GAS_COST.DEX_OVERHEAD +
479
+ CALLDATA_GAS_COST.LENGTH_SMALL +
480
+ // ParentStruct header
481
+ CALLDATA_GAS_COST.OFFSET_SMALL +
482
+ // ParentStruct -> avax
483
+ CALLDATA_GAS_COST.ADDRESS +
484
+ // ParentStruct -> pools[] header
485
+ CALLDATA_GAS_COST.OFFSET_SMALL +
486
+ // ParentStruct -> pools[]
487
+ CALLDATA_GAS_COST.LENGTH_SMALL +
488
+ // ParentStruct -> pools[0]
489
+ CALLDATA_GAS_COST.wordNonZeroBytes(22));
490
+ }
491
+ // Encode params required by the exchange adapter
492
+ // V5: Used for multiSwap, buy & megaSwap
493
+ // V6: Not used, can be left blank
494
+ // Hint: abiCoder.encodeParameter() could be useful
495
+ getAdapterParam(_srcToken, _destToken, _srcAmount, _destAmount, _data, _side) {
496
+ // Not implemented for ApexDefi
497
+ const payload = '';
498
+ return {
499
+ targetExchange: config_1.ApexDefiConfig[this.dexKey][this.network].routerAddress,
500
+ payload,
501
+ networkFee: '0',
502
+ };
503
+ }
504
+ // Encode params required by the exchange adapter for V6
505
+ // This is the main method used for swaps in V6
506
+ getDexParam(srcToken, destToken, srcAmount, destAmount, recipient, data, _side) {
507
+ // Handle wrapper operations
508
+ if (data.swapType === 'wrapper') {
509
+ return this.getWrapperSwap(srcToken, destToken, srcAmount, destAmount, recipient, data);
510
+ }
511
+ if (data.swapType === 'direct') {
512
+ return this.getDirectTokenSwap(data.path[0].tokenIn, data.path[0].tokenOut, srcAmount, destAmount);
513
+ }
514
+ else {
515
+ return this.getRouterSwap(srcAmount, destAmount, recipient, data);
516
+ }
517
+ }
518
+ getDirectTokenSwap(srcToken, destToken, srcAmount, destAmount) {
519
+ const isSrcAVAX = (0, utils_1.isETHAddress)(srcToken);
520
+ const isDestAVAX = (0, utils_1.isETHAddress)(destToken);
521
+ let swapFunction;
522
+ let swapParams;
523
+ let targetExchange;
524
+ if (isSrcAVAX && !isDestAVAX) {
525
+ // AVAX → Token: call swapNativeToToken on the token
526
+ swapFunction = 'swapNativeToToken';
527
+ swapParams = [
528
+ destAmount, // minimumTokensOut
529
+ (0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(), // deadline
530
+ ];
531
+ targetExchange = destToken; // Call directly on the token
532
+ }
533
+ else if (!isSrcAVAX && isDestAVAX) {
534
+ // Token → AVAX: call swapTokenToNative on the token
535
+ swapFunction = 'swapTokenToNative';
536
+ swapParams = [
537
+ srcAmount, // tokensSold
538
+ destAmount, // minimumNativeOut
539
+ (0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(), // deadline
540
+ ];
541
+ targetExchange = srcToken; // Call directly on the token
542
+ }
543
+ else {
544
+ throw new Error('Invalid direct swap pair');
545
+ }
546
+ const exchangeData = this.tokenIface.encodeFunctionData(swapFunction, swapParams);
547
+ return {
548
+ needWrapNative: false,
549
+ dexFuncHasRecipient: false,
550
+ exchangeData,
551
+ targetExchange,
552
+ returnAmountPos: undefined,
553
+ };
554
+ }
555
+ getRouterSwap(srcAmount, destAmount, recipient, data) {
556
+ const { path } = data;
557
+ // Convert native AVAX to WAVAX for router calls, but leave ERC20 tokens as-is
558
+ const routerPath = this.fixPathForRouter(path.map(p => p.tokenIn).concat(path[path.length - 1].tokenOut));
559
+ // Determine the correct swap function based on token types
560
+ const isSrcAVAX = (0, utils_1.isETHAddress)(path[0].tokenIn);
561
+ const isDestAVAX = (0, utils_1.isETHAddress)(path[path.length - 1].tokenOut);
562
+ let swapFunction;
563
+ let swapParams;
564
+ if (isSrcAVAX && !isDestAVAX) {
565
+ // AVAX -> Token
566
+ swapFunction = 'swapExactAVAXForTokens';
567
+ swapParams = [
568
+ destAmount, // Keep original amount - router handles decimal conversion
569
+ routerPath,
570
+ recipient,
571
+ (0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(),
572
+ ];
573
+ }
574
+ else if (!isSrcAVAX && isDestAVAX) {
575
+ // Token -> AVAX
576
+ swapFunction = 'swapExactTokensForAVAX';
577
+ swapParams = [
578
+ srcAmount, // Keep original amount - router handles decimal conversion
579
+ destAmount,
580
+ routerPath,
581
+ recipient,
582
+ (0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(),
583
+ ];
584
+ }
585
+ else {
586
+ // Token -> Token (cross-pair via AVAX)
587
+ swapFunction = 'swapExactTokensForTokens';
588
+ swapParams = [
589
+ srcAmount, // Keep original amount - router handles decimal conversion
590
+ destAmount,
591
+ routerPath,
592
+ recipient,
593
+ (0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(),
594
+ ];
595
+ }
596
+ const exchangeData = this.routerIface.encodeFunctionData(swapFunction, swapParams);
597
+ return {
598
+ needWrapNative: this.needWrapNative,
599
+ dexFuncHasRecipient: true,
600
+ exchangeData,
601
+ targetExchange: config_1.ApexDefiConfig[this.dexKey][this.network].routerAddress,
602
+ returnAmountPos: undefined,
603
+ };
604
+ }
605
+ // Encode params for simple swap (V5)
606
+ async getSimpleParam(srcToken, destToken, srcAmount, destAmount, data, _side) {
607
+ // Handle wrapper operations
608
+ if (data.swapType === 'wrapper') {
609
+ return this.getWrapperSimpleParam(srcToken, destToken, srcAmount, destAmount, data);
610
+ }
611
+ const { path } = data;
612
+ // Convert native AVAX to WAVAX for router calls
613
+ const routerPath = this.fixPathForRouter(path.map(p => p.tokenIn).concat(path[path.length - 1].tokenOut));
614
+ // Determine the swap function based on the token types
615
+ let swapFunction;
616
+ let swapParams;
617
+ const isSrcAVAX = (0, utils_1.isETHAddress)(srcToken);
618
+ const isDestAVAX = (0, utils_1.isETHAddress)(destToken);
619
+ const targetExchange = config_1.ApexDefiConfig[this.dexKey][this.network].routerAddress;
620
+ if (isSrcAVAX && !isDestAVAX) {
621
+ // AVAX -> Token
622
+ swapFunction = 'swapExactAVAXForTokens';
623
+ swapParams = [
624
+ destAmount,
625
+ routerPath, // Use converted path
626
+ targetExchange, // recipient - will be set by the router
627
+ (0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(), // deadline: 7 days from now
628
+ ];
629
+ }
630
+ else if (!isSrcAVAX && isDestAVAX) {
631
+ // Token -> AVAX
632
+ swapFunction = 'swapExactTokensForAVAX';
633
+ swapParams = [
634
+ srcAmount,
635
+ destAmount,
636
+ routerPath, // Use converted path
637
+ targetExchange, // recipient - will be set by the router
638
+ (0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(), // deadline: 7 days from now
639
+ ];
640
+ }
641
+ else {
642
+ // Token -> Token
643
+ swapFunction = 'swapExactTokensForTokens';
644
+ swapParams = [
645
+ srcAmount,
646
+ destAmount,
647
+ routerPath, // Use converted path
648
+ targetExchange, // recipient - will be set by the router
649
+ (0, simple_exchange_2.getLocalDeadlineAsFriendlyPlaceholder)(), // deadline: 7 days from now
650
+ ];
651
+ }
652
+ const swapData = this.routerIface.encodeFunctionData(swapFunction, swapParams);
653
+ return this.buildSimpleParamWithoutWETHConversion(srcToken, srcAmount, destToken, destAmount, swapData, targetExchange, targetExchange, '0');
654
+ }
655
+ // Direct swap methods for V5
656
+ getDirectParam(_srcToken, _destToken, _srcAmount, _destAmount, _expectedAmount, _data, _side, _permit, _uuid, _feePercent, _deadline, _partner, _beneficiary, _contractMethod) {
657
+ // This method is not implemented for ApexDefi
658
+ throw new Error('Direct swaps not supported for ApexDefi');
659
+ }
660
+ // Direct swap methods for V6
661
+ getDirectParamV6(_srcToken, _destToken, _fromAmount, _toAmount, _quotedAmount, _data, _side, _permit, _uuid, _partnerAndFee, _beneficiary, _blockNumber, _contractMethod) {
662
+ // This method is not implemented for ApexDefi
663
+ throw new Error('Direct swaps not supported for ApexDefi');
664
+ }
665
+ // Static methods for direct function names
666
+ static getDirectFunctionName() {
667
+ // ApexDefi doesn't support direct swaps
668
+ return [];
669
+ }
670
+ static getDirectFunctionNameV6() {
671
+ // ApexDefi doesn't support direct swaps
672
+ return [];
673
+ }
674
+ // This is called once before getTopPoolsForToken is
675
+ // called for multiple tokens. This can be helpful to
676
+ // update common state required for calculating
677
+ // getTopPoolsForToken. It is optional for a DEX
678
+ // to implement this
679
+ async updatePoolState() {
680
+ // Update all existing pools to their latest state
681
+ const blockNumber = await this.dexHelper.web3Provider.eth.getBlockNumber();
682
+ const poolUpdatePromises = Object.values(this.eventPools).map(async (pool) => {
683
+ if (pool) {
684
+ try {
685
+ await pool.getStateOrGenerate(blockNumber);
686
+ }
687
+ catch (error) {
688
+ this.logger.error(`Error updating pool state for ${pool.poolAddress}:`, error);
689
+ }
690
+ }
691
+ });
692
+ await Promise.all(poolUpdatePromises);
693
+ }
694
+ // Returns list of top pools based on liquidity. Max
695
+ // limit number pools should be returned.
696
+ async getTopPoolsForToken(tokenAddress, limit) {
697
+ try {
698
+ const blockNumber = await this.dexHelper.web3Provider.eth.getBlockNumber();
699
+ // Check if this token has a wrapper
700
+ const tokenInfo = this.getERC314Token(tokenAddress);
701
+ const hasWrapper = tokenInfo.address !== tokenAddress;
702
+ // Use the underlying ERC314 token for pool lookups
703
+ const tokenToCheck = hasWrapper ? tokenInfo.address : tokenAddress;
704
+ // Check if the input token is AVAX
705
+ const isAVAX = (0, utils_1.isETHAddress)(tokenToCheck);
706
+ if (isAVAX) {
707
+ // If asking for AVAX pools, return all tokens that have AVAX pairs
708
+ const tokenAddresses = await this.dexHelper.multiContract.methods
709
+ .aggregate([
710
+ {
711
+ target: config_1.ApexDefiConfig[this.dexKey][this.network].factoryAddress,
712
+ callData: this.factoryIface.encodeFunctionData('getAllTokens', []),
713
+ },
714
+ ])
715
+ .call({}, blockNumber);
716
+ const tokens = this.factoryIface.decodeFunctionResult('getAllTokens', tokenAddresses.returnData[0])[0];
717
+ if (!tokens.length) {
718
+ return [];
719
+ }
720
+ // Get reserves for all tokens (limit to requested limit)
721
+ const reservesCallData = this.tokenIface.encodeFunctionData('getReserves', []);
722
+ const multiCall = tokens.map(token => ({
723
+ target: token,
724
+ callData: reservesCallData,
725
+ }));
726
+ const result = await this.dexHelper.multiContract.methods
727
+ .aggregate(multiCall)
728
+ .call({}, blockNumber);
729
+ const pools = [];
730
+ for (let i = 0; i < tokens.length; i++) {
731
+ const token = tokens[i];
732
+ const reserves = this.tokenIface.decodeFunctionResult('getReserves', result.returnData[i]);
733
+ // If reserves are 0, skip this pool
734
+ if (reserves[0] === 0n && reserves[1] === 0n) {
735
+ continue;
736
+ }
737
+ // Calculate liquidity in USD using getTokenUSDPrice
738
+ const liquidityUSD = await this.dexHelper.getTokenUSDPrice({
739
+ address: this.dexHelper.config.data.wrappedNativeTokenAddress,
740
+ decimals: 18,
741
+ }, reserves[0]);
742
+ pools.push({
743
+ exchange: this.dexKey,
744
+ address: token.toLowerCase(),
745
+ poolIdentifier: this.getPoolIdentifier(token),
746
+ connectorTokens: [
747
+ {
748
+ address: this.dexHelper.config.data.wrappedNativeTokenAddress.toLowerCase(),
749
+ decimals: 18,
750
+ },
751
+ ],
752
+ liquidityUSD,
753
+ });
754
+ }
755
+ // Sort by liquidity and return top pools
756
+ return pools
757
+ .sort((a, b) => b.liquidityUSD - a.liquidityUSD)
758
+ .slice(0, limit);
759
+ }
760
+ else {
761
+ // For non-AVAX tokens, check if they exist as a pool
762
+ const tokenInfo = await this.dexHelper.multiContract.methods
763
+ .aggregate([
764
+ {
765
+ target: config_1.ApexDefiConfig[this.dexKey][this.network].factoryAddress,
766
+ callData: this.factoryIface.encodeFunctionData('tokenInfoByTokenAddress', [tokenToCheck]),
767
+ },
768
+ {
769
+ target: tokenToCheck, // Use underlying token
770
+ callData: this.tokenIface.encodeFunctionData('getReserves', []),
771
+ },
772
+ ])
773
+ .call({}, blockNumber);
774
+ // Decode token info
775
+ const tokenData = this.factoryIface.decodeFunctionResult('tokenInfoByTokenAddress', tokenInfo.returnData[0]);
776
+ // If name is empty, the token doesn't exist in the factory
777
+ if (!tokenData[0] || tokenData[0] === '') {
778
+ return [];
779
+ }
780
+ // Decode reserves
781
+ const reserves = this.tokenIface.decodeFunctionResult('getReserves', tokenInfo.returnData[1]);
782
+ // If reserves are 0, the pool has no liquidity
783
+ if (reserves[0] === 0n && reserves[1] === 0n) {
784
+ return [];
785
+ }
786
+ // Calculate liquidity in USD using getTokenUSDPrice
787
+ const liquidityUSD = await this.dexHelper.getTokenUSDPrice({
788
+ address: this.dexHelper.config.data.wrappedNativeTokenAddress,
789
+ decimals: 18,
790
+ }, reserves[0]);
791
+ return [
792
+ {
793
+ exchange: this.dexKey,
794
+ address: tokenAddress.toLowerCase(), // Return original token address
795
+ poolIdentifier: this.getPoolIdentifier(tokenToCheck), // Use underlying token for pool ID
796
+ connectorTokens: [
797
+ {
798
+ address: this.dexHelper.config.data.wrappedNativeTokenAddress.toLowerCase(),
799
+ decimals: 18,
800
+ },
801
+ ],
802
+ liquidityUSD,
803
+ },
804
+ ];
805
+ }
806
+ }
807
+ catch (error) {
808
+ // If the call fails, the token doesn't exist as a pool
809
+ this.logger.debug(`Token ${tokenAddress} is not a valid ApexDefi pool: ${error}`);
810
+ return [];
811
+ }
812
+ }
813
+ // Shared logic for pool discovery/creation
814
+ async fetchAndInitPool(pairAddress, blockNumber, poolKey) {
815
+ try {
816
+ const poolData = await (0, utils_2.fetchApexDefiOnChainPoolData)(pairAddress, this.network, blockNumber, this.dexHelper, this.tokenIface, this.factoryIface, this.logger);
817
+ // No pool data found, return null
818
+ if (!poolData) {
819
+ return null;
820
+ }
821
+ const eventPool = new apex_defi_pool_1.ApexDefiEventPool(this.dexKey, this.network, this.dexHelper, this.dexHelper.config.data.wrappedNativeTokenAddress, pairAddress, pairAddress, this.logger, poolData.factoryAddress);
822
+ await eventPool.initialize(blockNumber, {
823
+ state: {
824
+ reserve0: poolData.reserve0,
825
+ reserve1: poolData.reserve1,
826
+ baseSwapRate: poolData.baseSwapRate,
827
+ protocolFee: poolData.protocolFee,
828
+ lpFee: poolData.lpFee,
829
+ tradingFee: poolData.tradingFee,
830
+ isLegacy: poolData.isLegacy,
831
+ tradingEnabled: poolData.tradingEnabled,
832
+ },
833
+ });
834
+ this.eventPools[poolKey] = eventPool;
835
+ return eventPool;
836
+ }
837
+ catch (error) {
838
+ this.logger.error('Error fetching/initializing pool:', error);
839
+ return null;
840
+ }
841
+ }
842
+ releaseResources() {
843
+ // Clean up event pools
844
+ Object.values(this.eventPools).forEach(pool => {
845
+ if (pool) {
846
+ pool.releaseResources();
847
+ }
848
+ });
849
+ // Clear the pools map
850
+ Object.keys(this.eventPools).forEach(key => {
851
+ delete this.eventPools[key];
852
+ });
853
+ // Clear supported tokens map
854
+ Object.keys(this.supportedTokensMap).forEach(key => {
855
+ delete this.supportedTokensMap[key];
856
+ });
857
+ // Clean up factory if it has releaseResources
858
+ if (this.factory && this.factory.releaseResources) {
859
+ this.factory.releaseResources();
860
+ }
861
+ // Clean up wrapper factory
862
+ if (this.wrapperFactory && this.wrapperFactory.releaseResources) {
863
+ this.wrapperFactory.releaseResources();
864
+ }
865
+ }
866
+ _getLoweredAddresses(srcToken, destToken) {
867
+ return [srcToken.address.toLowerCase(), destToken.address.toLowerCase()];
868
+ }
869
+ fixPathForRouter(path) {
870
+ return path.map(token => {
871
+ // Only convert native AVAX to WAVAX for router calls
872
+ if (token.toLowerCase() === constants_1.ETHER_ADDRESS.toLowerCase()) {
873
+ return this.dexHelper.config.data.wrappedNativeTokenAddress;
874
+ }
875
+ // Leave all other tokens as-is (including ERC20 tokens like USDC)
876
+ return token;
877
+ });
878
+ }
879
+ // Helper method to get ERC314 token for pricing/pools
880
+ // Simplified getERC314Token method - always return ERC314 token for pricing
881
+ getERC314Token(tokenAddress) {
882
+ // if token is AVAX, return AVAX
883
+ if ((0, utils_1.isETHAddress)(tokenAddress)) {
884
+ return {
885
+ address: tokenAddress,
886
+ decimals: 18,
887
+ };
888
+ }
889
+ // PRIORITY 1: Check if this is an original token (ERC20) that has a wrapper
890
+ const wrapperAddress = this.wrapperFactory.getWrapperByOriginalToken(tokenAddress);
891
+ if (wrapperAddress) {
892
+ const wrapperInfo = this.wrapperFactory.getWrapperInfo(wrapperAddress);
893
+ if (wrapperInfo) {
894
+ return {
895
+ address: wrapperInfo.wrappedToken,
896
+ decimals: wrapperInfo.wrappedTokenDecimals,
897
+ };
898
+ }
899
+ }
900
+ // PRIORITY 2: No wrapper found - this is a native ERC314 token (like APEX)
901
+ return {
902
+ address: tokenAddress,
903
+ decimals: 18,
904
+ };
905
+ }
906
+ // 2. Add decimal conversion helper methods
907
+ convertAmountToERC314(amount, fromDecimals, toDecimals) {
908
+ if (fromDecimals === toDecimals)
909
+ return amount;
910
+ if (fromDecimals > toDecimals) {
911
+ return amount / 10n ** BigInt(fromDecimals - toDecimals);
912
+ }
913
+ else {
914
+ return amount * 10n ** BigInt(toDecimals - fromDecimals);
915
+ }
916
+ }
917
+ convertAmountFromERC314(amount, fromDecimals, toDecimals) {
918
+ if (fromDecimals === toDecimals)
919
+ return amount;
920
+ if (fromDecimals > toDecimals) {
921
+ return amount / 10n ** BigInt(fromDecimals - toDecimals);
922
+ }
923
+ else {
924
+ return amount * 10n ** BigInt(toDecimals - fromDecimals);
925
+ }
926
+ }
927
+ convertAmountsToERC314(amounts, fromDecimals) {
928
+ return amounts.map(amount => {
929
+ if (amount === 0n)
930
+ return 0n;
931
+ return this.convertAmountToERC314(amount, fromDecimals, 18);
932
+ });
933
+ }
934
+ convertPricesFromERC314(prices, toDecimals) {
935
+ return prices.map(price => {
936
+ if (price === 0n)
937
+ return 0n;
938
+ return this.convertAmountFromERC314(price, 18, toDecimals);
939
+ });
940
+ }
941
+ // Simplified wrapper detection using helper
942
+ isWrapperOperation(srcToken, destToken) {
943
+ return this.wrapperFactory.isWrapperOperation(srcToken.address, destToken.address);
944
+ }
945
+ // Fixed wrapper prices to handle both SELL and BUY operations
946
+ getWrapperPrices(srcToken, destToken, amounts, side) {
947
+ const wrapperPairInfo = this.wrapperFactory.getWrapperPairInfo(srcToken.address, destToken.address);
948
+ if (!wrapperPairInfo) {
949
+ return [];
950
+ }
951
+ const { wrapperAddress, isWrap } = wrapperPairInfo;
952
+ const prices = amounts.map(amount => {
953
+ if (amount === 0n)
954
+ return 0n;
955
+ const isSell = side === constants_1.SwapSide.SELL;
956
+ const fromDecimals = isSell ? srcToken.decimals : destToken.decimals;
957
+ const toDecimals = isSell ? destToken.decimals : srcToken.decimals;
958
+ // For SELL: convert input to output
959
+ // For BUY: convert desired output to required input
960
+ return isWrap
961
+ ? this.convertAmountToERC314(amount, fromDecimals, toDecimals)
962
+ : this.convertAmountFromERC314(amount, fromDecimals, toDecimals);
963
+ });
964
+ const unit = (0, utils_1.getBigIntPow)(side === constants_1.SwapSide.SELL ? srcToken.decimals : destToken.decimals);
965
+ return [
966
+ {
967
+ prices,
968
+ unit,
969
+ data: {
970
+ path: [
971
+ {
972
+ tokenIn: srcToken.address.toLowerCase(),
973
+ tokenOut: destToken.address.toLowerCase(),
974
+ },
975
+ ],
976
+ swapType: 'wrapper',
977
+ wrapperAddress,
978
+ isWrap,
979
+ },
980
+ exchange: this.dexKey,
981
+ poolIdentifiers: [
982
+ `${this.dexKey}_wrapper_${srcToken.address.toLowerCase()}`,
983
+ ],
984
+ gasCost: 100000,
985
+ poolAddresses: [wrapperAddress],
986
+ },
987
+ ];
988
+ }
989
+ // Simplified wrapper swap
990
+ getWrapperSwap(_srcToken, _destToken, srcAmount, _destAmount, _recipient, data) {
991
+ const { wrapperAddress, isWrap } = data;
992
+ if (!wrapperAddress)
993
+ throw new Error('Wrapper address not found');
994
+ if (isWrap === undefined)
995
+ throw new Error('isWrap not found in data');
996
+ const swapFunction = isWrap ? 'wrap' : 'unwrap';
997
+ const swapParams = [srcAmount];
998
+ const exchangeData = this.wrapperIface.encodeFunctionData(swapFunction, swapParams);
999
+ return {
1000
+ needWrapNative: false,
1001
+ dexFuncHasRecipient: false,
1002
+ exchangeData,
1003
+ targetExchange: wrapperAddress,
1004
+ returnAmountPos: undefined,
1005
+ };
1006
+ }
1007
+ // Simplified wrapper simple param
1008
+ async getWrapperSimpleParam(srcToken, destToken, srcAmount, destAmount, data) {
1009
+ const { wrapperAddress, isWrap } = data;
1010
+ if (!wrapperAddress)
1011
+ throw new Error('Wrapper address not found');
1012
+ if (isWrap === undefined)
1013
+ throw new Error('isWrap not found in data');
1014
+ const swapFunction = isWrap ? 'wrap' : 'unwrap';
1015
+ const swapParams = [srcAmount];
1016
+ const swapData = this.wrapperIface.encodeFunctionData(swapFunction, swapParams);
1017
+ return this.buildSimpleParamWithoutWETHConversion(srcToken, srcAmount, destToken, destAmount, swapData, wrapperAddress, wrapperAddress, '0');
1018
+ }
1019
+ }
1020
+ exports.ApexDefi = ApexDefi;
1021
+ //# sourceMappingURL=apex-defi.js.map