@gearbox-protocol/sdk 14.12.0-next.66 → 14.12.0-next.68

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 (244) hide show
  1. package/dist/cjs/common-utils/index.js +2 -2
  2. package/dist/cjs/common-utils/utils/apy/calculate-safe-borrow-rate.js +3 -3
  3. package/dist/cjs/common-utils/utils/assets-math.js +7 -7
  4. package/dist/cjs/common-utils/utils/creditAccount/calc-health-factor.js +2 -2
  5. package/dist/cjs/common-utils/utils/creditAccount/debt.js +2 -2
  6. package/dist/cjs/common-utils/utils/creditAccount/quota-utils.js +5 -5
  7. package/dist/cjs/common-utils/utils/index.js +2 -2
  8. package/dist/cjs/common-utils/utils/strategies/leverage/calculate-max-leverage-factor.js +2 -2
  9. package/dist/cjs/common-utils/utils/strategies/leverage/calculate-max-strategy-debt.js +5 -5
  10. package/dist/cjs/common-utils/utils/strategies/strategy-info/calculate-total-points.js +2 -2
  11. package/dist/cjs/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.js +2 -2
  12. package/dist/cjs/common-utils/utils/validation/validate-open-account-pool-status.js +4 -4
  13. package/dist/cjs/model/history.js +28 -0
  14. package/dist/cjs/model/history.schema.js +84 -0
  15. package/dist/cjs/model/index.js +77 -0
  16. package/dist/cjs/model/liquidations.js +23 -0
  17. package/dist/cjs/model/liquidations.schema.js +93 -0
  18. package/dist/cjs/model/opportunities.js +55 -0
  19. package/dist/cjs/model/opportunities.schema.js +223 -0
  20. package/dist/cjs/model/package.json +1 -0
  21. package/dist/cjs/model/positions.js +1 -0
  22. package/dist/cjs/model/positions.schema.js +120 -0
  23. package/dist/cjs/model/primitives.js +1 -0
  24. package/dist/cjs/model/primitives.schema.js +85 -0
  25. package/dist/cjs/new-sdk/AbstractNamespace.js +158 -0
  26. package/dist/cjs/new-sdk/GearboxSDK.js +122 -0
  27. package/dist/cjs/new-sdk/index.js +11 -0
  28. package/dist/cjs/new-sdk/opportunities/OpportunitiesNamespace.js +122 -0
  29. package/dist/cjs/new-sdk/opportunities/index.js +4 -0
  30. package/dist/cjs/new-sdk/opportunities/types.js +1 -0
  31. package/dist/cjs/new-sdk/package.json +1 -0
  32. package/dist/cjs/new-sdk/types.js +22 -0
  33. package/dist/cjs/new-sdk/utils/history.js +1 -0
  34. package/dist/cjs/new-sdk/utils/index.js +2 -0
  35. package/dist/cjs/offchain/GearboxAPI.js +33 -0
  36. package/dist/cjs/offchain/index.js +8 -0
  37. package/dist/cjs/offchain/opportunities/OffchainOpportunities.js +97 -0
  38. package/dist/cjs/offchain/opportunities/index.js +4 -0
  39. package/dist/cjs/offchain/package.json +1 -0
  40. package/dist/cjs/offchain/types.js +1 -0
  41. package/dist/cjs/preview/preview/buildDelayedPreview.js +5 -5
  42. package/dist/cjs/rewards/rewards/api.js +2 -2
  43. package/dist/cjs/rewards/rewards/extra-apy.js +2 -2
  44. package/dist/cjs/sdk/MultichainSDK.js +18 -2
  45. package/dist/cjs/sdk/OnchainSDK.js +8 -1
  46. package/dist/cjs/sdk/accounts/index.js +2 -0
  47. package/dist/cjs/sdk/accounts/liquidations/LiquidationsService.js +161 -106
  48. package/dist/cjs/sdk/accounts/liquidations/MultichainLiquidationsService.js +32 -38
  49. package/dist/cjs/sdk/accounts/liquidations/constants.js +13 -0
  50. package/dist/cjs/sdk/accounts/liquidations/index.js +2 -0
  51. package/dist/cjs/sdk/base/MultichainConstruct.js +80 -0
  52. package/dist/cjs/sdk/base/TokensMeta.js +51 -0
  53. package/dist/cjs/sdk/base/index.js +2 -0
  54. package/dist/cjs/sdk/chain/chains.js +76 -0
  55. package/dist/cjs/sdk/chain/index.js +4 -0
  56. package/dist/cjs/sdk/core/errors.js +13 -0
  57. package/dist/cjs/sdk/core/index.js +2 -1
  58. package/dist/cjs/sdk/index.js +25 -1
  59. package/dist/cjs/sdk/market/MarketConfiguratorContract.js +14 -0
  60. package/dist/cjs/sdk/market/MarketSuite.js +159 -0
  61. package/dist/cjs/sdk/market/credit/CreditManagerV310Contract.js +26 -0
  62. package/dist/cjs/sdk/market/credit/CreditSuite.js +92 -0
  63. package/dist/cjs/sdk/market/math.js +104 -0
  64. package/dist/cjs/sdk/market/oracle/PriceOracleBaseContract.js +52 -0
  65. package/dist/cjs/sdk/market/pool/LinearInterestRateModelContract.js +30 -0
  66. package/dist/cjs/sdk/market/pool/PoolQuotaKeeperV310Contract.js +26 -0
  67. package/dist/cjs/sdk/market/pool/PoolSuite.js +28 -0
  68. package/dist/cjs/sdk/market/pool/PoolV310Contract.js +27 -0
  69. package/dist/cjs/sdk/market/pool/math.js +44 -0
  70. package/dist/cjs/sdk/market/pricefeeds/AbstractPriceFeed.js +17 -0
  71. package/dist/cjs/sdk/opportunities/MultichainOpportunitiesService.js +60 -0
  72. package/dist/cjs/sdk/opportunities/OpportunitiesService.js +48 -0
  73. package/dist/cjs/sdk/opportunities/index.js +12 -0
  74. package/dist/cjs/sdk/types/multichain.js +1 -0
  75. package/dist/cjs/{common-utils → sdk}/utils/bigint-math.js +11 -11
  76. package/dist/cjs/sdk/utils/index.js +3 -0
  77. package/dist/cjs/sdk/utils/zod.js +12 -0
  78. package/dist/esm/common-utils/index.js +1 -1
  79. package/dist/esm/common-utils/utils/apy/calculate-safe-borrow-rate.js +1 -1
  80. package/dist/esm/common-utils/utils/assets-math.js +1 -1
  81. package/dist/esm/common-utils/utils/creditAccount/calc-health-factor.js +1 -1
  82. package/dist/esm/common-utils/utils/creditAccount/debt.js +1 -1
  83. package/dist/esm/common-utils/utils/creditAccount/quota-utils.js +1 -1
  84. package/dist/esm/common-utils/utils/index.js +1 -1
  85. package/dist/esm/common-utils/utils/strategies/leverage/calculate-max-leverage-factor.js +1 -1
  86. package/dist/esm/common-utils/utils/strategies/leverage/calculate-max-strategy-debt.js +1 -1
  87. package/dist/esm/common-utils/utils/strategies/strategy-info/calculate-total-points.js +1 -1
  88. package/dist/esm/common-utils/utils/strategies/strategy-info/get-cm-you-can-earn.js +1 -1
  89. package/dist/esm/common-utils/utils/validation/validate-open-account-pool-status.js +1 -1
  90. package/dist/esm/dev/AccountOpener.js +1 -1
  91. package/dist/esm/dev/withdrawalUtils.js +1 -1
  92. package/dist/esm/model/history.js +26 -0
  93. package/dist/esm/model/history.schema.js +76 -0
  94. package/dist/esm/model/index.js +11 -0
  95. package/dist/esm/model/liquidations.js +22 -0
  96. package/dist/esm/model/liquidations.schema.js +85 -0
  97. package/dist/esm/model/opportunities.js +51 -0
  98. package/dist/esm/model/opportunities.schema.js +201 -0
  99. package/dist/esm/model/package.json +1 -0
  100. package/dist/esm/model/positions.js +1 -0
  101. package/dist/esm/model/positions.schema.js +109 -0
  102. package/dist/esm/model/primitives.js +1 -0
  103. package/dist/esm/model/primitives.schema.js +75 -0
  104. package/dist/esm/new-sdk/AbstractNamespace.js +157 -0
  105. package/dist/esm/new-sdk/GearboxSDK.js +121 -0
  106. package/dist/esm/new-sdk/index.js +7 -0
  107. package/dist/esm/new-sdk/opportunities/OpportunitiesNamespace.js +121 -0
  108. package/dist/esm/new-sdk/opportunities/index.js +3 -0
  109. package/dist/esm/new-sdk/opportunities/types.js +1 -0
  110. package/dist/esm/new-sdk/package.json +1 -0
  111. package/dist/esm/new-sdk/types.js +21 -0
  112. package/dist/esm/new-sdk/utils/history.js +1 -0
  113. package/dist/esm/new-sdk/utils/index.js +2 -0
  114. package/dist/esm/offchain/GearboxAPI.js +32 -0
  115. package/dist/esm/offchain/index.js +5 -0
  116. package/dist/esm/offchain/opportunities/OffchainOpportunities.js +95 -0
  117. package/dist/esm/offchain/opportunities/index.js +2 -0
  118. package/dist/esm/offchain/package.json +1 -0
  119. package/dist/esm/offchain/types.js +1 -0
  120. package/dist/esm/preview/preview/buildDelayedPreview.js +1 -1
  121. package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
  122. package/dist/esm/preview/trace/extractTransfers.js +1 -1
  123. package/dist/esm/rewards/rewards/api.js +1 -1
  124. package/dist/esm/rewards/rewards/extra-apy.js +1 -1
  125. package/dist/esm/sdk/MultichainSDK.js +18 -2
  126. package/dist/esm/sdk/OnchainSDK.js +8 -1
  127. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +2 -2
  128. package/dist/esm/sdk/accounts/index.js +2 -2
  129. package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +164 -109
  130. package/dist/esm/sdk/accounts/liquidations/MultichainLiquidationsService.js +32 -38
  131. package/dist/esm/sdk/accounts/liquidations/constants.js +12 -1
  132. package/dist/esm/sdk/accounts/liquidations/index.js +2 -2
  133. package/dist/esm/sdk/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  134. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  135. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  136. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  137. package/dist/esm/sdk/base/MultichainConstruct.js +79 -0
  138. package/dist/esm/sdk/base/TokensMeta.js +53 -2
  139. package/dist/esm/sdk/base/index.js +2 -1
  140. package/dist/esm/sdk/chain/chains.js +74 -2
  141. package/dist/esm/sdk/chain/detectNetwork.js +1 -1
  142. package/dist/esm/sdk/chain/index.js +2 -2
  143. package/dist/esm/sdk/core/createAddressProvider.js +1 -1
  144. package/dist/esm/sdk/core/errors.js +13 -1
  145. package/dist/esm/sdk/core/index.js +2 -2
  146. package/dist/esm/sdk/index.js +11 -5
  147. package/dist/esm/sdk/market/MarketConfiguratorContract.js +14 -0
  148. package/dist/esm/sdk/market/MarketSuite.js +159 -0
  149. package/dist/esm/sdk/market/credit/CreditFacadeV310BaseContract.js +1 -1
  150. package/dist/esm/sdk/market/credit/CreditManagerV310Contract.js +26 -0
  151. package/dist/esm/sdk/market/credit/CreditSuite.js +92 -0
  152. package/dist/esm/sdk/market/math.js +98 -0
  153. package/dist/esm/sdk/market/oracle/PriceOracleBaseContract.js +52 -0
  154. package/dist/esm/sdk/market/pool/LinearInterestRateModelContract.js +30 -0
  155. package/dist/esm/sdk/market/pool/PoolQuotaKeeperV310Contract.js +26 -0
  156. package/dist/esm/sdk/market/pool/PoolSuite.js +28 -0
  157. package/dist/esm/sdk/market/pool/PoolV310Contract.js +28 -1
  158. package/dist/esm/sdk/market/pool/math.js +41 -0
  159. package/dist/esm/sdk/market/pricefeeds/AbstractPriceFeed.js +17 -0
  160. package/dist/esm/sdk/market/zapper/IETHZapperContract.js +1 -1
  161. package/dist/esm/sdk/market/zapper/ZapperContract.js +1 -1
  162. package/dist/esm/sdk/opportunities/MultichainOpportunitiesService.js +59 -0
  163. package/dist/esm/sdk/opportunities/OpportunitiesService.js +47 -0
  164. package/dist/esm/sdk/opportunities/index.js +4 -0
  165. package/dist/esm/sdk/pools/PoolService.js +1 -1
  166. package/dist/esm/sdk/types/multichain.js +1 -0
  167. package/dist/esm/{common-utils → sdk}/utils/bigint-math.js +11 -11
  168. package/dist/esm/sdk/utils/index.js +3 -2
  169. package/dist/esm/sdk/utils/viem/simulateWithPriceUpdates.js +1 -1
  170. package/dist/esm/sdk/utils/zod.js +13 -2
  171. package/dist/types/common-utils/index.d.ts +1 -1
  172. package/dist/types/common-utils/utils/index.d.ts +1 -1
  173. package/dist/types/model/history.d.ts +105 -0
  174. package/dist/types/model/history.schema.d.ts +66 -0
  175. package/dist/types/model/index.d.ts +11 -0
  176. package/dist/types/model/liquidations.d.ts +238 -0
  177. package/dist/types/model/liquidations.schema.d.ts +294 -0
  178. package/dist/types/model/opportunities.d.ts +584 -0
  179. package/dist/types/model/opportunities.schema.d.ts +1037 -0
  180. package/dist/types/model/positions.d.ts +247 -0
  181. package/dist/types/model/positions.schema.d.ts +701 -0
  182. package/dist/types/model/primitives.d.ts +194 -0
  183. package/dist/types/model/primitives.schema.d.ts +81 -0
  184. package/dist/types/new-sdk/AbstractNamespace.d.ts +119 -0
  185. package/dist/types/new-sdk/GearboxSDK.d.ts +78 -0
  186. package/dist/types/new-sdk/index.d.ts +9 -0
  187. package/dist/types/new-sdk/opportunities/OpportunitiesNamespace.d.ts +69 -0
  188. package/dist/types/new-sdk/opportunities/index.d.ts +3 -0
  189. package/dist/types/new-sdk/opportunities/types.d.ts +66 -0
  190. package/dist/types/new-sdk/types.d.ts +149 -0
  191. package/dist/types/new-sdk/utils/history.d.ts +44 -0
  192. package/dist/types/new-sdk/utils/index.d.ts +2 -0
  193. package/dist/types/offchain/GearboxAPI.d.ts +31 -0
  194. package/dist/types/offchain/index.d.ts +5 -0
  195. package/dist/types/offchain/opportunities/OffchainOpportunities.d.ts +69 -0
  196. package/dist/types/offchain/opportunities/index.d.ts +2 -0
  197. package/dist/types/offchain/types.d.ts +50 -0
  198. package/dist/types/sdk/MultichainSDK.d.ts +15 -2
  199. package/dist/types/sdk/OnchainSDK.d.ts +9 -3
  200. package/dist/types/sdk/accounts/index.d.ts +3 -3
  201. package/dist/types/sdk/accounts/liquidations/LiquidationsService.d.ts +24 -16
  202. package/dist/types/sdk/accounts/liquidations/MultichainLiquidationsService.d.ts +26 -20
  203. package/dist/types/sdk/accounts/liquidations/constants.d.ts +12 -1
  204. package/dist/types/sdk/accounts/liquidations/index.d.ts +3 -3
  205. package/dist/types/sdk/accounts/liquidations/types.d.ts +34 -309
  206. package/dist/types/sdk/base/MultichainConstruct.d.ts +57 -0
  207. package/dist/types/sdk/base/TokensMeta.d.ts +26 -0
  208. package/dist/types/sdk/base/index.d.ts +2 -1
  209. package/dist/types/sdk/chain/chains.d.ts +68 -1
  210. package/dist/types/sdk/chain/index.d.ts +2 -2
  211. package/dist/types/sdk/core/errors.d.ts +10 -1
  212. package/dist/types/sdk/core/index.d.ts +2 -2
  213. package/dist/types/sdk/index.d.ts +15 -8
  214. package/dist/types/sdk/market/MarketConfiguratorContract.d.ts +9 -0
  215. package/dist/types/sdk/market/MarketSuite.d.ts +98 -1
  216. package/dist/types/sdk/market/credit/CreditManagerV310Contract.d.ts +14 -0
  217. package/dist/types/sdk/market/credit/CreditSuite.d.ts +43 -0
  218. package/dist/types/sdk/market/credit/types.d.ts +22 -0
  219. package/dist/types/sdk/market/index.d.ts +2 -2
  220. package/dist/types/sdk/market/math.d.ts +74 -0
  221. package/dist/types/sdk/market/oracle/PriceOracleBaseContract.d.ts +23 -0
  222. package/dist/types/sdk/market/oracle/types.d.ts +46 -0
  223. package/dist/types/sdk/market/pool/LinearInterestRateModelContract.d.ts +12 -0
  224. package/dist/types/sdk/market/pool/PoolQuotaKeeperV310Contract.d.ts +22 -1
  225. package/dist/types/sdk/market/pool/PoolSuite.d.ts +23 -0
  226. package/dist/types/sdk/market/pool/PoolV310Contract.d.ts +18 -0
  227. package/dist/types/sdk/market/pool/math.d.ts +57 -0
  228. package/dist/types/sdk/market/pool/types.d.ts +23 -0
  229. package/dist/types/sdk/market/pricefeeds/AbstractPriceFeed.d.ts +6 -0
  230. package/dist/types/sdk/market/pricefeeds/types.d.ts +10 -0
  231. package/dist/types/sdk/opportunities/MultichainOpportunitiesService.d.ts +40 -0
  232. package/dist/types/sdk/opportunities/OpportunitiesService.d.ts +42 -0
  233. package/dist/types/sdk/opportunities/index.d.ts +4 -0
  234. package/dist/types/sdk/types/index.d.ts +2 -1
  235. package/dist/types/sdk/types/multichain.d.ts +65 -0
  236. package/dist/types/sdk/types/state.d.ts +1 -1
  237. package/dist/types/sdk/types/transactions.d.ts +3 -0
  238. package/dist/types/{common-utils → sdk}/utils/bigint-math.d.ts +7 -11
  239. package/dist/types/sdk/utils/index.d.ts +3 -2
  240. package/dist/types/sdk/utils/zod.d.ts +6 -2
  241. package/package.json +16 -1
  242. package/dist/cjs/sdk/accounts/liquidations/helpers.js +0 -201
  243. package/dist/esm/sdk/accounts/liquidations/helpers.js +0 -192
  244. package/dist/types/sdk/accounts/liquidations/helpers.d.ts +0 -140
