@gearbox-protocol/sdk 14.12.0-next.67 → 14.12.0-next.69

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 (53) hide show
  1. package/dist/cjs/model/index.js +13 -0
  2. package/dist/cjs/model/liquidations.schema.js +3 -1
  3. package/dist/cjs/model/opportunities.schema.js +10 -7
  4. package/dist/cjs/model/positions.schema.js +120 -0
  5. package/dist/cjs/sdk/accounts/liquidations/LiquidationsService.js +19 -8
  6. package/dist/cjs/sdk/market/MarketSuite.js +8 -12
  7. package/dist/cjs/sdk/market/credit/CreditSuite.js +4 -14
  8. package/dist/cjs/sdk/opportunities/OpportunitiesService.js +8 -63
  9. package/dist/cjs/sdk/router/RouterV310Contract.js +34 -0
  10. package/dist/esm/dev/AccountOpener.js +1 -1
  11. package/dist/esm/dev/withdrawalUtils.js +1 -1
  12. package/dist/esm/model/index.js +3 -1
  13. package/dist/esm/model/liquidations.schema.js +3 -1
  14. package/dist/esm/model/opportunities.schema.js +10 -7
  15. package/dist/esm/model/positions.schema.js +109 -0
  16. package/dist/esm/preview/simulate/simulatePoolOperation.js +1 -1
  17. package/dist/esm/preview/trace/extractTransfers.js +1 -1
  18. package/dist/esm/sdk/accounts/CreditAccountsServiceV310.js +2 -2
  19. package/dist/esm/sdk/accounts/liquidations/LiquidationsService.js +20 -9
  20. package/dist/esm/sdk/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.js +1 -1
  21. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.js +1 -1
  22. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.js +1 -1
  23. package/dist/esm/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.js +1 -1
  24. package/dist/esm/sdk/base/TokensMeta.js +2 -2
  25. package/dist/esm/sdk/chain/detectNetwork.js +1 -1
  26. package/dist/esm/sdk/core/createAddressProvider.js +1 -1
  27. package/dist/esm/sdk/market/MarketSuite.js +8 -12
  28. package/dist/esm/sdk/market/credit/CreditFacadeV310BaseContract.js +1 -1
  29. package/dist/esm/sdk/market/credit/CreditSuite.js +5 -15
  30. package/dist/esm/sdk/market/pool/PoolV310Contract.js +1 -1
  31. package/dist/esm/sdk/market/zapper/IETHZapperContract.js +1 -1
  32. package/dist/esm/sdk/market/zapper/ZapperContract.js +1 -1
  33. package/dist/esm/sdk/opportunities/OpportunitiesService.js +8 -63
  34. package/dist/esm/sdk/pools/PoolService.js +1 -1
  35. package/dist/esm/sdk/router/RouterV310Contract.js +34 -0
  36. package/dist/esm/sdk/utils/viem/simulateWithPriceUpdates.js +1 -1
  37. package/dist/types/model/index.d.ts +3 -1
  38. package/dist/types/model/liquidations.d.ts +9 -1
  39. package/dist/types/model/liquidations.schema.d.ts +5 -3
  40. package/dist/types/model/opportunities.d.ts +70 -29
  41. package/dist/types/model/opportunities.schema.d.ts +220 -249
  42. package/dist/types/model/positions.d.ts +239 -3
  43. package/dist/types/model/positions.schema.d.ts +701 -0
  44. package/dist/types/model/primitives.d.ts +3 -2
  45. package/dist/types/sdk/index.d.ts +3 -3
  46. package/dist/types/sdk/market/MarketSuite.d.ts +4 -15
  47. package/dist/types/sdk/market/credit/CreditSuite.d.ts +3 -7
  48. package/dist/types/sdk/market/index.d.ts +2 -2
  49. package/dist/types/sdk/opportunities/OpportunitiesService.d.ts +6 -11
  50. package/dist/types/sdk/router/RouterV310Contract.d.ts +5 -1
  51. package/dist/types/sdk/router/index.d.ts +2 -2
  52. package/dist/types/sdk/router/types.d.ts +35 -1
  53. package/package.json +1 -1
