@gearbox-protocol/sdk 16.4.0-next.4 → 16.4.0-next.6

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 (58) hide show
  1. package/dist/cjs/dev/midasUtils.js +46 -11
  2. package/dist/cjs/onchain/accounts/intents/borrow.js +139 -0
  3. package/dist/cjs/onchain/accounts/intents/{collateral-money.js → collateral-valuation.js} +7 -7
  4. package/dist/cjs/onchain/accounts/intents/index.js +79 -1
  5. package/dist/cjs/onchain/accounts/intents/leverage-band.js +2 -12
  6. package/dist/cjs/onchain/accounts/intents/maxBorrow.js +85 -0
  7. package/dist/cjs/onchain/accounts/intents/maxWithdrawCollateral.js +14 -14
  8. package/dist/cjs/onchain/accounts/intents/open-strategy.js +6 -45
  9. package/dist/cjs/onchain/accounts/intents/testing/sdk-mock.js +1 -0
  10. package/dist/cjs/onchain/accounts/intents/utils/common.js +19 -0
  11. package/dist/cjs/onchain/accounts/intents/utils/credit-account-slice.js +21 -0
  12. package/dist/cjs/onchain/accounts/intents/utils/index.js +2 -0
  13. package/dist/cjs/onchain/accounts/intents/withdraw-limits.js +8 -8
  14. package/dist/cjs/onchain/positions/calcHealthFactor.js +3 -3
  15. package/dist/cjs/onchain/preview/preview/previewOpenStrategyPosition.js +2 -1
  16. package/dist/cjs/sdk/execute/ExecuteApi.js +65 -5
  17. package/dist/cjs/sdk/prepare/PrepareApi.js +86 -12
  18. package/dist/esm/dev/midasUtils.js +47 -12
  19. package/dist/esm/onchain/accounts/intents/borrow.js +137 -0
  20. package/dist/esm/onchain/accounts/intents/{collateral-money.js → collateral-valuation.js} +7 -7
  21. package/dist/esm/onchain/accounts/intents/index.js +79 -1
  22. package/dist/esm/onchain/accounts/intents/leverage-band.js +2 -12
  23. package/dist/esm/onchain/accounts/intents/maxBorrow.js +83 -0
  24. package/dist/esm/onchain/accounts/intents/maxWithdrawCollateral.js +14 -14
  25. package/dist/esm/onchain/accounts/intents/open-strategy.js +6 -45
  26. package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +1 -0
  27. package/dist/esm/onchain/accounts/intents/utils/common.js +19 -1
  28. package/dist/esm/onchain/accounts/intents/utils/credit-account-slice.js +21 -1
  29. package/dist/esm/onchain/accounts/intents/utils/index.js +3 -3
  30. package/dist/esm/onchain/accounts/intents/withdraw-limits.js +8 -8
  31. package/dist/esm/onchain/positions/calcHealthFactor.js +3 -3
  32. package/dist/esm/onchain/preview/preview/previewOpenStrategyPosition.js +2 -1
  33. package/dist/esm/sdk/execute/ExecuteApi.js +65 -5
  34. package/dist/esm/sdk/prepare/PrepareApi.js +86 -12
  35. package/dist/types/dev/midasUtils.d.ts +4 -3
  36. package/dist/types/model/previews.d.ts +11 -2
  37. package/dist/types/onchain/accounts/index.d.ts +4 -3
  38. package/dist/types/onchain/accounts/intents/borrow.d.ts +141 -0
  39. package/dist/types/onchain/accounts/intents/{collateral-money.d.ts → collateral-valuation.d.ts} +8 -8
  40. package/dist/types/onchain/accounts/intents/index.d.ts +78 -2
  41. package/dist/types/onchain/accounts/intents/maxBorrow.d.ts +47 -0
  42. package/dist/types/onchain/accounts/intents/maxWithdrawCollateral.d.ts +3 -3
  43. package/dist/types/onchain/accounts/intents/open-strategy.d.ts +3 -17
  44. package/dist/types/onchain/accounts/intents/testing/sdk-mock.d.ts +2 -0
  45. package/dist/types/onchain/accounts/intents/tests/open-strategy.fixtures.d.ts +2 -2
  46. package/dist/types/onchain/accounts/intents/types.d.ts +6 -1
  47. package/dist/types/onchain/accounts/intents/utils/common.d.ts +15 -1
  48. package/dist/types/onchain/accounts/intents/utils/credit-account-slice.d.ts +14 -1
  49. package/dist/types/onchain/accounts/intents/utils/index.d.ts +3 -3
  50. package/dist/types/onchain/accounts/intents/withdraw-limits.d.ts +1 -1
  51. package/dist/types/onchain/index.d.ts +4 -3
  52. package/dist/types/sdk/execute/index.d.ts +2 -2
  53. package/dist/types/sdk/execute/types.d.ts +48 -6
  54. package/dist/types/sdk/index.d.ts +5 -4
  55. package/dist/types/sdk/prepare/PrepareApi.d.ts +15 -3
  56. package/dist/types/sdk/prepare/index.d.ts +4 -3
  57. package/dist/types/sdk/prepare/types.d.ts +169 -49
  58. package/package.json +1 -1
@@ -16,6 +16,8 @@ var ExecuteApi = class {
16
16
  switch (request.kind) {
17
17
  case "pool": return poolTx(sdk, request);
18
18
  case "open": return openTx(sdk, request);
19
+ case "openEmpty": return openEmptyTx(sdk, request);
20
+ case "borrow": return borrowTx(sdk, request);
19
21
  case "account": return accountTx(sdk, request);
20
22
  }
21
23
  }