@@ -1,6 +1,6 @@
1
- import { ierc20Abi } from "../../abi/iERC20.js";
2
1
  import { iCreditFacadeV310Abi } from "../../abi/310/generated.js";
3
2
  import { AddressMap } from "../../sdk/utils/AddressMap.js";
3
+ import { ierc20Abi } from "../../abi/iERC20.js";
4
4
  import "../../sdk/index.js";
5
5
  import { UnexpectedFacadeEventOrderError } from "./errors.js";
6
6
  import { getAddress, isAddressEqual, parseEventLogs } from "viem";
@@ -1,7 +1,7 @@
1
+ import { BigIntMath } from "../../sdk/utils/bigint-math.js";
1
2
  import { chains } from "../../sdk/chain/chains.js";
2
3
  import { toBigInt } from "../../sdk/utils/formatter.js";
3
4
  import "../../sdk/index.js";
4
- import { BigIntMath } from "../../common-utils/utils/bigint-math.js";
5
5
  import "../../common-utils/index.js";
6
6
  import { MerkleXYZApi } from "./merkl-api.js";
7
7
  import { getAddress } from "viem";
@@ -1,8 +1,8 @@
1
+ import { BigIntMath } from "../../sdk/utils/bigint-math.js";
1
2
  import { chains } from "../../sdk/chain/chains.js";