@@ -0,0 +1,109 @@
1
+ import { ZodAddress } from "../sdk/utils/zod.js";
2
+ import { assetTypeSchema, bpsSchema, chainIdSchema, leverageSchema, tokenAmountSchema, tokenSchema } from "./primitives.schema.js";
3
+ import { apyBreakdownSchema, pointsProgramSchema } from "./opportunities.schema.js";
4
+ import { delayedReceivedAssetSchema, liquidationPositionSchema } from "./liquidations.schema.js";
5
+ import { z } from "zod/v4";
6
+ //#region src/model/positions.schema.ts
7
+ /**
8
+ * Runtime schemas for {@link ./positions.js}, see the note in
9
+ * `primitives.schema.ts` on why they are written by hand.
10
+ **/
11
+ /**
12
+ * {@link PositionKind}
13
+ **/
14
+ const positionKindSchema = z.union([
15
+ z.literal("pool"),
16
+ z.literal("strategy"),
17
+ z.literal("liquidation")
18
+ ]);
19
+ /**
20
+ * {@link TokenRewardsPnL}
21
+ **/
22
+ const tokenRewardsPnLSchema = z.object({
23
+ ...tokenAmountSchema.shape,
24
+ kind: z.literal("token")
25
+ });
26
+ /**
27
+ * {@link PointsProgramPnL}
28
+ **/
29
+ const pointsProgramPnLSchema = z.object({
30
+ ...pointsProgramSchema.shape,
31
+ value: z.number()
32
+ });
33
+ /**
34
+ * {@link PointsRewardsPnL}
35
+ **/
36
+ const pointsRewardsPnLSchema = z.object({
37
+ kind: z.literal("point"),
38
+ points: z.array(pointsProgramPnLSchema)
39
+ });
40
+ /**
41
+ * {@link RewardsPnL}
42
+ **/
43
+ const rewardsPnLSchema = z.discriminatedUnion("kind", [tokenRewardsPnLSchema, pointsRewardsPnLSchema]);
44
+ /**
45
+ * {@link PnlBreakdown}
46
+ **/
47
+ const pnlBreakdownSchema = z.object({
48
+ organic: tokenAmountSchema,
49
+ total: tokenAmountSchema,
50
+ rewards: z.array(rewardsPnLSchema)
51
+ });
52
+ /**
53
+ * {@link PositionCollateral}
54
+ **/
55
+ const positionCollateralSchema = z.object({
56
+ collateral: tokenAmountSchema,
57
+ quota: tokenAmountSchema,
58
+ withdrawals: z.array(delayedReceivedAssetSchema)
59
+ });
60
+ /**
61
+ * {@link PoolPosition}
62
+ **/
63
+ const poolPositionSchema = z.object({
64
+ kind: z.literal("pool"),
65
+ name: z.string(),
66
+ chainId: chainIdSchema,
67
+ pool: ZodAddress(),
68
+ netValue: tokenAmountSchema,
69
+ apy: apyBreakdownSchema,
70
+ pnl: pnlBreakdownSchema.optional()
71
+ });
72
+ /**
73
+ * {@link StrategyPosition}
74
+ **/
75
+ const strategyPositionSchema = z.object({
76
+ kind: z.literal("strategy"),
77
+ name: z.string(),
78
+ chainId: chainIdSchema,
79
+ creditManager: ZodAddress(),
80
+ creditAccount: ZodAddress(),
81
+ targetCollateral: tokenSchema.nullable(),
82
+ leverage: leverageSchema,
83
+ borrowApy: bpsSchema,
84
+ netApy: apyBreakdownSchema.optional(),
85
+ totalDebt: tokenAmountSchema,
86
+ totalValue: tokenAmountSchema,
87
+ healthFactor: bpsSchema,
88
+ pnl: pnlBreakdownSchema.optional(),
89
+ collaterals: z.array(positionCollateralSchema)
90
+ });
91
+ /**
92
+ * {@link Position}
93
+ **/
94
+ const positionSchema = z.discriminatedUnion("kind", [
95
+ poolPositionSchema,
96
+ strategyPositionSchema,
97
+ liquidationPositionSchema
98
+ ]);
99
+ /**
100
+ * {@link PositionFilter}
101
+ **/
102
+ const positionFilterSchema = z.object({
103
+ kind: positionKindSchema.optional(),
104
+ isZeroDebt: z.boolean().optional(),
105
+ chainIds: z.array(chainIdSchema).optional(),
106
+ underlyingType: assetTypeSchema.optional()
107
+ });
108
+ //#endregion
109
+ export { pnlBreakdownSchema, pointsProgramPnLSchema, pointsRewardsPnLSchema, poolPositionSchema, positionCollateralSchema, positionFilterSchema, positionKindSchema, positionSchema, rewardsPnLSchema, strategyPositionSchema, tokenRewardsPnLSchema };
@@ -1,5 +1,5 @@
1
- import { iZapperAbi } from "../../abi/iZapper.js";
2
1
  import { iPoolV310Abi } from "../../abi/310/generated.js";
2
+ import { iZapperAbi } from "../../abi/iZapper.js";
3
3
  import { asPreviewSimulationError } from "./errors.js";
4
4
  //#region src/preview/simulate/simulatePoolOperation.ts