@@ -62,17 +64,75 @@ async function openTx(sdk, request) {
62
64
  reopenCreditAccount: state.creditAccount,
63
65
  permits: {},
64
66
  referralCode: 0n,
65
- rwaOptions: await openRwaOptions(sdk, request)
67
+ rwaOptions: await openRwaOptions(sdk, request, request.targetToken)
68
+ });
69
+ }
70
+ /**
71
+ * The opening with nothing in it: no debt to draw, no collateral to take, no
72
+ * path to run and no quota to buy, so `openCA` is left with the price updates
73
+ * the market demands and the facade's own `openCreditAccount`.
74
+ *
75
+ * Nothing is read off the preparation because there is nothing on it. The
76
+ * account holds no token, so an RWA market has none to gate on either.
77
+ **/
78
+ function openEmptyTx(sdk, request) {
79
+ return sdk.accounts.openCA({
80
+ creditManager: request.creditManager,
81
+ to: request.wallet,
82
+ collateral: [],
83
+ ethAmount: 0n,
84
+ debt: 0n,
85
+ calls: [],
86
+ averageQuota: [],
87
+ minQuota: [],
88
+ permits: {},
89
+ referralCode: 0n
90
+ });
91
+ }
92
+ /**
93
+ * A loan is an opening whose debt leaves again, so it is the same `openCA`
94
+ * with `withdrawToken` set: the facade draws the debt, takes the collateral,
95
+ * runs whatever path buys the payout, and sweeps that payout to the wallet.
96
+ *
97
+ * Both quota branches are the one the state carries. An opening has two
98
+ * because the balances it lands on are a router quote; here the account is
99
+ * left holding the collateral the caller named, and a named amount has no
100
+ * floor to differ from.
101
+ **/
102
+ async function borrowTx(sdk, request) {
103
+ const { creditManager, wallet, ethAmount, sim } = request;
104
+ const { state } = sim.data;
105
+ const collateral = {
106
+ token: state.collateral.token.address,
107
+ balance: state.collateral.value
108
+ };
109
+ return sdk.accounts.openCA({
110
+ creditManager,
111
+ to: wallet,
112
+ collateral: [collateral],
113
+ ethAmount,
114
+ debt: state.totalDebt.value,
115
+ calls: state.calls,
116
+ withdrawToken: state.borrowed.token.address,
117
+ averageQuota: state.quotaIncrease,
118
+ minQuota: state.quotaIncrease,
119
+ reopenCreditAccount: state.creditAccount,
120
+ permits: {},
121
+ referralCode: 0n,
122
+ rwaOptions: await openRwaOptions(sdk, request, collateral.token)
66
123
  });
67
124
  }
68
125
  /**
69
126
  * The documented `openCA` contract: ask the market for its open requirements
70
127
  * and hand them back as operation args, with the caller's cached signatures
71
- * attached. `undefined` on non-RWA markets and when no target token is named.
128
+ * attached. `undefined` on non-RWA markets and when no token is named.
129
+ *
130
+ * `token` is the one the account ends up holding, which is what an RWA market
131
+ * gates on: the opening's target, and the borrow's collateral.
72
132
  **/