2
3
  import { PERCENTAGE_FACTOR } from "../../sdk/constants/math.js";
3
4
  import { toBN } from "../../sdk/utils/formatter.js";
4
5
  import "../../sdk/index.js";
5
- import { BigIntMath } from "../../common-utils/utils/bigint-math.js";
6
6
  import "../../common-utils/index.js";
7
7
  import axios from "axios";
8
8
  //#region src/rewards/rewards/extra-apy.ts
@@ -1,10 +1,12 @@
1
1
  import { getNetworkType } from "./chain/chains.js";
2
+ import { ChainNotConfiguredError, SdkMissingChainStateError, SdkStateVersionMismatchError, SdkSyncFailedError } from "./core/errors.js";
2
3
  import { PriceUpdatesCache } from "./market/pricefeeds/updates/PriceUpdatesCache.js";
3
4
  import "./market/pricefeeds/updates/index.js";
4
5
  import { MultichainLiquidationsService } from "./accounts/liquidations/MultichainLiquidationsService.js";
5
6
  import "./accounts/index.js";
6
- import { SdkMissingChainStateError, SdkStateVersionMismatchError, SdkSyncFailedError } from "./core/errors.js";
7
7
  import "./core/index.js";
8
+ import { MultichainOpportunitiesService } from "./opportunities/MultichainOpportunitiesService.js";
9
+ import "./opportunities/index.js";
8
10
  import { OnchainSDK } from "./OnchainSDK.js";
