@gearbox-protocol/sdk 14.12.0-next.34 → 14.12.0-next.36

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 (50) hide show
  1. package/dist/cjs/abi/IWithdrawalCompressorV313.js +136 -0
  2. package/dist/cjs/plugins/delayed-withdrawal/DelayedWithdrawalPlugin.js +24 -33
  3. package/dist/cjs/sdk/MultichainSDK.js +7 -0
  4. package/dist/cjs/sdk/OnchainSDK.js +14 -4
  5. package/dist/cjs/sdk/accounts/CreditAccountsServiceV310.js +16 -3
  6. package/dist/cjs/sdk/accounts/index.js +2 -0
  7. package/dist/cjs/sdk/accounts/liquidations/LiquidationsService.js +207 -0
  8. package/dist/cjs/sdk/accounts/liquidations/MultichainLiquidationsService.js +65 -0
  9. package/dist/cjs/sdk/accounts/liquidations/helpers.js +63 -0
  10. package/dist/cjs/sdk/accounts/liquidations/index.js +28 -0
  11. package/dist/cjs/sdk/accounts/liquidations/types.js +16 -0
  12. package/dist/cjs/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.js +142 -74
  13. package/dist/cjs/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +97 -0
  14. package/dist/cjs/sdk/accounts/withdrawal-compressor/addresses.js +1 -1
  15. package/dist/cjs/sdk/accounts/withdrawal-compressor/createWithdrawalCompressor.js +1 -7
  16. package/dist/cjs/sdk/accounts/withdrawal-compressor/types.js +20 -0
  17. package/dist/esm/abi/IWithdrawalCompressorV313.js +136 -0
  18. package/dist/esm/plugins/delayed-withdrawal/DelayedWithdrawalPlugin.js +24 -33
  19. package/dist/esm/sdk/MultichainSDK.js +7 -0
  20. package/dist/esm/sdk/OnchainSDK.js +16 -5
  21. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +16 -3
  22. package/dist/esm/sdk/accounts/index.js +1 -0
  23. package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +188 -0
  24. package/dist/esm/sdk/accounts/liquidations/MultichainLiquidationsService.js +41 -0
  25. package/dist/esm/sdk/accounts/liquidations/helpers.js +36 -0
  26. package/dist/esm/sdk/accounts/liquidations/index.js +4 -0
  27. package/dist/esm/sdk/accounts/liquidations/types.js +0 -0
  28. package/dist/esm/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.js +138 -74
  29. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +104 -1
  30. package/dist/esm/sdk/accounts/withdrawal-compressor/addresses.js +1 -1
  31. package/dist/esm/sdk/accounts/withdrawal-compressor/createWithdrawalCompressor.js +1 -7
  32. package/dist/esm/sdk/accounts/withdrawal-compressor/types.js +12 -0
  33. package/dist/types/abi/IWithdrawalCompressorV313.d.ts +200 -0
  34. package/dist/types/plugins/delayed-withdrawal/DelayedWithdrawalPlugin.d.ts +7 -7
  35. package/dist/types/sdk/MultichainSDK.d.ts +6 -0
  36. package/dist/types/sdk/OnchainSDK.d.ts +8 -5
  37. package/dist/types/sdk/accounts/CreditAccountsServiceV310.d.ts +1 -1
  38. package/dist/types/sdk/accounts/index.d.ts +1 -0
  39. package/dist/types/sdk/accounts/liquidations/LiquidationsService.d.ts +20 -0
  40. package/dist/types/sdk/accounts/liquidations/MultichainLiquidationsService.d.ts +23 -0
  41. package/dist/types/sdk/accounts/liquidations/helpers.d.ts +34 -0
  42. package/dist/types/sdk/accounts/liquidations/index.d.ts +4 -0
  43. package/dist/types/sdk/accounts/liquidations/types.d.ts +172 -0
  44. package/dist/types/sdk/accounts/types.d.ts +6 -0
  45. package/dist/types/sdk/accounts/withdrawal-compressor/AbstractWithdrawalCompressorContract.d.ts +80 -6
  46. package/dist/types/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.d.ts +222 -0
  47. package/dist/types/sdk/accounts/withdrawal-compressor/createWithdrawalCompressor.d.ts +5 -4
  48. package/dist/types/sdk/accounts/withdrawal-compressor/types.d.ts +106 -7
  49. package/dist/types/sdk/types/state.d.ts +8 -0
  50. package/package.json +1 -1