5
5
  function previewRead(operation) {
@@ -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,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,4 +1,3 @@
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";
@@ -18,6 +17,7 @@ import { RWA_LIQUIDATOR_SECURITIZE } from "../../market/rwa/securitize/constants
18
17
  import { SecuritizeLiquidatorContract } from "../../market/rwa/securitize/SecuritizeLiquidatorContract.js";
19
18
  import "../../market/rwa/securitize/index.js";
20
19
  import { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./constants.js";
20
+ import { iLiquidationCompressorV313Abi } from "../../../abi/ILiquidationCompressorV313.js";
21
21
  //#region src/sdk/accounts/liquidations/LiquidationsService.ts
22
22
  /**
23
23
  * Service for discovering liquidatable credit accounts and previewing manual
@@ -97,17 +97,12 @@ var LiquidationsService = class extends SDKConstruct {
97
97
  await compressor.loadWithdrawableAssets();
98
98
  const phantomTokens = new AddressSet(compressor.getWithdrawableAssets().map((a) => a.withdrawalPhantomToken));
99
99
  const { claimable, pending } = await compressor.getExternalAccountCurrentWithdrawals(props.liquidator, ...phantomTokens.asArray());
100
- const chainId = this.sdk.chainId;
101
100
  return [...claimable.map((w) => ({
102
- chainId,
103
- sourceToken: this.sdk.tokensMeta.mustGetToken(w.token),
104
- output: this.#withdrawalOutput(w.outputs, w.token),
101
+ ...this.#liquidationPosition(w.token, w.outputs),
105
102
  claimTx: this.#claimTx(w.claimCalls, w.token),
106
103
  redeemer: w.redeemer
107
104
  })), ...pending.map((w) => ({
108
- chainId,
109
- sourceToken: this.sdk.tokensMeta.mustGetToken(w.token),
110
- output: this.#withdrawalOutput(w.expectedOutputs, w.token),
105
+ ...this.#liquidationPosition(w.token, w.expectedOutputs),
111
106
  claimableAt: Number(w.claimableAt),
112
107
  redeemer: w.redeemer
113
108
  }))];
@@ -162,6 +157,22 @@ var LiquidationsService = class extends SDKConstruct {
162
157
  valueUsd: null
163
158
  };
164
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
+ }
165
176
  #withdrawalOutput(outputs, sourceToken) {
166
177
  const [output] = outputs;
167
178
  if (outputs.length !== 1 || !output) throw new Error(`expected exactly one output for withdrawal of ${sourceToken}, got ${outputs.length}`);
@@ -185,7 +196,7 @@ var LiquidationsService = class extends SDKConstruct {
185
196
  return {
186
197
  isDelayed: true,
187
198
  ...amount,
188
- redeemerAddress: hexEq(o.redeemerAddress, "0x0000000000000000000000000000000000000000") ? void 0 : o.redeemerAddress,
199
+ redeemer: hexEq(o.redeemerAddress, "0x0000000000000000000000000000000000000000") ? void 0 : o.redeemerAddress,
189
200
  claimableAt: o.claimableAt === 0n ? void 0 : Number(o.claimableAt)
190
201
  };
191
202
  });
@@ -1,7 +1,7 @@
1
- import { iRedemptionLoggerV310Abi } from "../../../abi/iRedemptionLoggerV310.js";
2
1
  import { BaseContract } from "../../base/BaseContract.js";
3
2
  import "../../base/index.js";
4
3
  import { decodeDelayedIntent } from "./intent-codec.js";
4
+ import { iRedemptionLoggerV310Abi } from "../../../abi/iRedemptionLoggerV310.js";
5
5
  import { InvalidDelayedIntentError } from "./errors.js";
6
6
  //#region src/sdk/accounts/withdrawal-compressor/RedemptionLoggerV310Contract.ts
7
7
  const abi = iRedemptionLoggerV310Abi;
@@ -1,5 +1,5 @@
1
- import { iWithdrawalCompressorV310Abi } from "../../../abi/IWithdrawalCompressorV310.js";
2
1
  import { AbstractWithdrawalCompressorContract } from "./AbstractWithdrawalCompressorContract.js";
2
+ import { iWithdrawalCompressorV310Abi } from "../../../abi/IWithdrawalCompressorV310.js";
3
3
  //#region src/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV310Contract.ts
4
4
  const abi = iWithdrawalCompressorV310Abi;
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { iWithdrawalCompressorV311Abi } from "../../../abi/IWithdrawalCompressorV311.js";
2
1
  import { AbstractWithdrawalCompressorContract } from "./AbstractWithdrawalCompressorContract.js";
2
+ import { iWithdrawalCompressorV311Abi } from "../../../abi/IWithdrawalCompressorV311.js";
3
3
  //#region src/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV311Contract.ts
4
4
  const abi = iWithdrawalCompressorV311Abi;
5
5
  /**
@@ -1,6 +1,6 @@
1
- import { iWithdrawalCompressorV313Abi } from "../../../abi/IWithdrawalCompressorV313.js";
2
1
  import { encodeDelayedIntent } from "./intent-codec.js";
3
2
  import { AbstractWithdrawalCompressorContract, iCreditAccountAbi, toClaimableWithdrawal, toPendingWithdrawal, toRequestableWithdrawal } from "./AbstractWithdrawalCompressorContract.js";
3
+ import { iWithdrawalCompressorV313Abi } from "../../../abi/IWithdrawalCompressorV313.js";
4
4
  import { toWithdrawalStatus } from "./types.js";
5
5
  //#region src/sdk/accounts/withdrawal-compressor/WithdrawalCompressorV313Contract.ts
6
6
  const abi = iWithdrawalCompressorV313Abi;
@@ -1,11 +1,11 @@
1
- import { iStateSerializerAbi } from "../../abi/iStateSerializer.js";
2
- import { iVersionAbi } from "../../abi/iVersion.js";
3
1
  import { AddressMap } from "../utils/AddressMap.js";
4
2
  import { AddressSet } from "../utils/AddressSet.js";
5
3
  import { bytes32ToString } from "../utils/bytes32ToString.js";
6
4
  import { getAssetType } from "../chain/chains.js";
7
5
  import { formatBN } from "../utils/formatter.js";
8
6
  import "../utils/index.js";
7
+ import { iStateSerializerAbi } from "../../abi/iStateSerializer.js";
8
+ import { iVersionAbi } from "../../abi/iVersion.js";
9
9
  //#region src/sdk/base/TokensMeta.ts
10
10
  /**
11
11
  * Registry of token metadata (symbol, decimals, phantom type) keyed by address.
@@ -1,5 +1,5 @@
1
- import { ierc20Abi } from "../../abi/iERC20.js";
2
1
  import { chains } from "./chains.js";
2
+ import { ierc20Abi } from "../../abi/iERC20.js";
3
3
  //#region src/sdk/chain/detectNetwork.ts
4
4
  /**
5
5
  * Detects the network type from the given client.
@@ -1,8 +1,8 @@
1
- import { iVersionAbi } from "../../abi/iVersion.js";
2
1
  import { AP_MARKET_COMPRESSOR, AP_PRICE_FEED_COMPRESSOR } from "../constants/address-provider.js";
3
2
  import { isV310 } from "../constants/versions.js";
4
3
  import "../constants/index.js";
5
4
  import { hexEq } from "../utils/hex.js";
5
+ import { iVersionAbi } from "../../abi/iVersion.js";
6
6
  import { AddressProviderV310Contract } from "./AddressProviderV310Contract.js";
7
7
  //#region src/sdk/core/createAddressProvider.ts
8
8
  const OVERRIDE_ADDRESSES = { Mainnet: {
@@ -3,6 +3,7 @@ import { isRWAToken, isSunsetPool } from "../chain/chains.js";
3
3
  import "../utils/index.js";
4
4
  import { SDKConstruct } from "../base/SDKConstruct.js";
5
5
  import "../base/index.js";
6
+ import { rayToBps } from "./math.js";
6
7
  import { CreditSuite } from "./credit/CreditSuite.js";
7
8
  import "./credit/index.js";
8
9
  import { MarketConfiguratorContract } from "./MarketConfiguratorContract.js";
@@ -189,17 +190,15 @@ var MarketSuite = class extends SDKConstruct {
189
190
  * Every opportunity this market offers: its pool, plus one row per
190
191
  * `(credit manager, target collateral)` pair.
191
192
  *
192
- * @param totals - Resolves the summed worth of the credit accounts backing a
193
- * strategy, which only a credit-account query can establish.
194
193
  * @param filter - Optional narrowing. A filter naming a kind skips building
195
194
  * the other kind entirely; every built row is then checked in full by
196
195
  * {@link matchesOpportunityFilter}, so there is one definition of what each
197
196
  * criterion means.
198
197
  */
199
- opportunities(totals, filter) {
198
+ opportunities(filter) {
200
199
  const rows = [];
201
200
  if (filter?.kind !== "strategy") rows.push(this.poolOpportunity());
202
- if (filter?.kind !== "pool") for (const { suite, collateral } of this.strategies) rows.push(suite.strategyOpportunity(collateral, totals(suite.creditManager.address, collateral)));
201
+ if (filter?.kind !== "pool") for (const { suite, collateral } of this.strategies) rows.push(suite.strategyOpportunity(collateral));
203
202
  return rows.filter((row) => matchesOpportunityFilter(row, filter));
204
203
  }
205
204
  /**
@@ -213,15 +212,13 @@ var MarketSuite = class extends SDKConstruct {
213
212
  kind: "pool",
214
213
  chainId: this.chainId,
215
214
  pool: pool.address,
216
- title: `${this.underlyingToken.symbol} Pool`,
215
+ name: `${this.underlyingToken.symbol} Pool`,
217
216
  curator: this.curator,
218
217
  underlyingToken: this.underlyingToken,
219
- totalSupply: {
220
- value: pool.totalSupply,
221
- valueUsd: oracle.safeUsdValue(pool.underlying, pool.totalAssets)
222
- },
218
+ totalSupply: oracle.toAmount(pool.underlying, pool.totalAssets),
223
219
  totalBorrow: oracle.toAmount(pool.underlying, pool.totalBorrowed),
224
220
  utilization: pool.utilization,
221
+ supplyApy: { organicApy: rayToBps(pool.supplyRate) },
225
222
  collateralTokens: this.collateralTokens,
226
223
  paused: pool.isPaused,
227
224
  rwa: this.rwa,
@@ -256,11 +253,10 @@ var MarketSuite = class extends SDKConstruct {
256
253
  *
257
254
  * @param creditManager - Credit manager the position is opened in.
258
255
  * @param collateral - Target collateral of the position.
259
- * @param totalSupply - Summed worth of the credit accounts backing it.
260
256
  * @throws If this market has no such strategy, see {@link mustFindStrategy}.
261
257
  */
262
- strategyOpportunityDetail(creditManager, collateral, totalSupply) {
263
- return this.mustFindStrategy(creditManager, collateral).suite.strategyOpportunityDetail(collateral, totalSupply);
258
+ strategyOpportunityDetail(creditManager, collateral) {
259
+ return this.mustFindStrategy(creditManager, collateral).suite.strategyOpportunityDetail(collateral);
264
260
  }
265
261
  /**
266
262
  * Whether any child contract wrapper has observed events that require a
@@ -1,7 +1,7 @@
1
- import { iPausableAbi } from "../../../abi/iPausable.js";
2
1
  import { iCreditFacadeMulticallV310Abi, iCreditFacadeV310Abi } from "../../../abi/310/generated.js";
3
2
  import { BaseContract } from "../../base/BaseContract.js";
4
3
  import "../../base/index.js";
4
+ import { iPausableAbi } from "../../../abi/iPausable.js";
5
5
  //#region src/sdk/market/credit/CreditFacadeV310BaseContract.ts
6
6
  const abi = [
7
7
  ...iCreditFacadeV310Abi,
@@ -4,7 +4,7 @@ import "../../constants/math.js";
4
4
  import "../../constants/index.js";
5
5
  import { SDKConstruct } from "../../base/SDKConstruct.js";
6
6
  import "../../base/index.js";
7
- import { additionalBorrowApyBps, borrowApyBps, utilizationBps } from "../math.js";
7
+ import { additionalBorrowApyBps, borrowApyBps } from "../math.js";
8
8
  import createCreditConfigurator from "./createCreditConfigurator.js";
9
9
  import createCreditFacade from "./createCreditFacade.js";
10
10
  import createCreditManager from "./createCreditManager.js";
@@ -145,16 +145,9 @@ var CreditSuite = class extends SDKConstruct {
145
145
  * read model does.
146
146
  *
147
147
  * @param collateral - Target collateral of the position.
148
- * @param totalSupply - Summed worth of the credit accounts backing it, which
149
- * only a credit-account query can establish. Defaults to zero, so a caller
150
- * that does not care about size can omit it.
151
148
  * @throws If the credit manager does not value the collateral.
152
149
  */
153
- strategyOpportunity(collateral, totalSupply_) {
154
- const totalSupply = totalSupply_ ?? {
155
- value: 0n,
156
- valueUsd: 0
157
- };
150
+ strategyOpportunity(collateral) {
158
151
  const { market, creditManager: cm } = this;
159
152
  const { pool } = market.pool;
160
153
  const oracle = market.priceOracle;
@@ -166,12 +159,10 @@ var CreditSuite = class extends SDKConstruct {
166
159
  chainId: this.chainId,
167
160
  creditManager: cm.address,
168
161
  targetCollateral: this.tokensMeta.mustGetToken(collateral),
169
- title: `${this.tokensMeta.symbol(collateral)} / ${market.underlyingToken.symbol}`,
162
+ name: `${this.tokensMeta.symbol(collateral)} / ${market.underlyingToken.symbol}`,
170
163
  curator: market.curator,
171
164
  underlyingToken: market.underlyingToken,
172
- totalSupply,
173
165
  totalBorrow: oracle.toAmount(pool.underlying, borrowed),
174
- utilization: utilizationBps(borrowed, totalSupply.value),
175
166
  collateralTokens: market.collateralTokens,
176
167
  paused: this.isPaused,
177
168
  rwa: market.rwa,
@@ -190,11 +181,10 @@ var CreditSuite = class extends SDKConstruct {
190
181
  * {@link strategyOpportunity} plus the data only its detail screen needs.
191
182
  *
192
183
  * @param collateral - Target collateral of the position.
193
- * @param totalSupply - Summed worth of the credit accounts backing it.
194
184
  */
195
- strategyOpportunityDetail(collateral, totalSupply) {
185
+ strategyOpportunityDetail(collateral) {
196
186
  return {
197
- ...this.strategyOpportunity(collateral, totalSupply),
187
+ ...this.strategyOpportunity(collateral),
198
188
  rateCurve: this.market.pool.rateCurve,
199
189
  priceFeeds: this.market.priceFeedSummary(collateral)
200
190
  };
@@ -1,4 +1,3 @@
1
- import { iPausableAbi } from "../../../abi/iPausable.js";
2
1
  import { iPoolV310Abi } from "../../../abi/310/generated.js";
3
2
  import { AddressMap } from "../../utils/AddressMap.js";
4
3
  import { RAY } from "../../constants/math.js";
@@ -7,6 +6,7 @@ import { formatBN, formatBNvalue, percentFmt } from "../../utils/formatter.js";
7
6
  import "../../utils/index.js";
8
7
  import { BaseContract } from "../../base/BaseContract.js";
9
8
  import "../../base/index.js";
9
+ import { iPausableAbi } from "../../../abi/iPausable.js";
10
10
  import { utilizationBps } from "../math.js";
11
11
  //#region src/sdk/market/pool/PoolV310Contract.ts
12
12
  const abi = [...iPoolV310Abi, ...iPausableAbi];
@@ -1,5 +1,5 @@
1
- import { iethZapperAbi } from "../../../abi/iETHZapper.js";
2
1
  import { ZapperContract } from "./ZapperContract.js";
2
+ import { iethZapperAbi } from "../../../abi/iETHZapper.js";
3
3
  //#region src/sdk/market/zapper/IETHZapperContract.ts
4
4
  const abi = iethZapperAbi;
5
5
  var IETHZapperContract = class extends ZapperContract {
@@ -1,6 +1,6 @@
1
- import { iZapperAbi } from "../../../abi/iZapper.js";
2
1
  import { BaseContract } from "../../base/BaseContract.js";
3
2
  import "../../base/index.js";
3
+ import { iZapperAbi } from "../../../abi/iZapper.js";
4
4
  import { UnsupportedZapperFunctionError } from "./errors.js";
5
5
  //#region src/sdk/market/zapper/ZapperContract.ts
6
6
  /**
@@ -1,40 +1,28 @@
1
1
  import { SDKConstruct } from "../base/SDKConstruct.js";
2
2
  import "../base/index.js";
3
- import { usdToNumber } from "../market/math.js";
4
3
  //#region src/sdk/opportunities/OpportunitiesService.ts
5
4
  /**
6
- * A lookup that knows of no strategy, used when a filter rules strategies out
7
- * and the credit-account query is skipped altogether.
8
- **/
9
- const NO_TOTALS = () => void 0;
10
- /**
11
5
  * Builds the `opportunities` read model from the chain.
12
6
  *
13
- * Everything except the credit-account totals comes from the market state the
14
- * SDK already holds, so a list costs one RPC round-trip at most. Yield figures
15
- * that fold in incentives, points or history are deliberately absent: they are
16
- * the backend's job, and this service never guesses them.
7
+ * Every value in a row is market state the SDK already holds, so a list costs
8
+ * no RPC round-trip at all. Yield figures that fold in incentives, points or
9
+ * history are deliberately absent: they are the backend's job, and this service
10
+ * never guesses them. So is the size of a strategy summing it takes a sweep
11
+ * over every credit account of the chain, which is too expensive for a list.
17
12
  *
18
13
  * The rows themselves are assembled by the market wrappers — see
19
14
  * {@link MarketSuite.opportunities} — because every value in them is market
20
- * state. What is left here is the one thing no single market can answer: how
21
- * much the credit accounts of a strategy are worth.
15
+ * state. This service only picks the markets and applies the filter.
22
16
  **/
23
17
  var OpportunitiesService = class extends SDKConstruct {
24
18
  /**
25
19
  * Every pool and strategy of every loaded market on this chain.
26
20
  *
27
- * Strategies are measured by the value locked in their credit accounts, so
28
- * the list issues one credit-account query unless the filter rules strategies
29
- * out entirely.
30
- *
31
21
  * @param filter - Optional narrowing, applied to the built rows.
32
22
  **/
33
23
  async list(filter) {
34
24
  if (filter?.chainIds && !filter.chainIds.includes(this.chainId)) return [];
35
- const { markets } = this.sdk.marketRegister;
36
- const totals = filter?.kind === "pool" ? NO_TOTALS : await this.#strategyTotals(markets);
37
- return markets.flatMap((market) => market.opportunities(totals, filter));
25
+ return this.sdk.marketRegister.markets.flatMap((market) => market.opportunities(filter));
38
26
  }
39
27
  /**
40
28
  * A single pool opportunity plus its interest rate curve and quotas.
@@ -52,51 +40,8 @@ var OpportunitiesService = class extends SDKConstruct {
52
40
  * collateral as a strategy.
53
41
  **/
54
42
  async getStrategy(key) {
55
- const market = this.sdk.marketRegister.findByCreditManager(key.creditManager);
56
- const { suite } = market.mustFindStrategy(key.creditManager, key.targetCollateral);
57
- const totals = await this.#strategyTotals([market]);
58
- return suite.strategyOpportunityDetail(key.targetCollateral, totals(key.creditManager, key.targetCollateral));
59
- }
60
- /**
61
- * Total value held by the credit accounts backing every strategy of the given
62
- * markets.
63
- *
64
- * An account that holds several strategy collaterals counts in full towards
65
- * each of them: the read model reports what a strategy's accounts are worth,
66
- * not how that worth splits across the collaterals inside them.
67
- **/
68
- async #strategyTotals(markets) {
69
- const wanted = /* @__PURE__ */ new Map();
70
- for (const market of markets) for (const { suite, collateral } of market.strategies) {
71
- const cm = suite.creditManager.address.toLowerCase();
72
- const tokens = wanted.get(cm) ?? /* @__PURE__ */ new Set();
73
- tokens.add(collateral.toLowerCase());
74
- wanted.set(cm, tokens);
75
- }
76
- if (wanted.size === 0) return NO_TOTALS;
77
- const accounts = await this.sdk.accounts.getCreditAccounts({ includeZeroDebt: true });
78
- const totals = /* @__PURE__ */ new Map();
79
- for (const account of accounts) {
80
- const tokens = wanted.get(account.creditManager.toLowerCase());
81
- if (!tokens) continue;
82
- for (const token of account.tokens) {
83
- if (token.balance <= 0n || !tokens.has(token.token.toLowerCase())) continue;
84
- const key = strategyKey(account.creditManager, token.token);
85
- const current = totals.get(key);
86
- totals.set(key, {
87
- value: (current?.value ?? 0n) + account.totalValue,
88
- valueUsd: (current?.valueUsd ?? 0) + usdToNumber(account.totalValueUSD)
89
- });
90
- }
91
- }
92
- return (creditManager, collateral) => totals.get(strategyKey(creditManager, collateral));
43
+ return this.sdk.marketRegister.findByCreditManager(key.creditManager).strategyOpportunityDetail(key.creditManager, key.targetCollateral);
93
44
  }
94
45
  };
95
- /**
96
- * Both halves of a strategy key folded into one map key.
97
- **/
98
- function strategyKey(creditManager, collateral) {
99
- return `${creditManager.toLowerCase()}:${collateral.toLowerCase()}`;
100
- }
101
46
  //#endregion
102
47
  export { OpportunitiesService };
@@ -1,5 +1,5 @@
1
- import { ierc20Abi } from "../../abi/iERC20.js";
2
1
  import { AddressSet } from "../utils/AddressSet.js";
2
+ import { ierc20Abi } from "../../abi/iERC20.js";
3
3
  import "../constants/addresses.js";
4
4
  import "../constants/index.js";
5
5
  import { hexEq } from "../utils/hex.js";
@@ -57,6 +57,40 @@ var RouterV310Contract = class extends AbstractRouterContract {
57
57
  };
58
58
  }
59
59
  /**
60
+ * {@inheritDoc IRouterContract.findManyToOnePath}
61
+ **/
62
+ async findManyToOnePath(props) {
63
+ const { creditAccount, creditManager, expectedBalances, leftoverBalances, target, slippage } = props;
64
+ const expectedMap = new AssetsMap(expectedBalances);
65
+ const leftoverMap = new AssetsMap(leftoverBalances);
66
+ const getNumSplits = this.#numSplitsGetter(creditManager, expectedBalances);
67
+ const tData = creditManager.collateralTokens.map((token) => ({
68
+ token,
69
+ balance: expectedMap.get(token) ?? 0n,
70
+ leftoverBalance: limitLeftover(leftoverMap.get(token), token) ?? 0n,
71
+ numSplits: getNumSplits(token),
72
+ claimRewards: false
73
+ }));
74
+ this.logger?.debug({
75
+ creditAccount: creditAccount.creditAccount,
76
+ creditManager: this.labelAddress(creditManager.address),
77
+ target: this.labelAddress(target),
78
+ slippage,
79
+ tData: this.#debugTokenData(tData)
80
+ }, "calling routeManyToOne");
81
+ const { result } = await this.contract.simulate.routeManyToOne([
82
+ creditAccount.creditAccount,
83
+ target,
84
+ BigInt(slippage),
85
+ tData
86
+ ], { gas: this.sdk.gasLimit });
87
+ return {
88
+ amount: result.amount,
89
+ minAmount: result.minAmount,
90
+ calls: [...result.calls]
91
+ };
92
+ }
93
+ /**
60
94
  * {@inheritDoc IRouterContract.findOpenStrategyPath}
61
95
  **/
62
96
  async findOpenStrategyPath(props) {
@@ -1,6 +1,6 @@
1
1
  import { errorAbis } from "../../../abi/errors.js";
2
- import { iUpdatablePriceFeedAbi } from "../../../abi/iUpdatablePriceFeed.js";
3
2
  import { generateCastTraceCall } from "./cast.js";
3
+ import { iUpdatablePriceFeedAbi } from "../../../abi/iUpdatablePriceFeed.js";
4
4
  import { simulateMulticall } from "./simulateMulticall.js";
5
5
  import { BaseError, CallExecutionError, ContractFunctionRevertedError, decodeFunctionData, decodeFunctionResult, encodeFunctionData, parseAbi } from "viem";
6
6
  import { getAction, parseAccount } from "viem/utils";
@@ -5,5 +5,7 @@ import { historyChartMetadataSchema, historyMetricSchema, historyPointSchema, hi
5
5
  import { DelayedReceivedAsset, InstantReceivedAsset, LiquidatableAccount, LiquidatableAccountFilter, LiquidationApproval, LiquidationDetails, LiquidationPosition, ReceivedAsset, matchesLiquidatableAccountFilter } from "./liquidations.js";
6
6
  import { delayedReceivedAssetSchema, instantReceivedAssetSchema, liquidatableAccountFilterSchema, liquidatableAccountSchema, liquidationApprovalSchema, liquidationDetailsSchema, liquidationPositionSchema, receivedAssetSchema } from "./liquidations.schema.js";
7
7
  import { apyBreakdownSchema, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterSchema, opportunityKeySchema, opportunityKindSchema, opportunitySchema, pointRewardsSchema, pointsProgramSchema, poolOpportunityDetailSchema, poolOpportunityKeySchema, poolOpportunitySchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, rewardsSchema, strategyOpportunityDetailSchema, strategyOpportunityKeySchema, strategyOpportunitySchema, tokenRewardsSchema } from "./opportunities.schema.js";
8
+ import { PnlBreakdown, PointsProgramPnL, PointsRewardsPnL, PoolPosition, Position, PositionCollateral, PositionFilter, PositionKind, RewardsPnL, StrategyPosition, TokenRewardsPnL } from "./positions.js";
9
+ import { pnlBreakdownSchema, pointsProgramPnLSchema, pointsRewardsPnLSchema, poolPositionSchema, positionCollateralSchema, positionFilterSchema, positionKindSchema, positionSchema, rewardsPnLSchema, strategyPositionSchema, tokenRewardsPnLSchema } from "./positions.schema.js";
8
10
  import { amountSchema, assetTypeSchema, bpsSchema, chainIdSchema, curatorSchema, leverageSchema, timestampSchema, tokenAmountSchema, tokenSchema, txCallSchema } from "./primitives.schema.js";
9
- export { Amount, ApyBreakdown, AssetType, Bps, ChainId, Curator, DelayedReceivedAsset, HistoryChartMetadata, HistoryMetric, HistoryPoint, HistoryRange, HistorySeries, InstantReceivedAsset, Leverage, LiquidatableAccount, LiquidatableAccountFilter, LiquidationApproval, LiquidationDetails, LiquidationPosition, Opportunity, OpportunityBase, OpportunityDetail, OpportunityFilter, OpportunityHistoryQuery, OpportunityId, OpportunityKey, OpportunityKind, POOL_HISTORY_METRICS, PointRewards, PointsProgram, PoolHistoryMetric, PoolOpportunity, PoolOpportunityDetail, PoolOpportunityKey, PoolOpportunityRef, PriceFeedData, PriceFeedSummary, QuotaAsset, RateCurve, RateCurvePoint, ReceivedAsset, Rewards, STRATEGY_HISTORY_METRICS, StrategyHistoryMetric, StrategyOpportunity, StrategyOpportunityDetail, StrategyOpportunityKey, StrategyOpportunityRef, Timestamp, Token, TokenAmount, TokenRewards, TxCall, amountSchema, apyBreakdownSchema, assetTypeSchema, bpsSchema, chainIdSchema, curatorSchema, delayedReceivedAssetSchema, historyChartMetadataSchema, historyMetricSchema, historyPointSchema, historyRangeSchema, historySeriesSchema, instantReceivedAssetSchema, leverageSchema, liquidatableAccountFilterSchema, liquidatableAccountSchema, liquidationApprovalSchema, liquidationDetailsSchema, liquidationPositionSchema, matchesLiquidatableAccountFilter, matchesOpportunityFilter, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterSchema, opportunityHistoryQuerySchema, opportunityId, opportunityKeySchema, opportunityKindSchema, opportunitySchema, pointRewardsSchema, pointsProgramSchema, poolHistoryMetricSchema, poolOpportunityDetailSchema, poolOpportunityId, poolOpportunityKeySchema, poolOpportunitySchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, receivedAssetSchema, rewardsSchema, strategyHistoryMetricSchema, strategyOpportunityDetailSchema, strategyOpportunityId, strategyOpportunityKeySchema, strategyOpportunitySchema, timestampSchema, tokenAmountSchema, tokenRewardsSchema, tokenSchema, txCallSchema };
11
+ export { Amount, ApyBreakdown, AssetType, Bps, ChainId, Curator, DelayedReceivedAsset, HistoryChartMetadata, HistoryMetric, HistoryPoint, HistoryRange, HistorySeries, InstantReceivedAsset, Leverage, LiquidatableAccount, LiquidatableAccountFilter, LiquidationApproval, LiquidationDetails, LiquidationPosition, Opportunity, OpportunityBase, OpportunityDetail, OpportunityFilter, OpportunityHistoryQuery, OpportunityId, OpportunityKey, OpportunityKind, POOL_HISTORY_METRICS, PnlBreakdown, PointRewards, PointsProgram, PointsProgramPnL, PointsRewardsPnL, PoolHistoryMetric, PoolOpportunity, PoolOpportunityDetail, PoolOpportunityKey, PoolOpportunityRef, PoolPosition, Position, PositionCollateral, PositionFilter, PositionKind, PriceFeedData, PriceFeedSummary, QuotaAsset, RateCurve, RateCurvePoint, ReceivedAsset, Rewards, RewardsPnL, STRATEGY_HISTORY_METRICS, StrategyHistoryMetric, StrategyOpportunity, StrategyOpportunityDetail, StrategyOpportunityKey, StrategyOpportunityRef, StrategyPosition, Timestamp, Token, TokenAmount, TokenRewards, TokenRewardsPnL, TxCall, amountSchema, apyBreakdownSchema, assetTypeSchema, bpsSchema, chainIdSchema, curatorSchema, delayedReceivedAssetSchema, historyChartMetadataSchema, historyMetricSchema, historyPointSchema, historyRangeSchema, historySeriesSchema, instantReceivedAssetSchema, leverageSchema, liquidatableAccountFilterSchema, liquidatableAccountSchema, liquidationApprovalSchema, liquidationDetailsSchema, liquidationPositionSchema, matchesLiquidatableAccountFilter, matchesOpportunityFilter, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterSchema, opportunityHistoryQuerySchema, opportunityId, opportunityKeySchema, opportunityKindSchema, opportunitySchema, pnlBreakdownSchema, pointRewardsSchema, pointsProgramPnLSchema, pointsProgramSchema, pointsRewardsPnLSchema, poolHistoryMetricSchema, poolOpportunityDetailSchema, poolOpportunityId, poolOpportunityKeySchema, poolOpportunitySchema, poolPositionSchema, positionCollateralSchema, positionFilterSchema, positionKindSchema, positionSchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, receivedAssetSchema, rewardsPnLSchema, rewardsSchema, strategyHistoryMetricSchema, strategyOpportunityDetailSchema, strategyOpportunityId, strategyOpportunityKeySchema, strategyOpportunitySchema, strategyPositionSchema, timestampSchema, tokenAmountSchema, tokenRewardsPnLSchema, tokenRewardsSchema, tokenSchema, txCallSchema };
@@ -118,7 +118,7 @@ interface DelayedReceivedAsset extends TokenAmount {
118
118
  * Redeemer contract transferred to the liquidator, from which the token
119
119
  * becomes claimable. `undefined` when the compressor does not report one.
120
120
  **/
121
- redeemerAddress?: Address;
121
+ redeemer?: Address;
122
122
  /**
123
123
  * Estimated moment a pending withdrawal becomes claimable. `undefined`
124
124
  * means the withdrawal is claimable now.
@@ -148,6 +148,14 @@ interface LiquidationApproval extends TokenAmount {
148
148
  * A single delayed-withdrawal position owned by the liquidator.
149
149
  **/
150
150
  interface LiquidationPosition {
151
+ /**
152
+ * Discriminates this position from the other kinds a wallet can hold.
153
+ **/
154
+ kind: "liquidation";
155
+ /**
156
+ * Display name of the position.
157
+ **/
158
+ name: string;
151
159
  /**
152
160
  * Chain the withdrawal lives on.
153
161
  **/