9
11
  //#region src/sdk/MultichainSDK.ts
10
12
  /**
@@ -22,6 +24,11 @@ var MultichainSDK = class {
22
24
  * configured chains.
23
25
  */
24
26
  liquidations;
27
+ /**
28
+ * Namespace for the pool and strategy opportunities of all configured
29
+ * chains.
30
+ */
31
+ opportunities;
25
32
  constructor(options) {
26
33
  this.#chains = /* @__PURE__ */ new Map();
27
34
  this.#logger = options.logger;
@@ -39,6 +46,7 @@ var MultichainSDK = class {
39
46
  this.#chains.set(network, sdk);
40
47
  }
41
48
  this.liquidations = new MultichainLiquidationsService(this);
49
+ this.opportunities = new MultichainOpportunitiesService(this);
42
50
  }
43
51
  /**
44
52
  * Attach all configured chains in parallel.
@@ -127,7 +135,7 @@ var MultichainSDK = class {
127
135
  if (typeof networkOrChainId === "number") network = getNetworkType(networkOrChainId);
128
136
  else network = networkOrChainId;
129
137
  const sdk = this.#chains.get(network);
130
- if (!sdk) throw new Error(`Chain ${String(networkOrChainId)} is not configured in this MultichainSDK`);
138
+ if (!sdk) throw new ChainNotConfiguredError(networkOrChainId);
131
139
  return sdk;
132
140
  }
133
141
  /**
@@ -137,6 +145,14 @@ var MultichainSDK = class {
137
145
  return this.#chains;
138
146
  }
139
147
  /**
148
+ * Shared logger, used for messages that are not attributable to a single
149
+ * chain. Per-chain messages should use the logger of the corresponding
150
+ * {@link OnchainSDK}.
151
+ **/
152
+ get logger() {
153
+ return this.#logger;
154
+ }
155
+ /**
140
156
  * Sync state for all chains in parallel.
141
157
  *
142
158
  * @param opts - Sync options.
@@ -8,6 +8,7 @@ import { formatTimestamp } from "./utils/formatter.js";
8
8
  import { toAddress } from "./utils/toAddress.js";
9
9
  import "./utils/index.js";
10
10
  import { ChainContractsRegister } from "./base/ChainContractsRegister.js";
11
+ import { SdkAlreadyAttachedError, SdkChainMismatchError, SdkNotAttachedError, SdkStateVersionMismatchError } from "./core/errors.js";
11
12
  import "./base/index.js";
12
13
  import { executeDelegatedMulticalls } from "./utils/viem/executeDelegatedMulticalls.js";
13
14
  import "./utils/viem/index.js";
@@ -22,8 +23,9 @@ import { createRedemptionLogger } from "./accounts/withdrawal-compressor/createR
22
23
  import { createWithdrawalCompressor } from "./accounts/withdrawal-compressor/createWithdrawalCompressor.js";
23
24
  import "./accounts/index.js";
24
25
  import { createAddressProvider, hydrateAddressProvider } from "./core/createAddressProvider.js";
25
- import { SdkAlreadyAttachedError, SdkChainMismatchError, SdkNotAttachedError, SdkStateVersionMismatchError } from "./core/errors.js";
26
26
  import "./core/index.js";
27
+ import { OpportunitiesService } from "./opportunities/OpportunitiesService.js";
28
+ import "./opportunities/index.js";
27
29
  import { PluginStateVersionError } from "./plugins/errors.js";
28
30
  import "./plugins/index.js";
29
31
  import { PoolService } from "./pools/PoolService.js";
@@ -106,6 +108,10 @@ var OnchainSDK = class extends ChainContractsRegister {
106
108
  */
107
109
  liquidations;