@@ -102,6 +102,100 @@ const iWithdrawalCompressorV313Abi = [
102
102
  ],
103
103
  stateMutability: "view"
104
104
  },
105
+ {
106
+ type: "function",
107
+ name: "getExternalAccountCurrentWithdrawals",
108
+ inputs: [
109
+ { name: "withdrawalToken", type: "address", internalType: "address" },
110
+ { name: "account", type: "address", internalType: "address" }
111
+ ],
112
+ outputs: [
113
+ {
114
+ name: "",
115
+ type: "tuple[]",
116
+ internalType: "struct ClaimableWithdrawal[]",
117
+ components: [
118
+ { name: "token", type: "address", internalType: "address" },
119
+ {
120
+ name: "withdrawalPhantomToken",
121
+ type: "address",
122
+ internalType: "address"
123
+ },
124
+ {
125
+ name: "withdrawalTokenSpent",
126
+ type: "uint256",
127
+ internalType: "uint256"
128
+ },
129
+ {
130
+ name: "outputs",
131
+ type: "tuple[]",
132
+ internalType: "struct WithdrawalOutput[]",
133
+ components: [
134
+ { name: "token", type: "address", internalType: "address" },
135
+ { name: "isDelayed", type: "bool", internalType: "bool" },
136
+ { name: "amount", type: "uint256", internalType: "uint256" }
137
+ ]
138
+ },
139
+ {
140
+ name: "claimCalls",
141
+ type: "tuple[]",
142
+ internalType: "struct MultiCall[]",
143
+ components: [
144
+ { name: "target", type: "address", internalType: "address" },
145
+ { name: "callData", type: "bytes", internalType: "bytes" }
146
+ ]
147
+ },
148
+ { name: "extraData", type: "bytes", internalType: "bytes" }
149
+ ]
150
+ },
151
+ {
152
+ name: "",
153
+ type: "tuple[]",
154
+ internalType: "struct PendingWithdrawal[]",
155
+ components: [
156
+ { name: "token", type: "address", internalType: "address" },
157
+ {
158
+ name: "withdrawalPhantomToken",
159
+ type: "address",
160
+ internalType: "address"
161
+ },
162
+ {
163
+ name: "expectedOutputs",
164
+ type: "tuple[]",
165
+ internalType: "struct WithdrawalOutput[]",
166
+ components: [
167
+ { name: "token", type: "address", internalType: "address" },
168
+ { name: "isDelayed", type: "bool", internalType: "bool" },
169
+ { name: "amount", type: "uint256", internalType: "uint256" }
170
+ ]
171
+ },
172
+ { name: "claimableAt", type: "uint256", internalType: "uint256" },
173
+ { name: "extraData", type: "bytes", internalType: "bytes" }
174
+ ]
175
+ }
176
+ ],
177
+ stateMutability: "view"
178
+ },
179
+ {
180
+ type: "function",
181
+ name: "getWithdrawalStatus",
182
+ inputs: [{ name: "redeemer", type: "address", internalType: "address" }],
183
+ outputs: [
184
+ { name: "", type: "uint8", internalType: "enum WithdrawalStatus" }
185
+ ],
186
+ stateMutability: "view"
187
+ },
188
+ {
189
+ type: "function",
190
+ name: "getWithdrawalStatus",
191
+ inputs: [
192
+ { name: "redeemers", type: "address[]", internalType: "address[]" }
193
+ ],
194
+ outputs: [
195
+ { name: "", type: "uint8[]", internalType: "enum WithdrawalStatus[]" }
196
+ ],
197
+ stateMutability: "view"
198
+ },
105
199
  {
106
200
  type: "function",
107
201
  name: "getWithdrawableAssets",
@@ -175,6 +269,48 @@ const iWithdrawalCompressorV313Abi = [
175
269
  ],
176
270
  stateMutability: "view"
177
271
  },