73
- async function openRwaOptions(sdk, request) {
74
- if (!request.targetToken) return;
75
- const requirements = await sdk.accounts.getOpenAccountRequirements(request.wallet, request.creditManager, { tokenOutAddress: request.targetToken });
133
+ async function openRwaOptions(sdk, request, token) {
134
+ if (!token) return;
135
+ const requirements = await sdk.accounts.getOpenAccountRequirements(request.wallet, request.creditManager, { tokenOutAddress: token });
76
136
  if (requirements?.protocol !== "securitize") return;
77
137
  return {
78
138
  protocol: "securitize",
@@ -195,26 +195,33 @@ var PrepareApi = class extends MultichainConstruct {
195
195
  }
196
196
  }
197
197
  /**
198
+ * {@inheritDoc IOpportunitiesPrepare.openEmptyCreditAccount}
199
+ **/
200
+ async openEmptyCreditAccount(strategy) {
201
+ try {
202
+ const sdk = await this.#chain(strategy.chainId);
203
+ const at = stateBlock(sdk);
204
+ const result = await service(sdk).openEmptyAccountIntent({
205
+ sdk,
206
+ creditManager: strategy.creditManager
207
+ });
208
+ return result.ok ? sdkOk(at) : methodError(result);
209
+ } catch (e) {
210
+ return sdkErr(unexpectedFailure(e));
211
+ }
212
+ }
213
+ /**
198
214
  * {@inheritDoc IOpportunitiesPrepare.openNewStrategy}
199
215
  **/
200
216
  async openNewStrategy(strategy, params) {
201
217
  try {
202
218
  const sdk = await this.#chain(strategy.chainId);
203
219
  const at = stateBlock(sdk);
204
- if (params.empty) return opened(await service(sdk).openStrategyIntent({
205
- sdk,
206
- creditManager: strategy.creditManager,
207
- empty: true
208
- }), at);
209
220
  const targetToken = params.targetToken ?? sdk.marketRegister.findCreditManager(strategy.creditManager).strategyTargetCollateral;
210
221
  if (!targetToken) return sdkErr(noStrategyTargetCollateral(strategy.creditManager));
211
- let creditAccount;
212
- if (params.creditAccount) {
213
- const reused = await slice(sdk, params.creditAccount);
214
- if (!reused || !isAddressEqual(reused.creditManager, strategy.creditManager)) return sdkErr(creditAccountNotFound(params.creditAccount));
215
- if (reused.totalDebt > 0n || reused.tokens.some((t) => t.quota > 0n)) return sdkErr(creditAccountNotEmpty(params.creditAccount));
216
- creditAccount = reused;
217
- }
222
+ const reused = await reusable(sdk, strategy, params.creditAccount);
223
+ if (reused && "error" in reused) return reused;
224
+ const creditAccount = reused?.account;
218
225
  return opened(await service(sdk).openStrategyIntent({
219
226
  sdk,
220
227
  creditManager: strategy.creditManager,
@@ -231,6 +238,30 @@ var PrepareApi = class extends MultichainConstruct {
231
238
  }
232
239
  }
233
240
  /**
241
+ * {@inheritDoc IOpportunitiesPrepare.borrow}
242
+ **/
243
+ async borrow(strategy, params) {
244
+ try {
245
+ const sdk = await this.#chain(strategy.chainId);
246
+ const at = stateBlock(sdk);
247
+ const reused = await reusable(sdk, strategy, params.creditAccount);
248
+ if (reused && "error" in reused) return reused;
249
+ return borrowed(await service(sdk).borrowIntent({
250
+ sdk,
251
+ creditManager: strategy.creditManager,
252
+ collateralToken: params.collateralToken,
253
+ collateralAmount: params.collateralAmount,
254
+ borrowToken: params.borrowToken,
255
+ borrowAmount: params.borrowAmount,
256
+ slippage: params.slippage,
257
+ quotaReserve: params.quotaReserve,
258
+ creditAccount: reused?.account
259
+ }), at);
260
+ } catch (e) {
261
+ return sdkErr(unexpectedFailure(e));
262
+ }
263
+ }
264
+ /**
234
265
  * {@inheritDoc IOpportunitiesPrepare.depositStrategy}
235
266
  **/
236
267
  async depositStrategy(position, params) {
@@ -353,6 +384,21 @@ var PrepareApi = class extends MultichainConstruct {
353
384
  });
354
385
  }
355
386
  /**
387
+ * {@inheritDoc IOpportunitiesPrepare.maxBorrow}
388
+ **/
389
+ maxBorrow(strategy, params) {
390
+ const sdk = this.sdk.chain(strategy.chainId);
391
+ return service(sdk).maxBorrow({
392
+ sdk,
393
+ creditManager: strategy.creditManager,
394
+ collateralToken: params.collateralToken,
395
+ collateralAmount: params.collateralAmount,
396
+ borrowToken: params.borrowToken,
397
+ targetHF: params.targetHF,
398
+ quotaReserve: params.quotaReserve
399
+ });
400
+ }
401
+ /**
356
402
  * The account a bare `max*` read weighs. These reads answer a number, not
357
403
  * an envelope, so an account the markets do not hold is thrown rather than
358
404
  * described, see {@link IOpportunitiesPrepare.maxWithdraw}.
@@ -438,6 +484,25 @@ async function slice(sdk, creditAccount) {
438
484
  return data && toCreditAccountSlice(data);
439
485
  }
440
486
  /**
487
+ * The pre-opened account a request asks to be run on, held to what "pre-opened"
488
+ * means: this manager's, owing nothing and holding no quota.
489
+ *
490
+ * Shared by the two flows that put something on a fresh account — an opening
491
+ * and a borrow — so both hold a reused one to the same terms. Whatever
492
+ * balances sit on it are left to the flow: an opening routes them, a borrow
493
+ * leaves them where they are.
494
+ *
495
+ * @returns Nothing when the request named no account, the refusal to answer
496
+ * with when it named one that does not qualify, and the slice otherwise
497
+ **/
498
+ async function reusable(sdk, strategy, creditAccount) {
499
+ if (!creditAccount) return;
500
+ const account = await slice(sdk, creditAccount);
501
+ if (!account || !isAddressEqual(account.creditManager, strategy.creditManager)) return sdkErr(creditAccountNotFound(creditAccount));
502
+ if (account.totalDebt > 0n || account.tokens.some((t) => t.quota > 0n)) return sdkErr(creditAccountNotEmpty(creditAccount));
503
+ return { account };
504
+ }
505
+ /**
441
506
  * The operation a claim resumes, or `undefined` when there is none to resume:
442
507
  * a withdrawal requested without an intent, or one read through a compressor
443
508
  * too old to report it. Every intent the engine records can be finished,
@@ -537,6 +602,15 @@ function opened(result, at) {
537
602
  }
538
603
  /**
539
604
  * {@inheritDoc planned}
605
+ **/
606
+ function borrowed(result, at) {
607
+ return result.ok ? sdkOk({
608
+ state: result.state,
609
+ ...at
610
+ }) : methodError(result);
611
+ }
612
+ /**
613
+ * {@inheritDoc planned}
540
614
  *
541
615
  * Both routes are payload, error and all: `errors` says why a missing one is
542
616
  * missing, and it stays on the error when neither route answered, since that is
@@ -22,9 +22,10 @@ interface UnpauseMidasIssuanceVaultProps {
22
22
  */
23
23
  type RestoreMidasIssuanceVaultPause = () => Promise<void>;
24
24
  /**
25
- * Unpauses a globally paused Midas issuance vault on an anvil fork, so that
26
- * `depositInstant` stops reverting with `Pausable: paused`, and returns a
27
- * callback that restores the original pause state.
25
+ * Unpauses a Midas issuance vault on an anvil fork so that `depositInstant`
26
+ * stops reverting with `Pausable: paused` (global) or `Pausable: fn paused`
27
+ * (per-selector), and returns a callback that restores the original pause
28
+ * state of each layer that was cleared.
28
29
  *
29
30
  * Impersonates `admin` and grants it `pauseAdminRole()` when missing, same as
30
31
  * `greenlistMidasGateway` does with the greenlist roles. The grant is not
@@ -369,6 +369,15 @@ interface OpenStrategyPositionProjection extends EstimatedProjection {
369
369
  * accordingly (omitted entirely when it reaches zero).
370
370
  */
371
371
  collateralAdded: TokenAmount[];
372
+ /**
373
+ * Tokens the same transaction hands back to the wallet
374
+ * (`withdrawCollateral` calls, with the MAX_UINT256 sentinel resolved
375
+ * against replayed balances).
376
+ *
377
+ * Empty for an opening that keeps everything it bought; a borrow pays its
378
+ * loan out here, and the values above are what is left once it has.
379
+ */
380
+ collateralWithdrawn: TokenAmount[];
372
381
  /**
373
382
  * The oracle could not price a token; it contributes nothing to the values.
374
383
  */
@@ -376,8 +385,8 @@ interface OpenStrategyPositionProjection extends EstimatedProjection {
376
385
  }
377
386
  /**
378
387
  * What an account-opening transaction that already exists would do — the
379
- * counterpart of `prepare.openNewStrategy`, read off calldata rather than
380
- * planned into it.
388
+ * counterpart of `prepare.openNewStrategy` and `prepare.borrow`, read off
389
+ * calldata rather than planned into it.
381
390
  **/
382
391
  interface OpenStrategyPositionPreview extends OpenStrategyPositionProjection {
383
392
  operation: "OpenCreditAccount";
@@ -19,17 +19,18 @@ import { AccountBotsService } from "./bots/AccountBotsService.js";
19
19
  import { PeripheryCompressorV310Contract } from "./bots/PeripheryCompressorV310Contract.js";
20
20
  import "./bots/index.js";
21
21
  import { CreditAccountsServiceV310 } from "./CreditAccountsServiceV310.js";
22
- import { LeverageBand } from "./intents/leverage-band.js";
23
22
  import { CalcDefaultQuotaProps, CalcQuotaUpdateProps, CalcRecommendedQuotaProps, calcDefaultQuota, calcQuotaUpdate, calcRecommendedQuota, roundUpQuota } from "./quota-utils.js";
24
23
  import { AccountCalculatorOperation } from "./intents/operations.js";
25
24
  import { AddCollateralIntent, AdjustLeverageIntent, ClaimRemainder, CreditAccountSlice, DelayableIntent, DelayedRoute, DelayedStart, DelayedStartResult, DepositStrategyIntent, FinishIntentProps, FinishIntentResult, InstantRoute, IntentPreviewResult, IntentRoutesResult, OperationState, PathLossRate, RepayStrategyIntent, ResumableIntent, RouteErrors, StartIntent, WithdrawAssetIntent, WithdrawCeilings, WithdrawStrategyIntent } from "./intents/types.js";
25
+ import { BorrowProps, BorrowState } from "./intents/borrow.js";
26
+ import { LeverageBand } from "./intents/leverage-band.js";
26
27
  import { OpenStrategyProps, OpenStrategyState } from "./intents/open-strategy.js";
27
28
  import { fetchCreditAccountSlice, toCreditAccountSlice } from "./intents/utils/credit-account-slice.js";
28
29
  import { isPhantomToken } from "./intents/utils/pick-token.js";
29
- import { CreditAccountOperationsService, OpenStrategyPreviewResult } from "./intents/index.js";
30
+ import { BorrowPreviewResult, CreditAccountOperationsService, EmptyAccountPreviewResult, OpenStrategyPreviewResult } from "./intents/index.js";
30
31
  import { LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS } from "./liquidations/constants.js";
31
32
  import { BuildLiquidationTxProps, BuildLiquidationTxPropsBase, GetLiquidatableAccountsProps, GetLiquidationDetailsProps, GetLiquidationDetailsPropsBase, GetLiquidationPositionsProps, GetLiquidationPositionsPropsBase, LoadRWALiquidatorsProps, OnchainLiquidationCall, OnchainLiquidationData, OnchainLiquidationOutput, RWALiquidatorInfo } from "./liquidations/types.js";
32
33
  import { LiquidationsService } from "./liquidations/LiquidationsService.js";
33
34
  import { MultichainLiquidationsService } from "./liquidations/MultichainLiquidationsService.js";
34
35
  import "./liquidations/index.js";
35
- export { AbstractWithdrawalCompressorContract, AccountBotsService, type AccountCalculatorOperation, AccountToCheck, type AddCollateralIntent, type AdjustLeverageIntent, AssembleCaOperationsProps, AssembleClaimDelayedCallsProps, AssembleCloseCreditAccountCallsProps, AssembleRepayCreditAccountCallsProps, AssembleStartDelayedWithdrawalCallsProps, BotStatusCall, BotsDirectResponse, BuildLiquidationTxProps, BuildLiquidationTxPropsBase, CMSlice, CalcDefaultQuotaProps, CalcQuotaUpdateProps, CalcRecommendedQuotaProps, ClaimFarmRewardsProps, type ClaimRemainder, ClaimableWithdrawal, CloseCreditAccountResult, ConnectedBotsCall, ConnectedBotsPerAccount, CreditAccountCompressor, CreditAccountCompressorV310Contract, CreditAccountDataCall, CreditAccountFilter, CreditAccountOperationResult, CreditAccountOperationsService, CreditAccountReadOptions, type CreditAccountSlice, CreditAccountsCall, CreditAccountsQuery, CreditAccountsReadOptions, CreditAccountsServiceV310, CreditAccountsTarget, CreditManagerFilter, CreditManagerOperationResult, CurrentWithdrawals, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, type DelayableIntent, DelayedIntentExtended, type DelayedRoute, type DelayedStart, type DelayedStartResult, type DepositStrategyIntent, EncodableCreditAccountOperation, type FinishIntentProps, type FinishIntentResult, FullyLiquidateProps, FullyLiquidateResult, GetApprovalAddressProps, GetConnectedBotsResponse, GetConnectedBotsResult, GetConnectedMigrationBotsResult, GetCreditAccountsArgs, GetCreditAccountsOptions, GetExternalAccountCurrentWithdrawalsProps, GetLiquidatableAccountsProps, GetLiquidationDetailsProps, GetLiquidationDetailsPropsBase, GetLiquidationPositionsProps, GetLiquidationPositionsPropsBase, GetWithdrawalRequestResultProps, ICreditAccountsService, IRedemptionLoggerContract, IWithdrawalCompressorContract, type InstantRoute, type IntentPreviewResult, type IntentRoutesResult, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, type LeverageBand, LiquidationsService, LoadRWALiquidatorsProps, MulticallWithFailure, MultichainLiquidationsService, OnchainLiquidationCall, OnchainLiquidationData, OnchainLiquidationOutput, OnchainRequestableWithdrawal, OpenCAProps, OpenStrategyPreviewResult, type OpenStrategyProps, type OpenStrategyState, type OperationState, PartiallyLiquidateProps, type PathLossRate, PendingWithdrawal, PeripheryCompressorV310Contract, PreviewDelayedWithdrawalProps, RWALiquidatorInfo, RedemptionLog, RedemptionLoggerV310Contract, type RepayStrategyIntent, RequestableWithdrawal, type ResumableIntent, Rewards, type RouteErrors, SetBotProps, SetBotResult, type StartIntent, type WithdrawAssetIntent, type WithdrawCeilings, type WithdrawStrategyIntent, WithdrawableAsset, WithdrawalCompressorLocation, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, WithdrawalCompressorVersion, WithdrawalOutput, WithdrawalStatus, WithdrawalsState, calcDefaultQuota, calcQuotaUpdate, calcRecommendedQuota, createRedemptionLogger, createWithdrawalCompressor, decodeDelayedIntent, encodeDelayedIntent, fetchCreditAccountSlice, getWithdrawalCompressorAddress, iCreditAccountAbi, isPhantomToken, roundUpQuota, toClaimableWithdrawal, toCreditAccountSlice, toPendingWithdrawal, toRequestableWithdrawal, toWithdrawalStatus };
36
+ export { AbstractWithdrawalCompressorContract, AccountBotsService, type AccountCalculatorOperation, AccountToCheck, type AddCollateralIntent, type AdjustLeverageIntent, AssembleCaOperationsProps, AssembleClaimDelayedCallsProps, AssembleCloseCreditAccountCallsProps, AssembleRepayCreditAccountCallsProps, AssembleStartDelayedWithdrawalCallsProps, BorrowPreviewResult, type BorrowProps, type BorrowState, BotStatusCall, BotsDirectResponse, BuildLiquidationTxProps, BuildLiquidationTxPropsBase, CMSlice, CalcDefaultQuotaProps, CalcQuotaUpdateProps, CalcRecommendedQuotaProps, ClaimFarmRewardsProps, type ClaimRemainder, ClaimableWithdrawal, CloseCreditAccountResult, ConnectedBotsCall, ConnectedBotsPerAccount, CreditAccountCompressor, CreditAccountCompressorV310Contract, CreditAccountDataCall, CreditAccountFilter, CreditAccountOperationResult, CreditAccountOperationsService, CreditAccountReadOptions, type CreditAccountSlice, CreditAccountsCall, CreditAccountsQuery, CreditAccountsReadOptions, CreditAccountsServiceV310, CreditAccountsTarget, CreditManagerFilter, CreditManagerOperationResult, CurrentWithdrawals, DELAYED_INTENT_TYPES, DELAYED_INTENT_VERSION, type DelayableIntent, DelayedIntentExtended, type DelayedRoute, type DelayedStart, type DelayedStartResult, type DepositStrategyIntent, EmptyAccountPreviewResult, EncodableCreditAccountOperation, type FinishIntentProps, type FinishIntentResult, FullyLiquidateProps, FullyLiquidateResult, GetApprovalAddressProps, GetConnectedBotsResponse, GetConnectedBotsResult, GetConnectedMigrationBotsResult, GetCreditAccountsArgs, GetCreditAccountsOptions, GetExternalAccountCurrentWithdrawalsProps, GetLiquidatableAccountsProps, GetLiquidationDetailsProps, GetLiquidationDetailsPropsBase, GetLiquidationPositionsProps, GetLiquidationPositionsPropsBase, GetWithdrawalRequestResultProps, ICreditAccountsService, IRedemptionLoggerContract, IWithdrawalCompressorContract, type InstantRoute, type IntentPreviewResult, type IntentRoutesResult, LIQUIDATION_APPROVAL_BUFFER, LIQUIDATION_COMPRESSOR_V313_ADDRESS, type LeverageBand, LiquidationsService, LoadRWALiquidatorsProps, MulticallWithFailure, MultichainLiquidationsService, OnchainLiquidationCall, OnchainLiquidationData, OnchainLiquidationOutput, OnchainRequestableWithdrawal, OpenCAProps, OpenStrategyPreviewResult, type OpenStrategyProps, type OpenStrategyState, type OperationState, PartiallyLiquidateProps, type PathLossRate, PendingWithdrawal, PeripheryCompressorV310Contract, PreviewDelayedWithdrawalProps, RWALiquidatorInfo, RedemptionLog, RedemptionLoggerV310Contract, type RepayStrategyIntent, RequestableWithdrawal, type ResumableIntent, Rewards, type RouteErrors, SetBotProps, SetBotResult, type StartIntent, type WithdrawAssetIntent, type WithdrawCeilings, type WithdrawStrategyIntent, WithdrawableAsset, WithdrawalCompressorLocation, WithdrawalCompressorV310Contract, WithdrawalCompressorV311Contract, WithdrawalCompressorV313Contract, WithdrawalCompressorVersion, WithdrawalOutput, WithdrawalStatus, WithdrawalsState, calcDefaultQuota, calcQuotaUpdate, calcRecommendedQuota, createRedemptionLogger, createWithdrawalCompressor, decodeDelayedIntent, encodeDelayedIntent, fetchCreditAccountSlice, getWithdrawalCompressorAddress, iCreditAccountAbi, isPhantomToken, roundUpQuota, toClaimableWithdrawal, toCreditAccountSlice, toPendingWithdrawal, toRequestableWithdrawal, toWithdrawalStatus };
@@ -0,0 +1,141 @@
1
+ import { TokenAmount } from "../../../model/primitives.js";
2
+ import "../../../model/index.js";
3
+ import { Asset } from "../../base/types.js";
4
+ import { MultiCall } from "../../types/transactions.js";
5
+ import { OnchainSDK } from "../../OnchainSDK.js";
6
+ import { CreditAccountSlice, OperationState } from "./types.js";
7
+ import "../../index.js";
8
+ import { Address } from "viem";
9
+ //#region src/onchain/accounts/intents/borrow.d.ts
10
+ /**
11
+ * Taking a loan against collateral, in one transaction that opens the account.
12
+ *
13
+ * The plainest thing a credit account can do, and the one shape of it the
14
+ * leveraged flows cannot express: the borrowed funds do not stay on the
15
+ * account to be traded, they go to the wallet. What is left behind is the
16
+ * collateral and the debt it backs.
17
+ */
18
+ interface BorrowProps {
19
+ sdk: OnchainSDK;
20
+ /** Credit manager to open the account in. */
21
+ creditManager: Address;
22
+ /** Token the wallet puts up, in the manager's collateral list. */
23
+ collateralToken: Address;
24
+ /** Amount of {@link collateralToken}, in its own units. */
25
+ collateralAmount: bigint;
26
+ /**
27
+ * Token the loan is paid out in. The market underlying needs no trade;
28
+ * anything else is bought with the borrowed underlying on the way out.
29
+ *
30
+ * On an RWA market the underlying is a compliance wrapper that cannot leave
31
+ * the account, so the payout there is the asset behind it — USDC rather than
32
+ * dcUSDC — and the wrapper itself is refused.
33
+ */
34
+ borrowToken: Address;
35
+ /** Amount of {@link borrowToken} the wallet asks for, in its own units. */
36
+ borrowAmount: bigint;
37
+ /** Router slippage in PERCENTAGE_FORMAT (100% = 10_000). */
38
+ slippage: number | undefined;
39
+ /** Extra quota headroom in PERCENTAGE_FORMAT. */
40
+ quotaReserve: number | undefined;
41
+ /**
42
+ * Existing credit account to draw the loan on, instead of opening one.
43
+ *
44
+ * Must carry no debt and no quotas, as a reused opening must. Borrowing on
45
+ * an account that already owes is what the `ADJUST_LEVERAGE` intent is for.
46
+ **/
47
+ creditAccount?: CreditAccountSlice;
48
+ }
49
+ /**
50
+ * Where a borrow leaves the wallet and the account it opens.
51
+ *
52
+ * A whole {@link OperationState}, holdings included: unlike an opening, a
53
+ * borrow has no second branch of balances to choose between — the collateral
54
+ * is the only thing left on the account and its amount is known exactly.
55
+ * Slippage lands on the payout instead, which is why that one is reported
56
+ * twice.
57
+ *
58
+ * Being that state rather than merely resembling it is what lets a borrow
59
+ * result go straight to `checkSimulation`, which weighs whatever the engine
60
+ * projected: the market, the debt, the quotas and the two factors, all of
61
+ * which a borrow reports where an operation on an existing account does.
62
+ */
63
+ interface BorrowState extends OperationState {
64
+ /** What the wallet puts up, as it will sit on the account. */
65
+ collateral: TokenAmount;
66
+ /**
67
+ * What the wallet is expected to receive, in the token it asked for. Equal
68
+ * to the debt when that token is the market underlying, and to the debt
69
+ * rescaled where an RWA payout unwraps it one for one; in neither case is
70
+ * anything traded.
71
+ */
72
+ borrowed: TokenAmount;
73
+ /**
74
+ * The floor under {@link borrowed} once slippage is allowed for — what the
75
+ * transaction is signed against. Equal to `borrowed` when nothing is traded.
76
+ */
77
+ minBorrowed: TokenAmount;
78
+ /**
79
+ * Router slippage the payout leg was quoted at, in PERCENTAGE_FORMAT
80
+ * (100% = 10_000). The SDK's own default where the caller named none.
81
+ */
82
+ slippage: number;
83
+ /**
84
+ * Quota to buy for the collateral; feeds `openCA.averageQuota` and
85
+ * `openCA.minQuota` alike, both branches being the same here.
86
+ *
87
+ * Transport for the transaction rather than something to display, like
88
+ * {@link calls} below.
89
+ */
90
+ quotaIncrease: Asset[];
91
+ /**
92
+ * The leg that turns the borrowed underlying into the payout: a router path
93
+ * where it is bought, the vault redemption where an RWA market unwraps it,
94
+ * empty where the payout is the underlying itself. Feeds `openCA.calls`,
95
+ * which places it before the withdrawal.
96
+ */
97
+ calls: MultiCall[];
98
+ /**
99
+ * The account this loan was simulated against and must be executed on, when
100
+ * it reuses one; `undefined` for a borrow that opens its own.
101
+ *
102
+ * Carried here rather than asked of the caller again at `buildTx`, so the
103
+ * transaction cannot be built against an account the numbers were not
104
+ * computed for.
105
+ **/
106
+ creditAccount?: Address;
107
+ }
108
+ /**
109
+ * Builds the state a borrow would leave behind.
110
+ *
111
+ * The debt is named rather than derived: a borrow asks for an amount, where an
112
+ * opening asks for a leverage and lets the collateral decide. Everything the
113
+ * loan pays out leaves the account, so the collateral alone backs it — which
114
+ * is what makes the health factor here a straight function of the two amounts.
115
+ *
116
+ * Produces no operation list, as opening never does: the caller hands the
117
+ * numbers and the calls to `sdk.accounts.openCA`, with `withdrawToken` set to
118
+ * the payout.
119
+ */
120
+ declare function buildBorrowState(props: BorrowProps): Promise<BorrowState>;
121
+ /** Inputs of {@link borrowCollateralQuota}. */
122
+ interface BorrowCollateralQuotaProps {
123
+ sdk: OnchainSDK;
124
+ creditManager: Address;
125
+ /** Collateral the fresh account will hold. */
126
+ assets: Asset[];
127
+ /** Extra quota headroom in PERCENTAGE_FORMAT. */
128
+ quotaReserve: number | undefined;
129
+ }
130
+ /**
131
+ * Quota a borrow buys for its collateral on an account that holds none yet.
132
+ *
133
+ * Shared with `maxBorrow`, because a quota short of the collateral's weighted
134
+ * value is what caps the loan: the two have to read the same number or the
135
+ * ceiling one offers is one the other refuses.
136
+ *
137
+ * @param props - {@link BorrowCollateralQuotaProps}
138
+ **/
139
+ declare function borrowCollateralQuota({ sdk, creditManager, assets, quotaReserve }: BorrowCollateralQuotaProps): Asset[];
140
+ //#endregion
141
+ export { BorrowCollateralQuotaProps, BorrowProps, BorrowState, borrowCollateralQuota, buildBorrowState };
@@ -2,7 +2,7 @@ import { OnchainSDK } from "../../OnchainSDK.js";
2
2
  import { CreditAccountSlice } from "./types.js";
3
3
  import "../../index.js";
4
4
  import { Address } from "viem";
5
- //#region src/onchain/accounts/intents/collateral-money.d.ts
5
+ //#region src/onchain/accounts/intents/collateral-valuation.d.ts
6
6
  /** One balance on the account, as the slice carries it. */
7
7
  type Holding = CreditAccountSlice["tokens"][number];
8
8
  /**
@@ -17,10 +17,10 @@ type Holding = CreditAccountSlice["tokens"][number];
17
17
  * exempt and stays on the main feed, as `CreditManagerV3._safeConvertToUSD`
18
18
  * does.
19
19
  *
20
- * Money is carried in USD × `PERCENTAGE_FACTOR`, the units the check compares
21
- * in, so a threshold never has to be divided back out.
20
+ * Every figure is carried in USD × `PERCENTAGE_FACTOR`, the units the check
21
+ * compares in, so a threshold never has to be divided back out.
22
22
  */
23
- interface CollateralMoney {
23
+ interface CollateralValuation {
24
24
  /** Market underlying, the one token safe pricing does not touch. */
25
25
  underlying: Address;
26
26
  /** Whether the holding is weighed at all. */
@@ -28,7 +28,7 @@ interface CollateralMoney {
28
28
  /** What the holding backs, in USD × `PERCENTAGE_FACTOR`. */
29
29
  weigh(holding: Holding): bigint;
30
30
  /** What the holding's quota backs, in the same units; 0 on a closed market. */
31
- quotaMoney(holding: Holding): bigint;
31
+ quotaValue(holding: Holding): bigint;
32
32
  /** USD at the main feed; `undefined` when the token has no price at all. */
33
33
  mainUsd(token: Address, amount: bigint): bigint | undefined;
34
34
  /** USD the check counts the holding at, before its threshold. */
@@ -36,7 +36,7 @@ interface CollateralMoney {
36
36
  /** Liquidation threshold in basis points; 0 for a token the manager refuses. */
37
37
  lt(token: Address): bigint;
38
38
  }
39
- /** {@inheritDoc CollateralMoney} */
40
- declare function collateralMoney(creditAccount: CreditAccountSlice, sdk: OnchainSDK): CollateralMoney;
39
+ /** {@inheritDoc CollateralValuation} */
40
+ declare function collateralValuation(creditAccount: CreditAccountSlice, sdk: OnchainSDK): CollateralValuation;
41
41
  //#endregion
42
- export { CollateralMoney, Holding, collateralMoney };
42
+ export { CollateralValuation, Holding, collateralValuation };
@@ -2,9 +2,11 @@ import { SDKError } from "../../../model/result.js";
2
2
  import "../../../model/index.js";
3
3
  import { SDKConstruct } from "../../base/SDKConstruct.js";
4
4
  import { IntentValidationError } from "../../validation/raise.js";
5
- import { LeverageBand, LeverageBandProps } from "./leverage-band.js";
6
5
  import { AccountCalculatorOperation } from "./operations.js";
7
6
  import { AddCollateralIntent, AdjustLeverageIntent, ClaimRemainder, CreditAccountSlice, DelayableIntent, DelayedRoute, DelayedStart, DelayedStartResult, DepositStrategyIntent, FinishIntentProps, FinishIntentResult, InstantRoute, IntentPreviewResult, IntentRoutesResult, OperationState, PathLossRate, RepayStrategyIntent, ResumableIntent, RouteErrors, StartIntent, StartIntentProps, WithdrawAssetIntent, WithdrawCeilings, WithdrawStrategyIntent } from "./types.js";
7
+ import { BorrowProps, BorrowState } from "./borrow.js";
8
+ import { LeverageBand, LeverageBandProps } from "./leverage-band.js";
9
+ import { MaxBorrowProps } from "./maxBorrow.js";
8
10
  import { OpenStrategyProps, OpenStrategyState } from "./open-strategy.js";
9
11
  import { fetchCreditAccountSlice, toCreditAccountSlice } from "./utils/credit-account-slice.js";
10
12
  import { isPhantomToken } from "./utils/pick-token.js";
@@ -21,6 +23,22 @@ type OpenStrategyPreviewResult = {
21
23
  ok: true;
22
24
  state: OpenStrategyState;
23
25
  } | SDKError<IntentValidationError>;
26
+ /**
27
+ * Borrow preview outcome, shaped like {@link OpenStrategyPreviewResult}: both
28
+ * open an account, so neither has an operation chain to report.
29
+ */
30
+ type BorrowPreviewResult = {
31
+ ok: true;
32
+ state: BorrowState;
33
+ } | SDKError<IntentValidationError>;
34
+ /**
35
+ * Empty-account preview outcome: the thinnest of the three, since an account
36
+ * that holds nothing has no state to project — only the market's own refusal
37
+ * to open one at all.
38
+ */
39
+ type EmptyAccountPreviewResult = {
40
+ ok: true;
41
+ } | SDKError<IntentValidationError>;
24
42
  /** An intent plus everything previewing it needs. */
25
43
  type StartProps = StartIntentProps & {
26
44
  intent: StartIntent;
@@ -119,6 +137,27 @@ declare class CreditAccountOperationsService extends SDKConstruct {
119
137
  token: Address;
120
138
  targetHF?: bigint;
121
139
  }): bigint;
140
+ /**
141
+ * Largest loan a given collateral supports at `targetHF`, in the payout
142
+ * token's units — the ceiling a borrow form should offer, and the amount
143
+ * {@link borrowIntent} will accept at the top of its range.
144
+ *
145
+ * Reads no account, like {@link leverageBand}: the borrow opens one. The
146
+ * collateral is valued the way the transaction will be judged, at safe
147
+ * prices and under the quota the borrow buys, and the answer is then held to
148
+ * what the market will lend.
149
+ *
150
+ * The default is {@link MIN_HF_LIMITED}, the threshold a form holds an
151
+ * account to.
152
+ *
153
+ * @param props - The manager, the SDK holding its market, the collateral put
154
+ * up, the token to be paid in, and optionally the health factor to land at
155
+ * @returns Amount in the payout token's units; `0n` where no loan of this
156
+ * shape can be funded
157
+ */
158
+ maxBorrow(props: Omit<MaxBorrowProps, "targetHF"> & {
159
+ targetHF?: bigint;
160
+ }): bigint;
122
161
  /**
123
162
  * Previews the same operation when its source only redeems through its
124
163
  * issuer: a Securitize dsToken, a Mellow share.
@@ -186,6 +225,21 @@ declare class CreditAccountOperationsService extends SDKConstruct {
186
225
  * beside it, so both halves of an operation are consumed the same way
187
226
  */
188
227
  finishIntent(props: FinishIntentProps): Promise<FinishIntentResult>;
228
+ /**
229
+ * Previews opening an account that holds nothing.
230
+ *
231
+ * Nothing is put up, drawn or routed, so there is no state to build and no
232
+ * guard to run beyond the market's own: a paused or expired facade takes no
233
+ * multicall, and an opening is a multicall like any other. Answers the same
234
+ * envelope its two neighbours do so a caller branches on `ok` throughout.
235
+ *
236
+ * @param props - The SDK holding the market, and the manager to open in
237
+ * @returns `{ ok: true }`, or `{ ok: false, error }` when the market takes
238
+ * no transaction right now
239
+ */
240
+ openEmptyAccountIntent(props: Pick<StartIntentProps, "sdk"> & {
241
+ creditManager: Address;
242
+ }): Promise<EmptyAccountPreviewResult>;
189
243
  /**
190
244
  * Previews opening a brand-new leveraged position.
191
245
  *
@@ -199,6 +253,28 @@ declare class CreditAccountOperationsService extends SDKConstruct {
199
253
  * leverage or the resulting debt is not viable
200
254
  */
201
255
  openStrategyIntent(props: OpenStrategyProps): Promise<OpenStrategyPreviewResult>;
256
+ /**
257
+ * Previews taking a loan against collateral, on an account this same
258
+ * transaction opens.
259
+ *
260
+ * Sits beside {@link openStrategyIntent} rather than under
261
+ * {@link startIntent} for the same reason: there is no account yet, and the
262
+ * output feeds `sdk.accounts.openCA`. What sets it apart from an opening is
263
+ * where the loan goes — out to the wallet rather than into a position — so
264
+ * the debt is named outright instead of following from a leverage, and the
265
+ * collateral is the only thing the account is left holding.
266
+ *
267
+ * `creditAccount` draws the loan on one the wallet already holds instead of
268
+ * opening another, as an opening takes one.
269
+ *
270
+ * @param props - Credit manager, the collateral the wallet puts up and the
271
+ * payout it asks for
272
+ * @returns Debt, the payout's two branches and the projection the account
273
+ * lands in, or `{ ok: false, error }` when the loan is not viable — a debt
274
+ * outside the facade's limits, collateral that cannot carry it, a payout the
275
+ * router has no path to
276
+ */
277
+ borrowIntent(props: BorrowProps): Promise<BorrowPreviewResult>;
202
278
  }
203
279
  //#endregion
204
- export { type AccountCalculatorOperation, type AddCollateralIntent, type AdjustLeverageIntent, type ClaimRemainder, CreditAccountOperationsService, type CreditAccountSlice, type DelayableIntent, type DelayedRoute, type DelayedStart, type DelayedStartResult, type DepositStrategyIntent, type FinishIntentProps, type FinishIntentResult, type InstantRoute, type IntentPreviewResult, type IntentRoutesResult, type LeverageBand, OpenStrategyPreviewResult, type OpenStrategyProps, type OpenStrategyState, type OperationState, type PathLossRate, type RepayStrategyIntent, type ResumableIntent, type RouteErrors, type StartIntent, type WithdrawAssetIntent, type WithdrawCeilings, type WithdrawStrategyIntent, fetchCreditAccountSlice, isPhantomToken, toCreditAccountSlice };
280
+ export { type AccountCalculatorOperation, type AddCollateralIntent, type AdjustLeverageIntent, BorrowPreviewResult, type BorrowProps, type BorrowState, type ClaimRemainder, CreditAccountOperationsService, type CreditAccountSlice, type DelayableIntent, type DelayedRoute, type DelayedStart, type DelayedStartResult, type DepositStrategyIntent, EmptyAccountPreviewResult, type FinishIntentProps, type FinishIntentResult, type InstantRoute, type IntentPreviewResult, type IntentRoutesResult, type LeverageBand, OpenStrategyPreviewResult, type OpenStrategyProps, type OpenStrategyState, type OperationState, type PathLossRate, type RepayStrategyIntent, type ResumableIntent, type RouteErrors, type StartIntent, type WithdrawAssetIntent, type WithdrawCeilings, type WithdrawStrategyIntent, fetchCreditAccountSlice, isPhantomToken, toCreditAccountSlice };
@@ -0,0 +1,47 @@
1
+ import { OnchainSDK } from "../../OnchainSDK.js";
2
+ import "../../index.js";
3
+ import { Address } from "viem";
4
+ //#region src/onchain/accounts/intents/maxBorrow.d.ts
5
+ interface MaxBorrowProps {
6
+ sdk: OnchainSDK;
7
+ /** Credit manager the loan would be taken in. */
8
+ creditManager: Address;
9
+ /** Token the wallet puts up, in the manager's collateral list. */
10
+ collateralToken: Address;
11
+ /** Amount of {@link collateralToken}, in its own units. */
12
+ collateralAmount: bigint;
13
+ /** Token the loan is paid out in; the answer is in its units. */
14
+ borrowToken: Address;
15
+ /** Health factor the loan has to leave the account at, in basis points. */
16
+ targetHF: bigint;
17
+ /** Extra quota headroom in PERCENTAGE_FORMAT, as the borrow itself takes. */
18
+ quotaReserve: number | undefined;
19
+ }
20
+ /**
21
+ * Largest loan this collateral supports at `targetHF` — the ceiling a borrow
22
+ * form should offer, in the payout token's units.
23
+ *
24
+ * The inverse of a borrow rather than a search for one: the loan leaves the
25
+ * account entirely, so the collateral is the whole of what backs the debt, and
26
+ * the health factor is one division away from the amount. Solving it the other
27
+ * way round costs a division too, and no iteration.
28
+ *
29
+ * Collateral is valued the way the transaction will be judged — at safe
30
+ * prices, under its liquidation threshold, capped by the quota the borrow
31
+ * buys for it, all of which is {@link collateralValuation}'s business. The ceiling
32
+ * is then held to what the market will actually lend: the pool's free
33
+ * liquidity, the manager's own allowance and the facade's `maxDebt`, whichever
34
+ * binds first.
35
+ *
36
+ * Nothing is fetched or simulated — the account does not exist yet and every
37
+ * input is loaded market state, so a form can call this on each keystroke.
38
+ *
39
+ * @param props - {@link MaxBorrowProps}
40
+ * @returns Amount in the payout token's units; `0n` when this market will fund
41
+ * no loan of this shape — including a debt that would land under `minDebt`, a
42
+ * collateral that backs nothing at safe prices, and a manager the SDK does not
43
+ * hold yet
44
+ **/
45
+ declare function maxBorrow(props: MaxBorrowProps): bigint;
46
+ //#endregion
47
+ export { MaxBorrowProps, maxBorrow };