108
110
  /**
111
+ * Namespace for the pool and strategy opportunities of this chain.
112
+ */
113
+ opportunities;
114
+ /**
109
115
  * @param network - Gearbox network type (e.g. `"Mainnet"`, `"Monad"`).
110
116
  * @param clientOptions - Connection options (RPC URLs, transport, or client).
111
117
  * @param options - SDK configuration options.
@@ -126,6 +132,7 @@ var OnchainSDK = class extends ChainContractsRegister {
126
132
  this.accounts = new CreditAccountsServiceV310(this);
127
133
  this.pools = new PoolService(this);
128
134
  this.liquidations = new LiquidationsService(this);
135
+ this.opportunities = new OpportunitiesService(this);
129
136
  this.#withdrawalCompressor = createWithdrawalCompressor(this);
130
137
  }
131
138
  /**
@@ -1,9 +1,9 @@
1
- import { iBaseRewardPoolAbi } from "../../abi/iBaseRewardPool.js";
2
- import { ierc4626AdapterAbi } from "../../abi/ierc4626Adapter.js";
3
1
  import { iBotListV310Abi, iCreditFacadeMulticallV310Abi } from "../../abi/310/generated.js";
4
2
  import { creditAccountCompressorAbi } from "../../abi/compressors/creditAccountCompressor.js";
5
3
  import { peripheryCompressorAbi } from "../../abi/compressors/peripheryCompressor.js";
6
4
  import { rewardsCompressorAbi } from "../../abi/compressors/rewardsCompressor.js";
5
+ import { iBaseRewardPoolAbi } from "../../abi/iBaseRewardPool.js";
6
+ import { ierc4626AdapterAbi } from "../../abi/ierc4626Adapter.js";
7
7
  import { iRWAFactoryAbi } from "../../abi/rwa/iRWAFactory.js";
8
8
  import { AddressMap } from "../utils/AddressMap.js";
9
9
  import { AddressSet } from "../utils/AddressSet.js";
@@ -1,5 +1,5 @@
1
1
  import { CreditAccountsServiceV310 } from "./CreditAccountsServiceV310.js";
2
- import { LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./liquidations/constants.js";
2
+ import { DUST_THRESHOLD, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./liquidations/constants.js";
3
3
  import { LiquidationsService } from "./liquidations/LiquidationsService.js";
4
4
  import { MultichainLiquidationsService } from "./liquidations/MultichainLiquidationsService.js";
5
5
  import "./liquidations/index.js";
@@ -16,4 +16,4 @@ import { toWithdrawalStatus } from "./withdrawal-compressor/types.js";
16
16
  import { WithdrawalCompressorV313Contract } from "./withdrawal-compressor/WithdrawalCompressorV313Contract.js";
17
17
  import { createWithdrawalCompressor } from "./withdrawal-compressor/createWithdrawalCompressor.js";
18
18
  import "./withdrawal-compressor/index.js";
19
- export { AbstractWithdrawalCompressorContract, CreditAccountsServiceV310, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, InvalidDelayedIntentError, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LiquidationsService, MultichainLiquidationsService, RedemptionLoggerV310Contract, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, createRedemptionLogger, createWithdrawalCompressor, decodeDelayedIntent, encodeDelayedIntent, getWithdrawalCompressorAddress, iCreditAccountAbi, toClaimableWithdrawal, toPendingWithdrawal, toRequestableWithdrawal, toWithdrawalStatus };
19
+ export { AbstractWithdrawalCompressorContract, CreditAccountsServiceV310, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, DUST_THRESHOLD, InvalidDelayedIntentError, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, LiquidationsService, MultichainLiquidationsService, RedemptionLoggerV310Contract, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, createRedemptionLogger, createWithdrawalCompressor, decodeDelayedIntent, encodeDelayedIntent, getWithdrawalCompressorAddress, iCreditAccountAbi, toClaimableWithdrawal, toPendingWithdrawal, toRequestableWithdrawal, toWithdrawalStatus };
@@ -1,109 +1,116 @@
1
- import { iLiquidationCompressorV313Abi } from "../../../abi/ILiquidationCompressorV313.js";
2
1
  import { AddressSet } from "../../utils/AddressSet.js";
3
2
  import { bytes32ToString } from "../../utils/bytes32ToString.js";
4
3
  import { ADDRESS_0X0 } from "../../constants/addresses.js";
5
- import { WAD } from "../../constants/math.js";
4
+ import { PERCENTAGE_FACTOR, WAD } from "../../constants/math.js";
6
5
  import "../../constants/index.js";
7
6
  import { hexEq } from "../../utils/hex.js";
8
7
  import "../../utils/index.js";
9
8
  import { SDKConstruct } from "../../base/SDKConstruct.js";
10
9
  import "../../base/index.js";
10
+ import { usdToNumber } from "../../market/math.js";
11
+ import { matchesLiquidatableAccountFilter } from "../../../model/liquidations.js";
12
+ import "../../../model/index.js";
11
13
  import { RWA_LIQUIDATOR_MIDAS } from "../../market/rwa/midas/constants.js";
12
14
  import { MidasLiquidatorContract } from "../../market/rwa/midas/MidasLiquidatorContract.js";
13
15
  import "../../market/rwa/midas/index.js";
14
16
  import { RWA_LIQUIDATOR_SECURITIZE } from "../../market/rwa/securitize/constants.js";
15
17
  import { SecuritizeLiquidatorContract } from "../../market/rwa/securitize/SecuritizeLiquidatorContract.js";
16
18
  import "../../market/rwa/securitize/index.js";
17
- import { LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./constants.js";
18
- import { calcEstimatedProfit, calcRepaymentAmount, liquidationCallToRawTx, pickMainAsset, toLiquidationApproval, toLiquidatorWithdrawals, toReceivedAssets } from "./helpers.js";
19
+ import { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./constants.js";
20
+ import { iLiquidationCompressorV313Abi } from "../../../abi/ILiquidationCompressorV313.js";
19
21
  //#region src/sdk/accounts/liquidations/LiquidationsService.ts
20
22
  /**
21
- * Per-chain implementation of {@link ILiquidationsService}.
22
- *
23
- * Discovers liquidatable credit accounts (health factor below 1 plus accounts
24
- * of expired credit managers with outstanding debt) and previews what a
25
- * manual liquidation pays and receives.
23
+ * Service for discovering liquidatable credit accounts and previewing manual
24
+ * liquidations.
26
25
  **/