272
+ {
273
+ type: "function",
274
+ name: "getWithdrawalRequestResult",
275
+ inputs: [
276
+ { name: "creditAccount", type: "address", internalType: "address" },
277
+ { name: "token", type: "address", internalType: "address" },
278
+ { name: "withdrawalToken", type: "address", internalType: "address" },
279
+ { name: "amount", type: "uint256", internalType: "uint256" }
280
+ ],
281
+ outputs: [
282
+ {
283
+ name: "",
284
+ type: "tuple",
285
+ internalType: "struct RequestableWithdrawal",
286
+ components: [
287
+ { name: "token", type: "address", internalType: "address" },
288
+ { name: "amountIn", type: "uint256", internalType: "uint256" },
289
+ {
290
+ name: "outputs",
291
+ type: "tuple[]",
292
+ internalType: "struct WithdrawalOutput[]",
293
+ components: [
294
+ { name: "token", type: "address", internalType: "address" },
295
+ { name: "isDelayed", type: "bool", internalType: "bool" },
296
+ { name: "amount", type: "uint256", internalType: "uint256" }
297
+ ]
298
+ },
299
+ {
300
+ name: "requestCalls",
301
+ type: "tuple[]",
302
+ internalType: "struct MultiCall[]",
303
+ components: [
304
+ { name: "target", type: "address", internalType: "address" },
305
+ { name: "callData", type: "bytes", internalType: "bytes" }
306
+ ]
307
+ },
308
+ { name: "claimableAt", type: "uint256", internalType: "uint256" }
309
+ ]
310
+ }
311
+ ],
312
+ stateMutability: "view"
313
+ },
178
314
  {
179
315
  type: "function",
180
316
  name: "getWithdrawalRequestResult",
@@ -24,16 +24,31 @@ module.exports = __toCommonJS(DelayedWithdrawalPlugin_exports);
24
24
  var import_sdk = require("../../sdk/index.js");
25
25
  const MAP_LABEL = "delayedWithdrawal";
26
26
  class DelayedWithdrawalPlugin extends import_sdk.BasePlugin {
27
- #withdrawableAssets;
28
27
  async load(force) {
29
28
  if (!force && this.loaded) {
30
29
  return this.state;
31
30
  }
32
- this.#withdrawableAssets = new import_sdk.AddressMap(void 0, MAP_LABEL);
33
- const resp = await this.sdk.withdrawalCompressor.getWithdrawableAssetsBatch();
34
- const byCreditManager = /* @__PURE__ */ new Map();
35
- for (const cfg of resp) {
36
- const assets = byCreditManager.get(cfg.creditManager) ?? [];
31
+ await this.sdk.withdrawalCompressor?.loadWithdrawableAssets(force);
32
+ return this.state;
33
+ }
34
+ get loaded() {
35
+ return !!this.sdk.withdrawalCompressor?.state;
36
+ }
37
+ /**
38
+ * Returns a map of cmAddress -> array of delayed assets
39
+ * @throws if withdrawable assets have not been loaded
40
+ */
41
+ get withdrawableAssets() {
42
+ const compressor = this.sdk.withdrawalCompressor;
43
+ if (!compressor?.state) {
44
+ throw new Error("withdrawable assets are not loaded");
45
+ }
46
+ const result = new import_sdk.AddressMap(
47
+ void 0,
48
+ MAP_LABEL
49
+ );
50
+ for (const cfg of compressor.getWithdrawableAssets()) {
51
+ const assets = result.get(cfg.creditManager) ?? [];
37
52
  assets.push({
38
53
  ...cfg,
39
54
  disabled: isConfigToOmit({
@@ -43,25 +58,9 @@ class DelayedWithdrawalPlugin extends import_sdk.BasePlugin {
43
58
  underlying: cfg.underlying
44
59
  })
45
60
  });
46
- byCreditManager.set(cfg.creditManager, assets);
47
- }
48
- for (const [creditManager, assets] of byCreditManager) {
49
- this.#withdrawableAssets.upsert(creditManager, assets);
61
+ result.upsert(cfg.creditManager, assets);
50
62
  }
51
- return this.state;
52
- }
53
- get loaded() {
54
- return !!this.#withdrawableAssets;
55
- }
56
- /**
57
- * Returns a map of cmAddress -> array of delayed assets
58
- * @throws if plugin is not attached
59
- */
60
- get withdrawableAssets() {
61
- if (!this.#withdrawableAssets) {
62
- throw new Error("withdrawable assets plugin not attached");
63
- }
64
- return this.#withdrawableAssets;
63
+ return result;
65
64
  }
66
65
  stateHuman(_) {
67
66
  return this.withdrawableAssets.values().flatMap((cm) => {
@@ -76,15 +75,7 @@ class DelayedWithdrawalPlugin extends import_sdk.BasePlugin {
76
75
  });
77
76
  }
78
77
  get state() {
79
- return {
80
- withdrawableAssets: this.withdrawableAssets.asRecord()
81
- };
82
- }
83
- hydrate(state) {
84
- this.#withdrawableAssets = new import_sdk.AddressMap(
85
- Object.entries(state.withdrawableAssets),
86
- MAP_LABEL
87
- );
78
+ return {};
88
79
  }
89
80
  }
90
81
  function getConfigKey(config) {
@@ -21,6 +21,7 @@ __export(MultichainSDK_exports, {
21
21
  MultichainSDK: () => MultichainSDK
22
22
  });
23
23
  module.exports = __toCommonJS(MultichainSDK_exports);
24
+ var import_accounts = require("./accounts/index.js");
24
25
  var import_chains = require("./chain/chains.js");
25
26
  var import_core = require("./core/index.js");
26
27
  var import_updates = require("./market/pricefeeds/updates/index.js");
@@ -30,6 +31,11 @@ class MultichainSDK {
30
31
  #redstoneCache;
31
32
  #pythCache;
32
33
  #logger;
34
+ /**
35
+ * Namespace for liquidatable credit accounts discovery across all
36
+ * configured chains.
37
+ */
38
+ liquidations;
33
39
  constructor(options) {
34
40
  this.#chains = /* @__PURE__ */ new Map();
35
41
  this.#logger = options.logger;
@@ -57,6 +63,7 @@ class MultichainSDK {
57
63
  );
58
64
  this.#chains.set(network, sdk);
59
65
  }
66
+ this.liquidations = new import_accounts.MultichainLiquidationsService(this);
60
67
  }
61
68
  /**
62
69
  * Attach all configured chains in parallel.
@@ -67,6 +67,7 @@ class OnchainSDK extends import_base.ChainContractsRegister {
67
67
  #rwa;
68
68
  #marketRegister;
69
69
  #priceFeeds;
70
+ #withdrawalCompressor;
70
71
  /**
71
72
  * Gas limit applied to read-only `eth_call` requests.
72
73
  **/
@@ -83,6 +84,10 @@ class OnchainSDK extends import_base.ChainContractsRegister {
83
84
  * Namespace for pool operations.
84
85
  */
85
86
  pools;
87
+ /**
88
+ * Namespace for liquidatable credit accounts discovery.
89
+ */
90
+ liquidations;
86
91
  /**
87
92
  * @param network - Gearbox network type (e.g. `"Mainnet"`, `"Monad"`).
88
93
  * @param clientOptions - Connection options (RPC URLs, transport, or client).
@@ -109,6 +114,8 @@ class OnchainSDK extends import_base.ChainContractsRegister {
109
114
  }
110
115
  this.accounts = new import_accounts.CreditAccountsServiceV310(this);
111
116
  this.pools = new import_pools.PoolService(this);
117
+ this.liquidations = new import_accounts.LiquidationsService(this);
118
+ this.#withdrawalCompressor = (0, import_accounts.createWithdrawalCompressor)(this);
112
119
  }
113
120
  /**
114
121
  * Initialises the SDK by reading live on-chain state.
@@ -255,6 +262,9 @@ class OnchainSDK extends import_base.ChainContractsRegister {
255
262
  this.#marketRegister.hydrate(state);
256
263
  this.#rwa = new import_market.RWARegistry(this);
257
264
  this.#rwa.setState(state.rwa);
265
+ if (state.withdrawals) {
266
+ this.#withdrawalCompressor?.hydrate(state.withdrawals);
267
+ }
258
268
  for (const [name, plugin] of import_utils.TypedObjectUtils.entries(this.plugins)) {
259
269
  const pluginState = state.plugins[name];
260
270
  if (plugin.hydrate && pluginState) {
@@ -319,6 +329,7 @@ class OnchainSDK extends import_base.ChainContractsRegister {
319
329
  addressProvider: this.addressProvider.state,
320
330
  ...this.marketRegister.state,
321
331
  rwa: this.#rwa.state,
332
+ withdrawals: this.#withdrawalCompressor?.state,
322
333
  plugins: Object.fromEntries(
323
334
  import_utils.TypedObjectUtils.entries(this.plugins).map(([name, plugin]) => [
324
335
  name,
@@ -536,12 +547,11 @@ class OnchainSDK extends import_base.ChainContractsRegister {
536
547
  return (0, import_router.createRouter)(this, routerAddr, routerV);
537
548
  }
538
549
  /**
539
- * Lazily returns a withdrawal compressor contract for the current chain.
540
- *
541
- * @throws If no withdrawal compressor is supported on the current chain.
550
+ * Withdrawal compressor contract for the current chain, or `undefined`
551
+ * when no withdrawal compressor is supported on it.
542
552
  **/
543
553
  get withdrawalCompressor() {
544
- return (0, import_accounts.createWithdrawalCompressor)(this);
554
+ return this.#withdrawalCompressor;
545
555
  }
546
556
  }
547
557
  // Annotate the CommonJS export names for ESM import in node:
@@ -771,14 +771,16 @@ class CreditAccountsServiceV310 extends import_base.SDKConstruct {
771
771
  creditAccount,
772
772
  amount,
773
773
  token,
774
+ withdrawalPhantomToken,
774
775
  intent
775
776
  }) {
776
- return this.sdk.withdrawalCompressor.getWithdrawalRequestResult(
777
+ return this.#withdrawalCompressor.getWithdrawalRequestResult({
777
778
  creditAccount,
778
779
  token,
779
780
  amount,
781
+ withdrawalPhantomToken,
780
782
  intent
781
- );
783
+ });
782
784
  }
783
785
  /**
784
786
  * {@inheritDoc ICreditAccountsService.getPendingWithdrawals}
@@ -786,7 +788,7 @@ class CreditAccountsServiceV310 extends import_base.SDKConstruct {
786
788
  async getPendingWithdrawals({
787
789
  creditAccount
788
790
  }) {
789
- const { claimable, pending } = await this.sdk.withdrawalCompressor.getCurrentWithdrawals(creditAccount);
791
+ const { claimable, pending } = await this.#withdrawalCompressor.getCurrentWithdrawals(creditAccount);
790
792
  return {
791
793
  claimableNow: claimable,
792
794
  pending
@@ -1853,6 +1855,17 @@ class CreditAccountsServiceV310 extends import_base.SDKConstruct {
1853
1855
  }
1854
1856
  return suite.creditFacade.multicall(creditAccount, calls);
1855
1857
  }
1858
+ /**
1859
+ * Withdrawal compressor of the current chain.
1860
+ * @throws If no withdrawal compressor is supported on the current chain.
1861
+ **/
1862
+ get #withdrawalCompressor() {
1863
+ const compressor = this.sdk.withdrawalCompressor;
1864
+ if (!compressor) {
1865
+ throw new Error(`no withdrawal compressor on ${this.sdk.networkType}`);
1866
+ }
1867
+ return compressor;
1868
+ }
1856
1869
  }