27
26
  var LiquidationsService = class extends SDKConstruct {
28
27
  /**
29
- * {@inheritDoc ILiquidationsService.getLiquidatableAccounts}
28
+ * Returns all liquidatable credit accounts: accounts with health factor
29
+ * below 1 plus accounts of expired credit managers with outstanding debt.
30
+ * Accounts whose collateral computation failed are excluded.
30
31
  **/
31
32
  async getLiquidatableAccounts(props) {
32
33
  await this.sdk.withdrawalCompressor?.loadWithdrawableAssets();
33
- const accounts = await this.sdk.accounts.getCreditAccounts({
34
+ const unhealthy = await this.sdk.accounts.getCreditAccounts({
34
35
  maxHealthFactor: WAD - 1n,
35
36
  includeZeroDebt: false
36
37
  });
37
- const seen = new AddressSet(accounts.map((ca) => ca.creditAccount));
38
- for (const ca of await this.#getExpiredCreditAccounts()) if (!seen.has(ca.creditAccount)) {
39
- seen.add(ca.creditAccount);
40
- accounts.push(ca);
41
- }
42
- const rows = [];
43
- for (const ca of accounts) {
44
- if (!ca.success) continue;
45
- rows.push(this.#buildAccount(ca));
46
- }
47
- const allowedAssets = props?.assets?.length ? new AddressSet(props.assets) : void 0;
48
- return rows.filter((row) => {
49
- if (props?.delayed !== void 0 && row.isDelayed !== props.delayed) return false;
50
- if (allowedAssets && !allowedAssets.has(row.asset)) return false;
51
- return true;
52
- });
38
+ const seen = new AddressSet(unhealthy.map((ca) => ca.creditAccount));
39
+ let expired = await this.#getExpiredCreditAccounts();
40
+ expired = expired.filter((ca) => !seen.has(ca.creditAccount));
41
+ return [...unhealthy, ...expired].flatMap((ca) => {
42
+ if (!ca.success) {
43
+ this.logger?.warn(`cannot compute liquidation details for ${ca.creditAccount}: collateral computation failed`);
44
+ return [];
45
+ }
46
+ return [this.#buildAccount(ca)];
47
+ }).filter((row) => matchesLiquidatableAccountFilter(row, props));
53
48
  }
54
49
  /**
55
- * {@inheritDoc ILiquidationsService.getLiquidationDetails}
50
+ * Returns detailed information about a liquidatable credit account,
51
+ * including the full list of assets the liquidator receives.
52
+ *
53
+ * @throws When the account is not found or its collateral computation fails.
56
54
  **/
57
55
  async getLiquidationDetails(props) {
58
56
  const { creditAccount, liquidator, ignoreReservePrices } = props;
59
57
  const ca = await this.#getCreditAccountData(creditAccount);
58
+ const suite = this.sdk.marketRegister.findCreditManager(ca.creditManager);
59
+ const { priceOracle } = suite.market;
60
60
  await this.sdk.withdrawalCompressor?.loadWithdrawableAssets();
61
- const account = this.#buildAccount(ca);
61
+ const account = this.#buildAccount(ca, suite);
62
62
  const data = await this.#getLiquidationData(ca, liquidator, ignoreReservePrices);
63
- const suite = this.sdk.marketRegister.findCreditManager(ca.creditManager);
64
63
  return {
65
64
  ...account,
66
- repaymentAmount: {
67
- token: hexEq(data.requiredToken, "0x0000000000000000000000000000000000000000") ? account.totalValue.token : data.requiredToken,
68
- balance: data.requiredAmount
69
- },
65
+ repaymentAmount: priceOracle.toTokenAmount(hexEq(data.requiredToken, "0x0000000000000000000000000000000000000000") ? account.totalValue.token.address : data.requiredToken, data.requiredAmount),
70
66
  isDelayed: data.expectedOutputs.some((o) => o.delayed),
71
- receivedAssets: toReceivedAssets(data.expectedOutputs),
67
+ receivedAssets: this.#receivedAssets(data.expectedOutputs, priceOracle),
72
68
  isLiquidatorEligible: data.isLiquidatorEligible,
73
69
  isCreditAccountFrozen: data.isCreditAccountFrozen,
74
70
  kycProtocol: data.kycProtocol || void 0,
75
- kycToken: hexEq(data.kycToken, "0x0000000000000000000000000000000000000000") ? void 0 : data.kycToken,
76
- approve: toLiquidationApproval({
77
- target: data.liquidationCall.target,
78
- creditFacade: suite.creditFacade.address,
79
- creditManager: ca.creditManager,
80
- token: data.requiredToken,
81
- amount: data.requiredAmount
82
- })
71
+ kycToken: hexEq(data.kycToken, "0x0000000000000000000000000000000000000000") ? void 0 : this.sdk.tokensMeta.getToken(data.kycToken),
72
+ approve: this.#liquidationApproval(data, suite, priceOracle)
83
73
  };
84
74
  }
85
75
  /**
86
- * {@inheritDoc ILiquidationsService.buildLiquidationTx}
76
+ * Builds the transaction that fully liquidates a credit account, repaying
77
+ * the debt from own funds and receiving the collateral from the credit account.
87
78
  **/
88
79
  async buildLiquidationTx(props) {
89
80
  const { creditAccount, liquidator, ignoreReservePrices } = props;
90
81
  const ca = await this.#getCreditAccountData(creditAccount);
91
- const data = await this.#getLiquidationData(ca, liquidator, ignoreReservePrices);
92
- return liquidationCallToRawTx(data.liquidationCall, `liquidate credit account ${this.labelAddress(creditAccount)} to ${this.labelAddress(liquidator)}`);
82
+ const { liquidationCall } = await this.#getLiquidationData(ca, liquidator, ignoreReservePrices);
83
+ this.logger?.debug(`built tx to liquidate credit account ${this.labelAddress(creditAccount)} to ${this.labelAddress(liquidator)}`);
84
+ return {
85
+ to: liquidationCall.target,
86
+ callData: liquidationCall.callData
87
+ };
93
88
  }
94
89
  /**
95
- * {@inheritDoc ILiquidationsService.getLiquidatorWithdrawals}
90
+ * Returns the status of delayed-withdrawal positions (redemption receipts)
91
+ * owned by a liquidator wallet: what is receivable, how much, and when it
92
+ * becomes claimable.
96
93
  **/
97
- async getLiquidatorWithdrawals(props) {
94
+ async getLiquidationPositions(props) {
98
95
  const compressor = this.sdk.withdrawalCompressor;
99
96
  if (!compressor) return [];
100
97
  await compressor.loadWithdrawableAssets();
101
98
  const phantomTokens = new AddressSet(compressor.getWithdrawableAssets().map((a) => a.withdrawalPhantomToken));
102
- const current = await compressor.getExternalAccountCurrentWithdrawals(props.liquidator, ...phantomTokens.asArray());
103
- return toLiquidatorWithdrawals(current, this.sdk.networkType, this.sdk.chainId);
99
+ const { claimable, pending } = await compressor.getExternalAccountCurrentWithdrawals(props.liquidator, ...phantomTokens.asArray());
100
+ return [...claimable.map((w) => ({
101
+ ...this.#liquidationPosition(w.token, w.outputs),
102
+ claimTx: this.#claimTx(w.claimCalls, w.token),
103
+ redeemer: w.redeemer
104
+ })), ...pending.map((w) => ({
105
+ ...this.#liquidationPosition(w.token, w.expectedOutputs),
106
+ claimableAt: Number(w.claimableAt),
107
+ redeemer: w.redeemer
108
+ }))];
104
109
  }
105
110
  /**
106
- * {@inheritDoc ILiquidationsService.loadRWALiquidators}
111
+ * Discovers the dedicated RWA liquidator contracts (Securitize, Midas)
112
+ * deployed for the markets of the chain and registers them in the SDK
113
+ * contracts register.
107
114
  **/
108
115
  async loadRWALiquidators() {
109
116
  const configurators = this.sdk.marketRegister.marketConfigurators;
@@ -120,14 +127,6 @@ var LiquidationsService = class extends SDKConstruct {
120
127
  });
121
128
  for (const info of resp.flat()) this.#createRWALiquidator(info);
122
129
  }
123
- /**
124
- * Instantiates the liquidator contract, which registers it and labels its
125
- * address (see `BaseContract`).
126
- *
127
- * @param info - Liquidator discovered by the compressor. The same gateway
128
- * can be configured in several credit managers, so duplicates are expected
129
- * and skipped.
130
- **/
131
130
  #createRWALiquidator(info) {
132
131
  const liquidator = info.liquidatorAddress;
133
132
  if (this.sdk.getContract(liquidator)) return;
@@ -142,20 +141,80 @@ var LiquidationsService = class extends SDKConstruct {
142
141
  return;
143
142
  }
144
143
  }
144
+ #anyMarketTokenAmount(token, value) {
145
+ const meta = this.sdk.tokensMeta.mustGetToken(token);
146
+ for (const market of this.sdk.marketRegister.markets) {
147
+ const valueUsd = market.priceOracle.safeUsdValue(token, value);
148
+ if (valueUsd !== null) return {
149
+ token: meta,
150
+ value,
151
+ valueUsd
152
+ };
153
+ }
154
+ return {
155
+ token: meta,
156
+ value,
157
+ valueUsd: null
158
+ };
159
+ }
160
+ /**
161
+ * The part a claimable and a pending withdrawal describe the same way. What
162
+ * separates them — the claim transaction and the moment it becomes
163
+ * available — is added by the caller.
164
+ **/
165
+ #liquidationPosition(token, outputs) {
166
+ const sourceToken = this.sdk.tokensMeta.mustGetToken(token);
167
+ const output = this.#withdrawalOutput(outputs, token);
168
+ return {
169
+ kind: "liquidation",
170
+ name: `${sourceToken.symbol} → ${output.token.symbol}`,
171
+ chainId: this.sdk.chainId,
172
+ sourceToken,
173
+ output
174
+ };
175
+ }
176
+ #withdrawalOutput(outputs, sourceToken) {
177
+ const [output] = outputs;
178
+ if (outputs.length !== 1 || !output) throw new Error(`expected exactly one output for withdrawal of ${sourceToken}, got ${outputs.length}`);
179
+ return this.#anyMarketTokenAmount(output.token, output.amount);
180
+ }
181
+ #claimTx(claimCalls, sourceToken) {
182
+ if (claimCalls.length > 1) throw new Error(`expected at most one claim call for withdrawal of ${sourceToken}, got ${claimCalls.length}`);
183
+ const [call] = claimCalls;
184
+ return call ? {
185
+ to: call.target,
186
+ callData: call.callData
187
+ } : void 0;
188
+ }
189
+ #receivedAssets(outputs, priceOracle) {
190
+ return outputs.map((o) => {
191
+ const amount = priceOracle.toTokenAmount(o.token, o.amount);
192
+ if (!o.delayed) return {
193
+ isDelayed: false,
194
+ ...amount
195
+ };
196
+ return {
197
+ isDelayed: true,
198
+ ...amount,
199
+ redeemer: hexEq(o.redeemerAddress, "0x0000000000000000000000000000000000000000") ? void 0 : o.redeemerAddress,
200
+ claimableAt: o.claimableAt === 0n ? void 0 : Number(o.claimableAt)
201
+ };
202
+ });
203
+ }
204
+ #liquidationApproval(data, suite, priceOracle) {
205
+ const { requiredToken, requiredAmount, liquidationCall } = data;
206
+ if (requiredAmount === 0n) return;
207
+ return {
208
+ spender: hexEq(liquidationCall.target, suite.creditFacade.address) ? suite.creditManager.address : liquidationCall.target,
209
+ ...priceOracle.toTokenAmount(requiredToken, requiredAmount * (PERCENTAGE_FACTOR + LIQUIDATION_APPROVAL_BUFFER) / PERCENTAGE_FACTOR)
210
+ };
211
+ }
145
212
  async #getCreditAccountData(creditAccount) {
146
213
  const ca = await this.sdk.accounts.getCreditAccountData(creditAccount);
147
214
  if (!ca) throw new Error(`credit account ${creditAccount} not found`);
148
215
  if (!ca.success) throw new Error(`cannot compute liquidation details for ${creditAccount}: collateral computation failed`);
149
216
  return ca;
150
217
  }
151
- /**
152
- * Previews the liquidation via the liquidation compressor.
153
- *
154
- * @param ca - Credit account to liquidate
155
- * @param liquidator - Liquidator wallet, zero address when not known: it only
156
- * affects the KYC eligibility fields and the receiver encoded into the calls
157
- * @param ignoreReservePrices - Exclude reserve price feeds from the updates
158
- **/
159
218
  async #getLiquidationData(ca, liquidator = ADDRESS_0X0, ignoreReservePrices) {
160
219
  const priceUpdates = await this.sdk.accounts.getOnDemandPriceUpdates(ca, ignoreReservePrices);
161
220
  const { result } = await this.client.simulateContract({
@@ -170,10 +229,6 @@ var LiquidationsService = class extends SDKConstruct {
170
229
  });
171
230
  return result;
172
231
  }
173
- /**
174
- * Accounts of expired credit managers with outstanding debt are liquidatable
175
- * regardless of their health factor.
176
- **/
177
232
  async #getExpiredCreditAccounts() {
178
233
  const expiredCMs = [];
179
234
  for (const market of this.sdk.marketRegister.markets) {
@@ -185,58 +240,58 @@ var LiquidationsService = class extends SDKConstruct {
185
240
  }
186
241
  if (expiredCMs.length === 0) return [];
187
242
  this.logger?.debug(`getting credit accounts of ${expiredCMs.length} expired credit managers`);
188
- const result = [];
189
- for (const creditManager of expiredCMs) {
190
- const accounts = await this.sdk.accounts.getCreditAccounts({
191
- creditManager,
192
- includeZeroDebt: false
193
- });
194
- result.push(...accounts);
195
- }
196
- return result;
243
+ return (await Promise.all(expiredCMs.map((creditManager) => this.sdk.accounts.getCreditAccounts({
244
+ creditManager,
245
+ includeZeroDebt: false
246
+ })))).flat();
197
247
  }
198
- /**
199
- * Requires the compressor's withdrawable assets cache to be loaded
200
- * (see `loadWithdrawableAssets`) so that phantom token lookups are sync.
201
- **/
202
- #buildAccount(ca) {
203
- const compressor = this.sdk.withdrawalCompressor;
204
- const suite = this.sdk.marketRegister.findCreditManager(ca.creditManager);
248
+ #buildAccount(ca, suite = this.sdk.marketRegister.findCreditManager(ca.creditManager)) {
205
249
  const market = suite.market;
206
- const meta = this.sdk.tokensMeta.get(suite.underlying);
207
- const unwrappedUnderlying = meta && this.sdk.tokensMeta.isRWAUnderlying(meta) ? meta.asset : suite.underlying;
250
+ const unwrappedUnderlying = this.sdk.tokensMeta.unwrapRWA(suite.underlying);
208
251
  const liquidationDiscount = suite.isExpired ? suite.creditManager.liquidationDiscountExpired : suite.creditManager.liquidationDiscount;
209
- let asset = pickMainAsset(ca, (token, balance) => {
210
- try {
211
- return market.priceOracle.convert(token, market.underlying, balance);
212
- } catch {
213
- return 0n;
214
- }
215
- });
216
- if (asset) asset = compressor?.getWithdrawalSourceToken(asset) ?? asset;
217
- else asset = unwrappedUnderlying;
252
+ const repaymentAmount = ca.totalValue * BigInt(liquidationDiscount) / PERCENTAGE_FACTOR;
253
+ const estimatedProfit = ca.totalValue - repaymentAmount;
254
+ const token = this.sdk.tokensMeta.mustGetToken(unwrappedUnderlying);
255
+ const usd = (part) => ca.totalValue > 0n ? usdToNumber(ca.totalValueUSD * part / ca.totalValue) : 0;
218
256
  return {
257
+ chainId: this.sdk.chainId,
219
258
  creditAccount: ca.creditAccount,
220
259
  creditManager: ca.creditManager,
221
- network: this.sdk.networkType,
222
- asset,
260
+ asset: this.sdk.tokensMeta.mustGetToken(this.#mainAsset(ca, market, unwrappedUnderlying)),
223
261
  totalValue: {
224
- token: unwrappedUnderlying,
225
- balance: ca.totalValue
262
+ token,
263
+ value: ca.totalValue,
264
+ valueUsd: usdToNumber(ca.totalValueUSD)
226
265
  },
227
- totalValueUSD: ca.totalValueUSD,
228
266
  repaymentAmount: {
229
- token: unwrappedUnderlying,
230
- balance: calcRepaymentAmount(ca.totalValue, liquidationDiscount)
267
+ token,
268
+ value: repaymentAmount,
269
+ valueUsd: usd(repaymentAmount)
231
270
  },
232
271
  estimatedProfit: {
233
- token: unwrappedUnderlying,
234
- balance: calcEstimatedProfit(ca.totalValue, liquidationDiscount)
272
+ token,
273
+ value: estimatedProfit,
274
+ valueUsd: usd(estimatedProfit)
235
275
  },
236
- isDelayed: ca.tokens.some((t) => t.balance > 10n && !!compressor?.getWithdrawalSourceToken(t.token)),
237
- paused: suite.creditFacade.isPaused
276
+ isDelayed: ca.tokens.some((t) => t.balance > 10n && !!this.sdk.withdrawalCompressor?.getWithdrawalSourceToken(t.token)),
277
+ paused: suite.creditFacade.isPaused,
278
+ rwa: market.rwa
238
279
  };
239
280
  }