1857
1870
  // Annotate the CommonJS export names for ESM import in node:
1858
1871
  0 && (module.exports = {
@@ -16,11 +16,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
16
16
  var accounts_exports = {};
17
17
  module.exports = __toCommonJS(accounts_exports);
18
18
  __reExport(accounts_exports, require("./CreditAccountsServiceV310.js"), module.exports);
19
+ __reExport(accounts_exports, require("./liquidations/index.js"), module.exports);
19
20
  __reExport(accounts_exports, require("./types.js"), module.exports);
20
21
  __reExport(accounts_exports, require("./withdrawal-compressor/index.js"), module.exports);
21
22
  // Annotate the CommonJS export names for ESM import in node:
22
23
  0 && (module.exports = {
23
24
  ...require("./CreditAccountsServiceV310.js"),
25
+ ...require("./liquidations/index.js"),
24
26
  ...require("./types.js"),
25
27
  ...require("./withdrawal-compressor/index.js")
26
28
  });
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var LiquidationsService_exports = {};
20
+ __export(LiquidationsService_exports, {
21
+ LiquidationsService: () => LiquidationsService
22
+ });
23
+ module.exports = __toCommonJS(LiquidationsService_exports);
24
+ var import_base = require("../../base/index.js");
25
+ var import_constants = require("../../constants/index.js");
26
+ var import_utils = require("../../utils/index.js");
27
+ var import_helpers = require("./helpers.js");
28
+ class LiquidationsService extends import_base.SDKConstruct {
29
+ /**
30
+ * {@inheritDoc ILiquidationsService.getLiquidatableAccounts}
31
+ **/
32
+ async getLiquidatableAccounts(props) {
33
+ if (props?.networks && !props.networks.includes(this.sdk.networkType)) {
34
+ return [];
35
+ }
36
+ await this.sdk.withdrawalCompressor?.loadWithdrawableAssets();
37
+ const accounts = await this.sdk.accounts.getCreditAccounts({
38
+ maxHealthFactor: import_constants.WAD - 1n,
39
+ includeZeroDebt: false
40
+ });
41
+ const seen = new import_utils.AddressSet(accounts.map((ca) => ca.creditAccount));
42
+ for (const ca of await this.#getExpiredCreditAccounts()) {
43
+ if (!seen.has(ca.creditAccount)) {
44
+ seen.add(ca.creditAccount);
45
+ accounts.push(ca);
46
+ }
47
+ }
48
+ const rows = [];
49
+ for (const ca of accounts) {
50
+ if (!ca.success) {
51
+ continue;
52
+ }
53
+ rows.push(this.#buildAccount(ca));
54
+ }
55
+ const allowedAssets = props?.assets?.length ? new import_utils.AddressSet(props.assets) : void 0;
56
+ return rows.filter((row) => {
57
+ if (props?.delayed !== void 0 && row.isDelayed !== props.delayed) {
58
+ return false;
59
+ }
60
+ if (allowedAssets && !allowedAssets.has(row.asset)) {
61
+ return false;
62
+ }
63
+ return true;
64
+ });
65
+ }
66
+ /**
67
+ * {@inheritDoc ILiquidationsService.getLiquidationDetails}
68
+ **/
69
+ async getLiquidationDetails(props) {
70
+ const { network, creditAccount } = props;
71
+ if (network !== this.sdk.networkType) {
72
+ throw new Error(
73
+ `network mismatch: this SDK is attached to ${this.sdk.networkType}, requested ${network}`
74
+ );
75
+ }
76
+ const ca = await this.sdk.accounts.getCreditAccountData(creditAccount);
77
+ if (!ca) {
78
+ throw new Error(`credit account ${creditAccount} not found`);
79
+ }
80
+ if (!ca.success) {
81
+ throw new Error(
82
+ `cannot compute liquidation details for ${creditAccount}: collateral computation failed`
83
+ );
84
+ }
85
+ const compressor = this.sdk.withdrawalCompressor;
86
+ await compressor?.loadWithdrawableAssets();
87
+ const account = this.#buildAccount(ca);
88
+ const receivedAssets = [];
89
+ for (const t of ca.tokens) {
90
+ if (t.balance > import_helpers.DUST_THRESHOLD && !compressor?.getWithdrawalSourceToken(t.token)) {
91
+ receivedAssets.push({
92
+ isDelayed: false,
93
+ token: t.token,
94
+ amount: t.balance
95
+ });
96
+ }
97
+ }
98
+ if (account.isDelayed && compressor) {
99
+ const { claimable, pending } = await compressor.getCurrentWithdrawals(creditAccount);
100
+ for (const w of claimable) {
101
+ for (const o of w.outputs) {
102
+ receivedAssets.push({
103
+ isDelayed: true,
104
+ token: o.token,
105
+ amount: o.amount,
106
+ sourceToken: w.token
107
+ });
108
+ }
109
+ }
110
+ for (const w of pending) {
111
+ for (const o of w.expectedOutputs) {
112
+ receivedAssets.push({
113
+ isDelayed: true,
114
+ token: o.token,
115
+ amount: o.amount,
116
+ sourceToken: w.token,
117
+ claimableAt: w.claimableAt
118
+ });
119
+ }
120
+ }
121
+ }
122
+ return { ...account, receivedAssets };
123
+ }
124
+ /**
125
+ * Accounts of expired credit managers with outstanding debt are liquidatable
126
+ * regardless of their health factor.
127
+ **/
128
+ async #getExpiredCreditAccounts() {
129
+ const expiredCMs = [];
130
+ for (const market of this.sdk.marketRegister.markets) {
131
+ if (market.pool.pool.totalBorrowed === 0n) {
132
+ continue;
133
+ }
134
+ for (const cm of market.creditManagers) {
135
+ const borrowed = market.pool.pool.creditManagerDebtParams.get(cm.creditManager.address)?.borrowed ?? 0n;
136
+ if (cm.isExpired && borrowed > 0n) {
137
+ expiredCMs.push(cm.creditManager.address);
138
+ }
139
+ }
140
+ }
141
+ if (expiredCMs.length === 0) {
142
+ return [];
143
+ }
144
+ this.logger?.debug(
145
+ `getting credit accounts of ${expiredCMs.length} expired credit managers`
146
+ );
147
+ const result = [];
148
+ for (const creditManager of expiredCMs) {
149
+ const accounts = await this.sdk.accounts.getCreditAccounts({
150
+ creditManager,
151
+ includeZeroDebt: false
152
+ });
153
+ result.push(...accounts);
154
+ }
155
+ return result;
156
+ }
157
+ /**
158
+ * Requires the compressor's withdrawable assets cache to be loaded
159
+ * (see `loadWithdrawableAssets`) so that phantom token lookups are sync.
160
+ **/
161
+ #buildAccount(ca) {
162
+ const compressor = this.sdk.withdrawalCompressor;
163
+ const suite = this.sdk.marketRegister.findCreditManager(ca.creditManager);
164
+ const market = suite.market;
165
+ const meta = this.sdk.tokensMeta.get(suite.underlying);
166
+ const unwrappedUnderlying = meta && this.sdk.tokensMeta.isRWAUnderlying(meta) ? meta.asset : suite.underlying;
167
+ const liquidationDiscount = suite.isExpired ? suite.creditManager.liquidationDiscountExpired : suite.creditManager.liquidationDiscount;
168
+ let asset = (0, import_helpers.pickMainAsset)(ca, (token, balance) => {
169
+ try {
170
+ return market.priceOracle.convert(token, market.underlying, balance);
171
+ } catch {
172
+ return 0n;
173
+ }
174
+ });
175
+ if (asset) {
176
+ asset = compressor?.getWithdrawalSourceToken(asset) ?? asset;
177
+ } else {
178
+ asset = unwrappedUnderlying;
179
+ }
180
+ return {
181
+ creditAccount: ca.creditAccount,
182
+ creditManager: ca.creditManager,
183
+ network: this.sdk.networkType,
184
+ asset,
185
+ totalValue: {
186
+ token: unwrappedUnderlying,
187
+ balance: ca.totalValue
188
+ },
189
+ totalValueUSD: ca.totalValueUSD,
190
+ repaymentAmount: {
191
+ token: unwrappedUnderlying,
192
+ balance: (0, import_helpers.calcRepaymentAmount)(ca.totalValue, liquidationDiscount)
193
+ },
194
+ estimatedProfit: {
195
+ token: unwrappedUnderlying,
196
+ balance: (0, import_helpers.calcEstimatedProfit)(ca.totalValue, liquidationDiscount)
197
+ },
198
+ isDelayed: ca.tokens.some(
199
+ (t) => t.balance > import_helpers.DUST_THRESHOLD && !!compressor?.getWithdrawalSourceToken(t.token)
200
+ )
201
+ };
202
+ }
203
+ }
204
+ // Annotate the CommonJS export names for ESM import in node:
205
+ 0 && (module.exports = {
206
+ LiquidationsService
207
+ });
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var MultichainLiquidationsService_exports = {};
20
+ __export(MultichainLiquidationsService_exports, {
21
+ MultichainLiquidationsService: () => MultichainLiquidationsService
22
+ });
23
+ module.exports = __toCommonJS(MultichainLiquidationsService_exports);
24
+ class MultichainLiquidationsService {
25
+ #sdk;
26
+ constructor(sdk) {
27
+ this.#sdk = sdk;
28
+ }
29
+ /**
30
+ * {@inheritDoc ILiquidationsService.getLiquidatableAccounts}
31
+ **/
32
+ async getLiquidatableAccounts(props) {
33
+ const chains = [...this.#sdk.chains.entries()].filter(
34
+ ([network]) => !props?.networks || props.networks.includes(network)
35
+ );
36
+ const results = await Promise.allSettled(
37
+ chains.map(
38
+ ([, chainSdk]) => chainSdk.liquidations.getLiquidatableAccounts(props)
39
+ )
40
+ );
41
+ const accounts = [];
42
+ results.forEach((result, i) => {
43
+ const [network, chainSdk] = chains[i];
44
+ if (result.status === "fulfilled") {
45
+ accounts.push(...result.value);
46
+ } else {
47
+ chainSdk.logger?.warn(
48
+ result.reason,
49
+ `failed to get liquidatable accounts on ${network}`
50
+ );
51
+ }
52
+ });
53
+ return accounts;
54
+ }
55
+ /**
56
+ * {@inheritDoc ILiquidationsService.getLiquidationDetails}
57
+ **/
58
+ async getLiquidationDetails(props) {
59
+ return this.#sdk.chain(props.network).liquidations.getLiquidationDetails(props);
60
+ }
61
+ }
62
+ // Annotate the CommonJS export names for ESM import in node:
63
+ 0 && (module.exports = {
64
+ MultichainLiquidationsService
65
+ });