281
+ #mainAsset(ca, market, fallback) {
282
+ let bestValue = 0;
283
+ let asset;
284
+ for (const t of ca.tokens) {
285
+ if (hexEq(t.token, ca.underlying) || (t.mask & ca.enabledTokensMask) === 0n || t.balance <= 10n) continue;
286
+ const value = market.priceOracle.safeUsdValue(t.token, t.balance) ?? 0;
287
+ if (value > bestValue) {
288
+ bestValue = value;
289
+ asset = t.token;
290
+ }
291
+ }
292
+ if (!asset) return fallback;
293
+ return this.sdk.withdrawalCompressor?.getWithdrawalSourceToken(asset) ?? asset;
294
+ }
240
295
  };
241
296
  //#endregion
242
297
  export { LiquidationsService };
@@ -1,65 +1,59 @@
1
+ import { MultichainConstruct } from "../../base/MultichainConstruct.js";
2
+ import "../../base/index.js";
1
3
  //#region src/sdk/accounts/liquidations/MultichainLiquidationsService.ts
2
4
  /**
3
- * Cross-chain implementation of {@link ILiquidationsService}.
5
+ * Cross-chain counterpart of {@link LiquidationsService}.
4
6
  *
5
- * Aggregates liquidatable accounts over all chains configured in
6
- * {@link MultichainSDK} (optionally restricted via
7
- * {@link MultichainNetworksProps.networks}). A failed chain is logged as
8
- * a warning and skipped, so one dead RPC does not empty the whole list.
7
+ * Fans out over all chains configured in {@link MultichainSDK} (optionally
8
+ * restricted via {@link MultichainNetworksProps.networks}). A failed chain is
9
+ * logged as a warning and skipped, so one dead RPC does not empty the whole
10
+ * list; its failure is reported in {@link MultichainResult.meta}. Networks that
11
+ * are not configured in the SDK are reported there the same way.
9
12
  **/
10
- var MultichainLiquidationsService = class {
11
- #sdk;
12
- constructor(sdk) {
13
- this.#sdk = sdk;
14
- }
13
+ var MultichainLiquidationsService = class extends MultichainConstruct {
15
14
  /**
16
- * {@inheritDoc ILiquidationsService.getLiquidatableAccounts}
15
+ * Accounts of all queried chains, see
16
+ * {@link LiquidationsService.getLiquidatableAccounts}.
17
17
  **/
18
18
  async getLiquidatableAccounts(props) {
19
- const chains = [...this.#sdk.chains.entries()].filter(([network]) => !props?.networks || props.networks.includes(network));
20
- const results = await Promise.allSettled(chains.map(([, chainSdk]) => chainSdk.liquidations.getLiquidatableAccounts(props)));
21
- const accounts = [];
22
- results.forEach((result, i) => {
23
- const [network, chainSdk] = chains[i];
24
- if (result.status === "fulfilled") accounts.push(...result.value);
25
- else chainSdk.logger?.warn(result.reason, `failed to get liquidatable accounts on ${network}`);
19
+ return this.queryChains({
20
+ networks: props?.networks,
21
+ label: "get liquidatable accounts",
22
+ run: (sdk) => sdk.liquidations.getLiquidatableAccounts(props)
26
23
  });
27
- return accounts;
28
24
  }
29
25
  /**
30
- * {@inheritDoc ILiquidationsService.getLiquidationDetails}
26
+ * {@inheritDoc LiquidationsService.getLiquidationDetails}
31
27
  **/
32
28
  async getLiquidationDetails(props) {
33
- return this.#sdk.chain(props.network).liquidations.getLiquidationDetails(props);
29
+ return this.sdk.chain(props.network).liquidations.getLiquidationDetails(props);
34
30
  }
35
31
  /**
36
- * {@inheritDoc ILiquidationsService.buildLiquidationTx}
32
+ * {@inheritDoc LiquidationsService.buildLiquidationTx}
37
33
  **/
38
34
  async buildLiquidationTx(props) {
39
- return this.#sdk.chain(props.network).liquidations.buildLiquidationTx(props);
35
+ return this.sdk.chain(props.network).liquidations.buildLiquidationTx(props);
40
36
  }
41
37
  /**
42
- * {@inheritDoc ILiquidationsService.getLiquidatorWithdrawals}
38
+ * Liquidation positions of all queried chains, see
39
+ * {@link LiquidationsService.getLiquidationPositions}.
43
40
  **/
44
- async getLiquidatorWithdrawals(props) {
45
- const chains = [...this.#sdk.chains.entries()].filter(([network]) => !props.networks || props.networks.includes(network));
46
- const results = await Promise.allSettled(chains.map(([, chainSdk]) => chainSdk.liquidations.getLiquidatorWithdrawals(props)));
47
- const withdrawals = [];
48
- results.forEach((result, i) => {
49
- const [network, chainSdk] = chains[i];
50
- if (result.status === "fulfilled") withdrawals.push(...result.value);
51
- else chainSdk.logger?.warn(result.reason, `failed to get liquidator withdrawals on ${network}`);
41
+ async getLiquidationPositions(props) {
42
+ return this.queryChains({
43
+ networks: props.networks,
44
+ label: "get liquidation positions",
45
+ run: (sdk) => sdk.liquidations.getLiquidationPositions(props)
52
46
  });
53
- return withdrawals;
54
47
  }
55
48
  /**
56
- * {@inheritDoc ILiquidationsService.loadRWALiquidators}
49
+ * Loads the liquidators of all queried chains, see
50
+ * {@link LiquidationsService.loadRWALiquidators}.
57
51
  **/
58
52
  async loadRWALiquidators(props) {
59
- const chains = [...this.#sdk.chains.entries()].filter(([network]) => !props?.networks || props.networks.includes(network));
60
- (await Promise.allSettled(chains.map(([, chainSdk]) => chainSdk.liquidations.loadRWALiquidators()))).forEach((result, i) => {
61
- const [network, chainSdk] = chains[i];
62
- if (result.status === "rejected") chainSdk.logger?.warn(result.reason, `failed to load RWA liquidators on ${network}`);
53
+ return this.runChains({
54
+ networks: props?.networks,
55
+ label: "load RWA liquidators",
56
+ run: (sdk) => sdk.liquidations.loadRWALiquidators()
63
57
  });
64
58
  }
65
59
  };
@@ -1,4 +1,15 @@
1
1
  //#region src/sdk/accounts/liquidations/constants.ts
2
2
  const LIQUIDATION_COMPRESSOR_V313_ADDRESS = "0xB70C4500a0afF02107eB983a348F22492fB6dC94";
3
+ /**
4
+ * Token balances at or below this threshold are treated as dust and ignored,
5
+ * consistent with the rest of the SDK (see `filterDust`).
6
+ **/
7
+ const DUST_THRESHOLD = 10n;
8
+ /**
9
+ * Headroom (in bps) added on top of the amount the liquidation pulls when
10
+ * building the liquidator's approval, so that the transaction does not revert
11
+ * when prices move between the preview and the execution.
12
+ **/
13
+ const LIQUIDATION_APPROVAL_BUFFER = 50n;
3
14
  //#endregion
4
- export { LIQUIDATION_COMPRESSOR_V313_ADDRESS };
15
+ export { DUST_THRESHOLD, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS };