@gearbox-protocol/sdk 16.3.0-next.2 → 16.3.0-next.4

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 (90) hide show
  1. package/dist/cjs/model/errors/index.js +0 -1
  2. package/dist/cjs/model/errors/operation-errors.js +1 -1
  3. package/dist/cjs/model/errors/prepare-errors.js +0 -8
  4. package/dist/cjs/model/index.js +2 -3
  5. package/dist/cjs/model/rwa.js +4 -4
  6. package/dist/cjs/model/rwa.schema.js +4 -4
  7. package/dist/cjs/offchain/opportunities/OffchainOpportunities.js +1 -1
  8. package/dist/cjs/onchain/accounts/CreditAccountsServiceV310.js +1 -3
  9. package/dist/cjs/onchain/accounts/intents/guards.js +4 -4
  10. package/dist/cjs/onchain/accounts/liquidations/LiquidationsService.js +1 -1
  11. package/dist/cjs/onchain/market/credit/CreditSuite.js +26 -12
  12. package/dist/cjs/onchain/market/rwa/midas/MidasDegenNFT.js +45 -5
  13. package/dist/cjs/onchain/market/rwa/securitize/SecuritizeDegenNFT.js +56 -12
  14. package/dist/cjs/onchain/market/rwa/securitize/SecuritizeRWAFactory.js +0 -37
  15. package/dist/cjs/onchain/opportunities/MultichainOpportunitiesService.js +8 -2
  16. package/dist/cjs/onchain/opportunities/OpportunitiesService.js +16 -4
  17. package/dist/cjs/onchain/preview/parse/parseRWAFactoryOperationCalldata.js +2 -2
  18. package/dist/cjs/onchain/validation/bundles/checkCreditOperation.js +3 -2
  19. package/dist/cjs/onchain/validation/bundles/checkDraw.js +3 -3
  20. package/dist/cjs/onchain/validation/bundles/checkRWAOpenRequirements.js +9 -9
  21. package/dist/cjs/onchain/validation/bundles/checkRWAOpening.js +6 -5
  22. package/dist/cjs/onchain/validation/checkSimulation.js +11 -14
  23. package/dist/cjs/onchain/validation/checks/checkDebtLimits.js +3 -2
  24. package/dist/cjs/sdk/execute/ExecuteApi.js +2 -2
  25. package/dist/cjs/sdk/index.js +0 -1
  26. package/dist/cjs/sdk/opportunities/OpportunitiesNamespace.js +9 -3
  27. package/dist/cjs/sdk/prepare/PrepareApi.js +27 -8
  28. package/dist/cjs/sdk/prepare/index.js +0 -1
  29. package/dist/esm/model/errors/index.js +2 -2
  30. package/dist/esm/model/errors/operation-errors.js +1 -1
  31. package/dist/esm/model/errors/prepare-errors.js +1 -8
  32. package/dist/esm/model/index.js +4 -4
  33. package/dist/esm/model/rwa.js +4 -4
  34. package/dist/esm/model/rwa.schema.js +5 -5
  35. package/dist/esm/offchain/opportunities/OffchainOpportunities.js +1 -1
  36. package/dist/esm/onchain/accounts/CreditAccountsServiceV310.js +1 -3
  37. package/dist/esm/onchain/accounts/intents/guards.js +4 -4
  38. package/dist/esm/onchain/accounts/liquidations/LiquidationsService.js +1 -1
  39. package/dist/esm/onchain/market/credit/CreditSuite.js +26 -12
  40. package/dist/esm/onchain/market/rwa/midas/MidasDegenNFT.js +45 -5
  41. package/dist/esm/onchain/market/rwa/securitize/SecuritizeDegenNFT.js +55 -10
  42. package/dist/esm/onchain/market/rwa/securitize/SecuritizeRWAFactory.js +0 -37
  43. package/dist/esm/onchain/opportunities/MultichainOpportunitiesService.js +8 -2
  44. package/dist/esm/onchain/opportunities/OpportunitiesService.js +16 -4
  45. package/dist/esm/onchain/preview/parse/parseRWAFactoryOperationCalldata.js +2 -2
  46. package/dist/esm/onchain/validation/bundles/checkCreditOperation.js +3 -2
  47. package/dist/esm/onchain/validation/bundles/checkDraw.js +3 -3
  48. package/dist/esm/onchain/validation/bundles/checkRWAOpenRequirements.js +9 -9
  49. package/dist/esm/onchain/validation/bundles/checkRWAOpening.js +6 -5
  50. package/dist/esm/onchain/validation/checkSimulation.js +11 -14
  51. package/dist/esm/onchain/validation/checks/checkDebtLimits.js +3 -2
  52. package/dist/esm/sdk/execute/ExecuteApi.js +2 -2
  53. package/dist/esm/sdk/index.js +2 -2
  54. package/dist/esm/sdk/opportunities/OpportunitiesNamespace.js +9 -3
  55. package/dist/esm/sdk/prepare/PrepareApi.js +28 -9
  56. package/dist/esm/sdk/prepare/index.js +2 -2
  57. package/dist/types/model/errors/index.d.ts +2 -2
  58. package/dist/types/model/errors/operation-errors.d.ts +10 -4
  59. package/dist/types/model/errors/prepare-errors.d.ts +1 -10
  60. package/dist/types/model/index.d.ts +4 -4
  61. package/dist/types/model/opportunities.d.ts +4 -5
  62. package/dist/types/model/rwa.d.ts +47 -27
  63. package/dist/types/model/rwa.schema.d.ts +3 -3
  64. package/dist/types/offchain/opportunities/OffchainOpportunities.d.ts +1 -2
  65. package/dist/types/offchain/opportunities/types.d.ts +1 -4
  66. package/dist/types/onchain/accounts/types.d.ts +4 -2
  67. package/dist/types/onchain/index.d.ts +3 -3
  68. package/dist/types/onchain/market/credit/CreditSuite.d.ts +8 -3
  69. package/dist/types/onchain/market/credit/types.d.ts +2 -2
  70. package/dist/types/onchain/market/index.d.ts +2 -2
  71. package/dist/types/onchain/market/rwa/index.d.ts +2 -2
  72. package/dist/types/onchain/market/rwa/midas/MidasDegenNFT.d.ts +19 -4
  73. package/dist/types/onchain/market/rwa/securitize/SecuritizeDegenNFT.d.ts +24 -4
  74. package/dist/types/onchain/market/rwa/securitize/SecuritizeRWAFactory.d.ts +2 -14
  75. package/dist/types/onchain/market/rwa/types.d.ts +39 -37
  76. package/dist/types/onchain/opportunities/MultichainOpportunitiesService.d.ts +5 -1
  77. package/dist/types/onchain/opportunities/OpportunitiesService.d.ts +10 -3
  78. package/dist/types/onchain/opportunities/types.d.ts +6 -1
  79. package/dist/types/onchain/validation/bundles/checkRWAOpenRequirements.d.ts +2 -2
  80. package/dist/types/onchain/validation/bundles/checkRWAOpening.d.ts +3 -3
  81. package/dist/types/onchain/validation/checkSimulation.d.ts +9 -20
  82. package/dist/types/onchain/validation/checks/checkDebtLimits.d.ts +4 -0
  83. package/dist/types/onchain/validation/index.d.ts +2 -2
  84. package/dist/types/sdk/index.d.ts +4 -3
  85. package/dist/types/sdk/opportunities/OpportunitiesNamespace.d.ts +5 -1
  86. package/dist/types/sdk/opportunities/types.d.ts +9 -3
  87. package/dist/types/sdk/prepare/PrepareApi.d.ts +6 -5
  88. package/dist/types/sdk/prepare/index.d.ts +4 -3
  89. package/dist/types/sdk/prepare/types.d.ts +47 -21
  90. package/package.json +1 -1
@@ -6,24 +6,24 @@ const require_onchain_validation_helpers_token = require("../helpers/token.js");
6
6
  require("../helpers/index.js");
7
7
  //#region src/onchain/validation/bundles/checkRWAOpenRequirements.ts
8
8
  /**
9
- * The RWA factory is satisfied that `wallet` may open on `token` with the
9
+ * The degen NFT is satisfied that `wallet` may open on `token` with the
10
10
  * registration args already on the transaction.
11
11
  */
12
12
  async function checkRWAOpenRequirements(input) {
13
13
  const { sdk, wallet, creditManager, token, providedArgs } = input;
14
14
  try {
15
- const requirements = await sdk.accounts.getOpenAccountRequirements(wallet, creditManager, { tokenOutAddress: token });
16
- if (!requirements) return [];
17
- const { rwaFactory } = sdk.marketRegister.findByCreditManager(creditManager);
18
- if (!rwaFactory) throw new Error(`no RWA factory for credit manager ${creditManager}`);
19
- const missing = rwaFactory.getMissingRequirements(requirements, providedArgs);
20
- if (!missing && requirements.securitizeTokensToRegister.length === 0) return [];
15
+ const nft = await sdk.marketRegister.findCreditManager(creditManager).degenNFT();
16
+ if (!nft) return [];
17
+ const requirements = await nft.getOpenAccountRequirements(wallet, { tokenOutAddress: token });
18
+ const missing = nft.getMissingRequirements(requirements, providedArgs);
19
+ if (!missing && nft.isRegistered(requirements)) return [];
21
20
  return [require_model_errors_operation_errors.rwaOpenRequirementsNotMet({
22
21
  token: require_onchain_validation_helpers_token.toToken(sdk, token),
23
22
  creditManager,
24
- factory: rwaFactory.address,
23
+ protocol: nft.protocol,
24
+ registrationLink: nft.registrationLink,
25
25
  requirements,
26
- ...missing === void 0 ? {} : { missing }
26
+ missing
27
27
  })];
28
28
  } catch (cause) {
29
29
  return [require_model_errors_prepare_errors.unexpectedFailure(cause, "read the RWA opening requirements")];
@@ -3,21 +3,22 @@ const require_onchain_utils_AddressSet = require("../../utils/AddressSet.js");
3
3
  const require_onchain_validation_bundles_checkRWAOpenRequirements = require("./checkRWAOpenRequirements.js");
4
4
  //#region src/onchain/validation/bundles/checkRWAOpening.ts
5
5
  /**
6
- * Per factory-gated token among `collateralAdded ∪ quotas`, whether the
6
+ * Per KYC-gated token among `collateralAdded ∪ quotas`, whether the
7
7
  * borrower still has to register or sign before this opening can land.
8
8
  */
9
9
  async function checkRWAOpening(input) {
10
10
  const { sdk, preview, sender } = input;
11
- const { rwaFactory } = sdk.marketRegister.findByCreditManager(preview.creditManager);
12
- if (!rwaFactory) return [];
13
- const gated = new require_onchain_utils_AddressSet.AddressSet(rwaFactory.getTokens());
11
+ const nft = await sdk.marketRegister.findCreditManager(preview.creditManager).degenNFT();
12
+ if (!nft) return [];
13
+ const gated = new require_onchain_utils_AddressSet.AddressSet(await nft.getTokens());
14
14
  const candidates = new require_onchain_utils_AddressSet.AddressSet([...preview.collateralAdded.map((a) => a.token.address), ...preview.quotas.map((q) => q.token.address)]);
15
+ const providedArgs = preview.operation === "RWAOpenCreditAccount" ? preview.rwaArgs : void 0;
15
16
  return (await Promise.all([...candidates].filter((token) => gated.has(token)).map((token) => require_onchain_validation_bundles_checkRWAOpenRequirements.checkRWAOpenRequirements({
16
17
  sdk,
17
18
  wallet: sender,
18
19
  creditManager: preview.creditManager,
19
20
  token,
20
- providedArgs: preview.rwaArgs
21
+ providedArgs
21
22
  })))).flat();
22
23
  }
23
24
  //#endregion
@@ -2,11 +2,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_onchain_validation_helpers_token = require("./helpers/token.js");
3
3
  require("./helpers/index.js");
4
4
  const require_onchain_validation_checks_checkDebtLimits = require("./checks/checkDebtLimits.js");
5
+ const require_onchain_validation_checks_checkQuotaCount = require("./checks/checkQuotaCount.js");
5
6
  require("./checks/index.js");
6
7
  const require_onchain_validation_bundles_checkAccountQuotas = require("./bundles/checkAccountQuotas.js");
7
8
  const require_onchain_validation_bundles_checkHealthFactors = require("./bundles/checkHealthFactors.js");
8
9
  const require_onchain_validation_bundles_checkMarket = require("./bundles/checkMarket.js");
9
- const require_onchain_validation_bundles_checkPoolOperation = require("./bundles/checkPoolOperation.js");
10
10
  //#region src/onchain/validation/checkSimulation.ts
11
11
  /**
12
12
  * Whether a simulated operation clears the caller's own thresholds.
@@ -28,19 +28,12 @@ const require_onchain_validation_bundles_checkPoolOperation = require("./bundles
28
28
  * touched. The engine performed all three during the walk, so a simulation that
29
29
  * came back `ok` has already passed them.
30
30
  *
31
- * A pool operation has no account to weigh, so what is left is the pool's own
32
- * state — which the engine does not read either.
31
+ * A credit account only, opened or adjusted: a pool operation has no account
32
+ * to weigh, and the three things its own state decides are read by `prepare`
33
+ * before it answers. An opening names its quotas `averageQuota` — the branch
34
+ * the planner already weighed it as.
33
35
  */
34
36
  function checkSimulation(sdk, input, options = {}) {
35
- if ("pool" in input) {
36
- const { pool, state, isDeposit } = input;
37
- return require_onchain_validation_bundles_checkPoolOperation.checkPoolOperation({
38
- sdk,
39
- pool,
40
- isDeposit,
41
- tokenOut: state.tokenOut
42
- });
43
- }
44
37
  const { state } = input;
45
38
  const suite = sdk.marketRegister.findCreditManager(state.creditManager);
46
39
  return [
@@ -50,9 +43,13 @@ function checkSimulation(sdk, input, options = {}) {
50
43
  minDebt: suite.creditFacade.minDebt,
51
44
  maxDebt: suite.creditFacade.maxDebt,
52
45
  underlying: require_onchain_validation_helpers_token.toToken(sdk, suite.market.pool.underlying),
53
- allowZero: true
46
+ allowZero: true,
47
+ maxBorrowAmount: suite.maxBorrowAmount()
54
48
  }),
55
- ...require_onchain_validation_bundles_checkAccountQuotas.checkAccountQuotas(suite, state),
49
+ ..."averageQuota" in state ? require_onchain_validation_checks_checkQuotaCount.checkQuotaCount({
50
+ count: state.averageQuota.filter((q) => q.balance > 0n).length,
51
+ max: suite.creditManager.maxEnabledTokens
52
+ }) : require_onchain_validation_bundles_checkAccountQuotas.checkAccountQuotas(suite, state),
56
53
  ...require_onchain_validation_bundles_checkHealthFactors.checkHealthFactors(state, options)
57
54
  ];
58
55
  }
@@ -6,12 +6,13 @@ require("../helpers/index.js");
6
6
  //#region src/onchain/validation/checks/checkDebtLimits.ts
7
7
  /** A debt the facade would revert on. */
8
8
  function checkDebtLimits(args) {
9
- const { debt, minDebt, maxDebt, underlying, allowZero } = args;
9
+ const { debt, minDebt, maxDebt, underlying, allowZero, maxBorrowAmount } = args;
10
10
  if (!(debt > maxDebt || debt < minDebt && !(allowZero && debt === 0n))) return [];
11
11
  return [require_model_errors_operation_errors.debtOutOfRange({
12
12
  requested: require_onchain_validation_helpers_amount.amountOf(underlying, debt),
13
13
  minDebt: require_onchain_validation_helpers_amount.amountOf(underlying, minDebt),
14
- maxDebt: require_onchain_validation_helpers_amount.amountOf(underlying, maxDebt)
14
+ maxDebt: require_onchain_validation_helpers_amount.amountOf(underlying, maxDebt),
15
+ maxBorrowAmount
15
16
  })];
16
17
  }
17
18
  //#endregion
@@ -74,9 +74,9 @@ async function openTx(sdk, request) {
74
74
  async function openRwaOptions(sdk, request) {
75
75
  if (!request.targetToken) return;
76
76
  const requirements = await sdk.accounts.getOpenAccountRequirements(request.wallet, request.creditManager, { tokenOutAddress: request.targetToken });
77
- if (!requirements) return;
77
+ if (requirements?.protocol !== "securitize") return;
78
78
  return {
79
- type: requirements.type,
79
+ protocol: "securitize",
80
80
  tokensToRegister: requirements.tokensToRegister,
81
81
  signaturesToCache: request.signaturesToCache ?? []
82
82
  };
@@ -47,7 +47,6 @@ exports.SourceUnavailableError = require_sdk_errors_SourceUnavailableError.Sourc
47
47
  exports.assertSameChains = require_sdk_errors_assertSameChains.assertSameChains;
48
48
  exports.creditAccountNotEmpty = require_model_errors_prepare_errors.creditAccountNotEmpty;
49
49
  exports.creditAccountNotFound = require_model_errors_prepare_errors.creditAccountNotFound;
50
- exports.emptyOpenTakesNothing = require_model_errors_prepare_errors.emptyOpenTakesNothing;
51
50
  exports.everyChainFailed = require_sdk_errors_everyChainFailed.everyChainFailed;
52
51
  exports.filterResponse = require_sdk_utils_filterResponse.filterResponse;
53
52
  exports.mergeChainList = require_sdk_utils_mergeChains.mergeChainList;
@@ -71,15 +71,21 @@ var OpportunitiesNamespace = class extends require_sdk_AbstractNamespace.Abstrac
71
71
  /**
72
72
  * {@inheritDoc IOpportunitiesBase.getStrategy}
73
73
  **/
74
- async getStrategy(key, wallet) {
74
+ async getStrategy(key) {
75
75
  return this.merged("get strategy opportunity", {
76
76
  chainIds: [key.chainId],
77
- fromChain: (source) => source.getStrategy(key, wallet),
78
- fromBackend: (source) => source.getStrategy(key, wallet),
77
+ fromChain: (source) => source.getStrategy(key),
78
+ fromBackend: (source) => source.getStrategy(key),
79
79
  merge: this.merge.strategy
80
80
  });
81
81
  }
82
82
  /**
83
+ * {@inheritDoc IOpportunitiesOnchainOnly.isEligibleForStrategy}
84
+ **/
85
+ async isEligibleForStrategy(key, wallet) {
86
+ return this.onchain.isEligibleForStrategy(key, wallet);
87
+ }
88
+ /**
83
89
  * {@inheritDoc IOpportunitiesBase.filter}
84
90
  **/
85
91
  filter(response, filter) {
@@ -5,6 +5,7 @@ const require_model_errors_prepare_errors = require("../../model/errors/prepare-
5
5
  const require_model_result = require("../../model/result.js");
6
6
  require("../../model/index.js");
7
7
  const require_onchain_validation_helpers_token = require("../../onchain/validation/helpers/token.js");
8
+ const require_onchain_validation_bundles_checkPoolOperation = require("../../onchain/validation/bundles/checkPoolOperation.js");
8
9
  const require_onchain_accounts_intents_utils_credit_account_slice = require("../../onchain/accounts/intents/utils/credit-account-slice.js");
9
10
  const require_onchain_accounts_intents_index = require("../../onchain/accounts/intents/index.js");
10
11
  require("../../onchain/index.js");
@@ -85,6 +86,13 @@ var PrepareApi = class extends require_onchain_base_MultichainConstruct.Multicha
85
86
  tokenIn,
86
87
  tokenOut
87
88
  });
89
+ const [refusal] = require_onchain_validation_bundles_checkPoolOperation.checkPoolOperation({
90
+ sdk: chain,
91
+ pool: pool.pool,
92
+ isDeposit: true,
93
+ tokenOut: state.tokenOut
94
+ });
95
+ if (refusal) return require_model_result.sdkErr(refusal);
88
96
  const call = pools.addLiquidity({
89
97
  collateral: {
90
98
  token: state.tokenIn.token.address,
@@ -121,6 +129,13 @@ var PrepareApi = class extends require_onchain_base_MultichainConstruct.Multicha
121
129
  tokenIn,
122
130
  tokenOut
123
131
  });
132
+ const [refusal] = require_onchain_validation_bundles_checkPoolOperation.checkPoolOperation({
133
+ sdk: chain,
134
+ pool: pool.pool,
135
+ isDeposit: false,
136
+ tokenOut: state.tokenOut
137
+ });
138
+ if (refusal) return require_model_result.sdkErr(refusal);
124
139
  const { calls } = pools.removeLiquidity({
125
140
  pool: pool.pool,
126
141
  amount: params.amount,
@@ -155,6 +170,13 @@ var PrepareApi = class extends require_onchain_base_MultichainConstruct.Multicha
155
170
  tokenIn,
156
171
  tokenOut
157
172
  });
173
+ const [refusal] = require_onchain_validation_bundles_checkPoolOperation.checkPoolOperation({
174
+ sdk: chain,
175
+ pool: pool.pool,
176
+ isDeposit: false,
177
+ tokenOut: state.tokenOut
178
+ });
179
+ if (refusal) return require_model_result.sdkErr(refusal);
158
180
  const { calls } = pools.removeLiquidity({
159
181
  pool: pool.pool,
160
182
  amount: params.amount,
@@ -180,14 +202,11 @@ var PrepareApi = class extends require_onchain_base_MultichainConstruct.Multicha
180
202
  try {
181
203
  const sdk = await this.#chain(strategy.chainId);
182
204
  const at = stateBlock(sdk);
183
- if (params.empty) {
184
- if (params.collateral.length > 0 || params.creditAccount || params.leverage !== 0n) return require_model_result.sdkErr(require_model_errors_prepare_errors.emptyOpenTakesNothing());
185
- return opened(await service(sdk).openStrategyIntent({
186
- sdk,
187
- creditManager: strategy.creditManager,
188
- empty: true
189
- }), at);
190
- }
205
+ if (params.empty) return opened(await service(sdk).openStrategyIntent({
206
+ sdk,
207
+ creditManager: strategy.creditManager,
208
+ empty: true
209
+ }), at);
191
210
  const targetToken = params.targetToken ?? sdk.marketRegister.findCreditManager(strategy.creditManager).strategyTargetCollateral;
192
211
  if (!targetToken) return require_model_result.sdkErr(require_model_errors_prepare_errors.noStrategyTargetCollateral(strategy.creditManager));
193
212
  let creditAccount;
@@ -6,6 +6,5 @@ require("./types.js");
6
6
  exports.PrepareApi = require_sdk_prepare_PrepareApi.PrepareApi;
7
7
  exports.creditAccountNotEmpty = require_model_errors_prepare_errors.creditAccountNotEmpty;
8
8
  exports.creditAccountNotFound = require_model_errors_prepare_errors.creditAccountNotFound;
9
- exports.emptyOpenTakesNothing = require_model_errors_prepare_errors.emptyOpenTakesNothing;
10
9
  exports.noStrategyTargetCollateral = require_model_errors_prepare_errors.noStrategyTargetCollateral;
11
10
  exports.unexpectedFailure = require_model_errors_prepare_errors.unexpectedFailure;
@@ -2,6 +2,6 @@ import "./base.js";
2
2
  import { creditAccountFrozen, liquidatorNotEligible, notEmergencyLiquidator } from "./liquidation-errors.js";
3
3
  import { creditManagerPaused, debtOutOfRange, forbiddenToken, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, leverageOutOfRange, marketExpired, poolPaused, poolSunset, quotaCountExceeded, quotaLimitReached, rwaOpenRequirementsNotMet } from "./operation-errors.js";
4
4
  import { unpriceableTokenError } from "./oracle-errors.js";
5
- import { creditAccountNotEmpty, creditAccountNotFound, emptyOpenTakesNothing, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, unexpectedFailure, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress } from "./prepare-errors.js";
5
+ import { creditAccountNotEmpty, creditAccountNotFound, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, unexpectedFailure, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress } from "./prepare-errors.js";
6
6
  import { malformedTransaction } from "./preview-errors.js";
7
- export { creditAccountFrozen, creditAccountNotEmpty, creditAccountNotFound, creditManagerPaused, debtOutOfRange, emptyOpenTakesNothing, forbiddenToken, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, leverageOutOfRange, liquidatorNotEligible, malformedTransaction, marketExpired, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, notEmergencyLiquidator, poolPaused, poolSunset, quotaCountExceeded, quotaLimitReached, rwaOpenRequirementsNotMet, unexpectedFailure, unpriceableTokenError, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress };
7
+ export { creditAccountFrozen, creditAccountNotEmpty, creditAccountNotFound, creditManagerPaused, debtOutOfRange, forbiddenToken, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, leverageOutOfRange, liquidatorNotEligible, malformedTransaction, marketExpired, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, notEmergencyLiquidator, poolPaused, poolSunset, quotaCountExceeded, quotaLimitReached, rwaOpenRequirementsNotMet, unexpectedFailure, unpriceableTokenError, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress };
@@ -113,7 +113,7 @@ function insufficientAllowance(args) {
113
113
  function rwaOpenRequirementsNotMet(args) {
114
114
  return {
115
115
  code: "rwaOpenRequirementsNotMet",
116
- message: `The RWA factory still wants something from the borrower before ${args.token.symbol} can be opened on.`,
116
+ message: `${args.protocol} still wants something from the borrower before ${args.token.symbol} can be opened on.`,
117
117
  ...args
118
118
  };
119
119
  }
@@ -72,13 +72,6 @@ function creditAccountNotEmpty(creditAccount) {
72
72
  creditAccount
73
73
  };
74
74
  }
75
- /** {@inheritDoc EmptyOpenTakesNothingError} */
76
- function emptyOpenTakesNothing() {
77
- return {
78
- code: "emptyOpenTakesNothing",
79
- message: "An empty opening takes no collateral, no account to reuse and no leverage."
80
- };
81
- }
82
75
  /**
83
76
  * {@inheritDoc UnexpectedFailureError}
84
77
  *
@@ -94,4 +87,4 @@ function unexpectedFailure(thrown, action = "prepare this operation") {
94
87
  };
95
88
  }
96
89
  //#endregion
97
- export { creditAccountNotEmpty, creditAccountNotFound, emptyOpenTakesNothing, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, unexpectedFailure, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress };
90
+ export { creditAccountNotEmpty, creditAccountNotFound, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, unexpectedFailure, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress };
@@ -7,8 +7,8 @@ import { FILTER_ALL, isFilterSet } from "./filters.js";
7
7
  import { booleanParamSchema, encodeFlag, filterAllSchema, filterable } from "./filters.schema.js";
8
8
  import { curatorNameSchema, curatorSchema } from "./curators.schema.js";
9
9
  import { delayedReceivedAssetSchema, instantReceivedAssetSchema, liquidatableAccountFilterSchema, liquidatableAccountSchema, liquidationApprovalSchema, liquidationDetailsSchema, liquidationPositionSchema, receivedAssetSchema } from "./liquidations.schema.js";
10
- import { KYC_PROTOCOLS, KYC_REGISTRATION_LINKS, RWA_FACTORY_SECURITIZE, RWA_FACTORY_TYPES, SECURITIZE_REGISTER_VAULT_TYPES } from "./rwa.js";
11
- import { kycProtocolSchema, kycRequirementSchema } from "./rwa.schema.js";
10
+ import { KYC_REGISTRATION_LINKS, RWA_FACTORY_SECURITIZE, RWA_FACTORY_TYPES, RWA_PROTOCOLS, SECURITIZE_REGISTER_VAULT_TYPES } from "./rwa.js";
11
+ import { kycRequirementSchema, rwaProtocolSchema } from "./rwa.schema.js";
12
12
  import { apyBreakdownSchema, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterQueryParamsSchema, opportunityFilterQuerySchema, opportunityFilterSchema, opportunityKeySchema, opportunityKindSchema, opportunitySchema, opportunityTotalsSchema, pointRewardsSchema, pointsProgramSchema, poolOpportunityDetailSchema, poolOpportunityKeySchema, poolOpportunitySchema, priceFeedDataSchema, priceFeedSummarySchema, quotaAssetSchema, rateCurvePointSchema, rateCurveSchema, rewardsSchema, strategyOpportunityDetailSchema, strategyOpportunityKeySchema, strategyOpportunitySchema, tokenRewardsSchema } from "./opportunities.schema.js";
13
13
  import { borrowRateBreakdownSchema, pnlBreakdownSchema, pointsProgramPnLSchema, pointsRewardsPnLSchema, poolPositionKeySchema, poolPositionSchema, positionCollateralSchema, positionFilterQueryParamsSchema, positionFilterQuerySchema, positionFilterSchema, positionKeySchema, positionKindSchema, positionSchema, positionTransactionKindSchema, positionTransactionSchema, positionsTotalsSchema, rewardsPnLSchema, strategyPositionKeySchema, strategyPositionSchema, tokenQuotaRateSchema, tokenRewardsPnLSchema } from "./positions.schema.js";
14
14
  import { ANALYTICS_POSITIONS_DEFAULT_LIMIT, ANALYTICS_POSITIONS_MAX_LIMIT, analyticsChartQueryOptionsSchema, analyticsChartQueryParamsSchema, analyticsChartQuerySchema, analyticsPositionListOptionsSchema, analyticsPositionListQueryParamsSchema, analyticsPositionListQuerySchema, analyticsPositionPageSchema, analyticsPositionSchema, analyticsPositionSortFieldSchema, analyticsSortDirectionSchema } from "./analytics.schema.js";
@@ -17,7 +17,7 @@ import "./delayed-intents.js";
17
17
  import { creditAccountFrozen, liquidatorNotEligible, notEmergencyLiquidator } from "./errors/liquidation-errors.js";
18
18
  import { creditManagerPaused, debtOutOfRange, forbiddenToken, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, leverageOutOfRange, marketExpired, poolPaused, poolSunset, quotaCountExceeded, quotaLimitReached, rwaOpenRequirementsNotMet } from "./errors/operation-errors.js";
19
19
  import { unpriceableTokenError } from "./errors/oracle-errors.js";
20
- import { creditAccountNotEmpty, creditAccountNotFound, emptyOpenTakesNothing, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, unexpectedFailure, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress } from "./errors/prepare-errors.js";
20
+ import { creditAccountNotEmpty, creditAccountNotFound, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, unexpectedFailure, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress } from "./errors/prepare-errors.js";
21
21
  import { malformedTransaction } from "./errors/preview-errors.js";
22
22
  import "./errors/index.js";
23
23
  import { matchesLiquidatableAccountFilter } from "./liquidations.js";
@@ -32,4 +32,4 @@ import { chainFailedSchema, chainMetadataSchema, chainSucceededSchema, dataSourc
32
32
  import { safeValue, sdkErr, sdkOk } from "./result.js";
33
33
  import "./withdrawals.js";
34
34
  import { positionClaimableWithdrawalSchema, positionPendingWithdrawalSchema, positionWithdrawalsSchema, withdrawalOutputAmountSchema } from "./withdrawals.schema.js";
35
- export { ANALYTICS_POSITIONS_DEFAULT_LIMIT, ANALYTICS_POSITIONS_MAX_LIMIT, CHART_METRIC_UNITS, CHART_RANGES, CHART_UNAVAILABLE_CODES, FILTER_ALL, KYC_PROTOCOLS, KYC_REGISTRATION_LINKS, POOL_OPPORTUNITY_CHART_METRICS, POOL_POSITION_CHART_METRICS, PROTOCOL_CHART_METRICS, RWA_FACTORY_SECURITIZE, RWA_FACTORY_TYPES, SECURITIZE_REGISTER_VAULT_TYPES, STRATEGY_OPPORTUNITY_CHART_METRICS, STRATEGY_POSITION_CHART_METRICS, STRATEGY_POSITION_COLLATERAL_ERROR, amountSchema, analyticsChartQueryOptionsSchema, analyticsChartQueryParamsSchema, analyticsChartQuerySchema, analyticsPositionListOptionsSchema, analyticsPositionListQueryParamsSchema, analyticsPositionListQuerySchema, analyticsPositionPageSchema, analyticsPositionSchema, analyticsPositionSortFieldSchema, analyticsSortDirectionSchema, apyBreakdownSchema, asEstimated, assetTypeSchema, backendPreferred, booleanParamSchema, borrowRateBreakdownSchema, bpsSchema, chainFailedSchema, chainIdSchema, chainMetadataSchema, chainSucceededSchema, chartBundleSchemaFor, chartDenominationSchema, chartMetricSchema, chartQueryCodec, chartQueryParamsSchema, chartQuerySchema, chartRangeSchema, chartSeriesSchema, chartValueSchema, chartWindowSchema, compareTagOf, creditAccountFrozen, creditAccountNotEmpty, creditAccountNotFound, creditManagerPaused, curatorNameSchema, curatorSchema, dataSourceSchema, debtOutOfRange, delayedReceivedAssetSchema, emptyOpenTakesNothing, encodeFlag, filterAllSchema, filterable, forbiddenToken, instantReceivedAssetSchema, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, isFilterSet, kycProtocolSchema, kycRequirementSchema, leverageOutOfRange, leverageSchema, liquidatableAccountFilterSchema, liquidatableAccountSchema, liquidationApprovalSchema, liquidationDetailsSchema, liquidationPositionId, liquidationPositionSchema, liquidatorNotEligible, malformedTransaction, marketExpired, matchesLiquidatableAccountFilter, matchesOpportunityFilter, matchesPositionFilter, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, notEmergencyLiquidator, noticeKindSchema, noticeSchema, offchainOnly, onchainOnly, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterQueryParamsSchema, opportunityFilterQuerySchema, opportunityFilterSchema, opportunityId, opportunityKeySchema, opportunityKindSchema, opportunitySchema, opportunityTotalsSchema, pnlBreakdownSchema, pointRewardsSchema, pointsProgramPnLSchema, pointsProgramSchema, pointsRewardsPnLSchema, poolOpportunityChartMetricSchema, poolOpportunityDetailSchema, poolOpportunityId, poolOpportunityKeySchema, poolOpportunitySchema, poolPaused, poolPositionChartMetricSchema, poolPositionId, poolPositionKeySchema, poolPositionSchema, poolSunset, positionClaimableWithdrawalSchema, positionCollateralSchema, positionFilterQueryParamsSchema, positionFilterQuerySchema, positionFilterSchema, positionId, positionKeySchema, positionKindSchema, positionPendingWithdrawalSchema, positionSchema, positionTransactionKindSchema, positionTransactionSchema, positionWithdrawalsSchema, positionsTotalsSchema, priceFeedDataSchema, priceFeedSummarySchema, protocolChartMetricSchema, quotaAssetSchema, quotaCountExceeded, quotaLimitReached, rateCurvePointSchema, rateCurveSchema, receivedAssetSchema, responseMetadataSchema, responseSchema, rewardsPnLSchema, rewardsSchema, rwaOpenRequirementsNotMet, safeValue, sdkErr, sdkOk, strategyOpportunityChartMetricSchema, strategyOpportunityDetailSchema, strategyOpportunityId, strategyOpportunityKeySchema, strategyOpportunitySchema, strategyPositionChartMetricSchema, strategyPositionId, strategyPositionKeySchema, strategyPositionSchema, timestampSchema, tokenAmountSchema, tokenQuotaRateSchema, tokenRewardsPnLSchema, tokenRewardsSchema, tokenSchema, tolerance, txCallSchema, underlyingTokenSchema, unexpectedFailure, unpriceableTokenError, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress, withdrawalOutputAmountSchema };
35
+ export { ANALYTICS_POSITIONS_DEFAULT_LIMIT, ANALYTICS_POSITIONS_MAX_LIMIT, CHART_METRIC_UNITS, CHART_RANGES, CHART_UNAVAILABLE_CODES, FILTER_ALL, KYC_REGISTRATION_LINKS, POOL_OPPORTUNITY_CHART_METRICS, POOL_POSITION_CHART_METRICS, PROTOCOL_CHART_METRICS, RWA_FACTORY_SECURITIZE, RWA_FACTORY_TYPES, RWA_PROTOCOLS, SECURITIZE_REGISTER_VAULT_TYPES, STRATEGY_OPPORTUNITY_CHART_METRICS, STRATEGY_POSITION_CHART_METRICS, STRATEGY_POSITION_COLLATERAL_ERROR, amountSchema, analyticsChartQueryOptionsSchema, analyticsChartQueryParamsSchema, analyticsChartQuerySchema, analyticsPositionListOptionsSchema, analyticsPositionListQueryParamsSchema, analyticsPositionListQuerySchema, analyticsPositionPageSchema, analyticsPositionSchema, analyticsPositionSortFieldSchema, analyticsSortDirectionSchema, apyBreakdownSchema, asEstimated, assetTypeSchema, backendPreferred, booleanParamSchema, borrowRateBreakdownSchema, bpsSchema, chainFailedSchema, chainIdSchema, chainMetadataSchema, chainSucceededSchema, chartBundleSchemaFor, chartDenominationSchema, chartMetricSchema, chartQueryCodec, chartQueryParamsSchema, chartQuerySchema, chartRangeSchema, chartSeriesSchema, chartValueSchema, chartWindowSchema, compareTagOf, creditAccountFrozen, creditAccountNotEmpty, creditAccountNotFound, creditManagerPaused, curatorNameSchema, curatorSchema, dataSourceSchema, debtOutOfRange, delayedReceivedAssetSchema, encodeFlag, filterAllSchema, filterable, forbiddenToken, instantReceivedAssetSchema, insufficientAllowance, insufficientBalance, insufficientCollateral, insufficientPoolLiquidity, isFilterSet, kycRequirementSchema, leverageOutOfRange, leverageSchema, liquidatableAccountFilterSchema, liquidatableAccountSchema, liquidationApprovalSchema, liquidationDetailsSchema, liquidationPositionId, liquidationPositionSchema, liquidatorNotEligible, malformedTransaction, marketExpired, matchesLiquidatableAccountFilter, matchesOpportunityFilter, matchesPositionFilter, multipleDelayedWithdrawals, noDelayedRoute, noRecordedIntent, noStrategyTargetCollateral, notEmergencyLiquidator, noticeKindSchema, noticeSchema, offchainOnly, onchainOnly, opportunityBaseSchema, opportunityDetailSchema, opportunityFilterQueryParamsSchema, opportunityFilterQuerySchema, opportunityFilterSchema, opportunityId, opportunityKeySchema, opportunityKindSchema, opportunitySchema, opportunityTotalsSchema, pnlBreakdownSchema, pointRewardsSchema, pointsProgramPnLSchema, pointsProgramSchema, pointsRewardsPnLSchema, poolOpportunityChartMetricSchema, poolOpportunityDetailSchema, poolOpportunityId, poolOpportunityKeySchema, poolOpportunitySchema, poolPaused, poolPositionChartMetricSchema, poolPositionId, poolPositionKeySchema, poolPositionSchema, poolSunset, positionClaimableWithdrawalSchema, positionCollateralSchema, positionFilterQueryParamsSchema, positionFilterQuerySchema, positionFilterSchema, positionId, positionKeySchema, positionKindSchema, positionPendingWithdrawalSchema, positionSchema, positionTransactionKindSchema, positionTransactionSchema, positionWithdrawalsSchema, positionsTotalsSchema, priceFeedDataSchema, priceFeedSummarySchema, protocolChartMetricSchema, quotaAssetSchema, quotaCountExceeded, quotaLimitReached, rateCurvePointSchema, rateCurveSchema, receivedAssetSchema, responseMetadataSchema, responseSchema, rewardsPnLSchema, rewardsSchema, rwaOpenRequirementsNotMet, rwaProtocolSchema, safeValue, sdkErr, sdkOk, strategyOpportunityChartMetricSchema, strategyOpportunityDetailSchema, strategyOpportunityId, strategyOpportunityKeySchema, strategyOpportunitySchema, strategyPositionChartMetricSchema, strategyPositionId, strategyPositionKeySchema, strategyPositionSchema, timestampSchema, tokenAmountSchema, tokenQuotaRateSchema, tokenRewardsPnLSchema, tokenRewardsSchema, tokenSchema, tolerance, txCallSchema, underlyingTokenSchema, unexpectedFailure, unpriceableTokenError, unsupportedCollateralToken, unsupportedTokenPair, withdrawalInProgress, withdrawalOutputAmountSchema };
@@ -34,15 +34,15 @@ const SECURITIZE_REGISTER_VAULT_TYPES = { RegisterVault: [
34
34
  }
35
35
  ] };
36
36
  /**
37
- * KYC providers a strategy may be gated by
37
+ * RWA protocols that require dedicated flows
38
38
  **/
39
- const KYC_PROTOCOLS = ["securitize", "midas"];
39
+ const RWA_PROTOCOLS = ["securitize", "midas"];
40
40
  /**
41
- * Hardcoded registration URLs for each {@link KycProtocol}.
41
+ * Hardcoded registration URLs for each {@link RWAProtocol}.
42
42
  **/
43
43
  const KYC_REGISTRATION_LINKS = {
44
44
  securitize: "https://securitize.io/",
45
45
  midas: "https://form.typeform.com/to/DqZaw6kr"
46
46
  };
47
47
  //#endregion
48
- export { KYC_PROTOCOLS, KYC_REGISTRATION_LINKS, RWA_FACTORY_SECURITIZE, RWA_FACTORY_TYPES, SECURITIZE_REGISTER_VAULT_TYPES };
48
+ export { KYC_REGISTRATION_LINKS, RWA_FACTORY_SECURITIZE, RWA_FACTORY_TYPES, RWA_PROTOCOLS, SECURITIZE_REGISTER_VAULT_TYPES };
@@ -1,18 +1,18 @@
1
1
  import { tokenSchema } from "./primitives.schema.js";
2
- import { KYC_PROTOCOLS } from "./rwa.js";
2
+ import { RWA_PROTOCOLS } from "./rwa.js";
3
3
  import { z } from "zod/v4";
4
4
  //#region src/model/rwa.schema.ts
5
5
  /**
6
- * {@link ./rwa.js#KycProtocol}
6
+ * {@link ./rwa.js#RWAProtocol}
7
7
  **/
8
- const kycProtocolSchema = z.enum(KYC_PROTOCOLS);
8
+ const rwaProtocolSchema = z.enum(RWA_PROTOCOLS);
9
9
  /**
10
10
  * {@link ./rwa.js#KycRequirement}
11
11
  **/
12
12
  const kycRequirementSchema = z.object({
13
- protocol: kycProtocolSchema,
13
+ protocol: rwaProtocolSchema,
14
14
  token: tokenSchema.optional(),
15
15
  registrationLink: z.string()
16
16
  });
17
17
  //#endregion
18
- export { kycProtocolSchema, kycRequirementSchema };
18
+ export { kycRequirementSchema, rwaProtocolSchema };
@@ -35,7 +35,7 @@ var OffchainOpportunities = class extends AbstractOffchainNamespace {
35
35
  /**
36
36
  * {@inheritDoc IOffchainOpportunities.getStrategy}
37
37
  **/
38
- async getStrategy(key, _wallet) {
38
+ async getStrategy(key) {
39
39
  return this.get({
40
40
  path: this.#strategyPath(key),
41
41
  schema: strategyOpportunityDetailSchema
@@ -188,9 +188,7 @@ var CreditAccountsServiceV310 = class extends SDKConstruct {
188
188
  * {@inheritDoc ICreditAccountsService.getOpenAccountRequirements}
189
189
  */
190
190
  async getOpenAccountRequirements(borrower, creditManager, props) {
191
- const { rwaFactory } = this.sdk.marketRegister.findCreditManager(creditManager);
192
- if (!rwaFactory) return;
193
- return rwaFactory.getOpenAccountRequirements(borrower, props);
191
+ return (await this.sdk.marketRegister.findCreditManager(creditManager).degenNFT())?.getOpenAccountRequirements(borrower, props);
194
192
  }
195
193
  /**
196
194
  * {@inheritDoc ICreditAccountsService.openCA}
@@ -43,13 +43,13 @@ function assertMarketOperable(suite) {
43
43
  }
44
44
  /** The pool has to be able to lend what the plan means to draw. */
45
45
  function assertCanBorrow(sdk, suite, amount) {
46
- const { value, limit } = suite.maxBorrowAmount();
46
+ const maxBorrowAmount = suite.maxBorrowAmount();
47
47
  raise(checkBorrowLimit({
48
48
  requested: amount,
49
- available: value,
50
- limit,
49
+ available: maxBorrowAmount.amount.value,
50
+ limit: maxBorrowAmount.limit,
51
51
  underlying: toToken(sdk, suite.market.pool.underlying)
52
- }), `borrow: ${amount} exceeds what the pool can lend now (${value})`);
52
+ }), `borrow: ${amount} exceeds what the pool can lend now (${maxBorrowAmount.amount.value})`);
53
53
  }
54
54
  /**
55
55
  * What the account is allowed to end up holding more of than it started with.
@@ -9,9 +9,9 @@ import "../../utils/index.js";
9
9
  import { SDKConstruct } from "../../base/SDKConstruct.js";
10
10
  import "../../base/index.js";
11
11
  import { usdToNumber } from "../../market/math.js";
12
+ import { RWA_LIQUIDATOR_MIDAS } from "../../market/rwa/midas/constants.js";
12
13
  import { matchesLiquidatableAccountFilter } from "../../../model/liquidations.js";
13
14
  import "../../../model/index.js";
14
- import { RWA_LIQUIDATOR_MIDAS } from "../../market/rwa/midas/constants.js";
15
15
  import { RWA_LIQUIDATOR_SECURITIZE } from "../../market/rwa/securitize/constants.js";
16
16
  import { dominantCollateral } from "../../market/credit/collateralUtils.js";
17
17
  import { MidasLiquidatorContract } from "../../market/rwa/midas/MidasLiquidatorContract.js";
@@ -7,8 +7,6 @@ import "../../utils/index.js";
7
7
  import { SDKConstruct } from "../../base/SDKConstruct.js";
8
8
  import "../../base/index.js";
9
9
  import { calcBorrowApy, calcQuotaRate, minSeizedAmount, optimalHFForPartialLiquidation, optimalRepaidAmount } from "../math.js";
10
- import { KYC_REGISTRATION_LINKS } from "../../../model/rwa.js";
11
- import "../../../model/index.js";
12
10
  import { createDegenNFT } from "../rwa/createDegenNFT.js";
13
11
  import { strategyName } from "../strategyName.js";
14
12
  import { dominantCollateral, isStrategyCollateral, pickStrategyTargetCollateral } from "./collateralUtils.js";
@@ -125,25 +123,37 @@ var CreditSuite = class extends SDKConstruct {
125
123
  degenNFT() {
126
124
  const address = this.creditFacade.degenNFT;
127
125
  if (isAddressEqual(address, "0x0000000000000000000000000000000000000000")) return Promise.resolve(void 0);
126
+ const factoryNft = this.rwaFactory?.degenNFT;
127
+ if (factoryNft && isAddressEqual(factoryNft.address, address)) return Promise.resolve(factoryNft);
128
128
  if (!this.#degenNFT) this.#degenNFT = createDegenNFT(this.sdk, address);
129
129
  return this.#degenNFT;
130
130
  }
131
131
  /**
132
- * What `wallet` still has to do before the facade lets it open an account;
133
- * `null` when nothing (no degen NFT, not a KYC gate, or already eligible).
132
+ * The KYC gate of this suite's strategy; `null` when there is none.
133
+ * Wallet-independent.
134
134
  */
135
- async kycRequirement(wallet, targetCollateral) {
135
+ async kycRequirement(targetCollateral) {
136
136
  const nft = await this.degenNFT();
137
137
  if (!nft) return null;
138
- const { eligible, token } = await nft.checkKyc(wallet, targetCollateral);
139
- if (eligible) return null;
138
+ const tokens = await nft.getTokens();
139
+ const token = tokens.find((t) => isAddressEqual(t, targetCollateral)) ?? tokens[0];
140
140
  return {
141
141
  protocol: nft.protocol,
142
- token: this.tokensMeta.getToken(token),
143
- registrationLink: KYC_REGISTRATION_LINKS[nft.protocol]
142
+ token: token ? this.tokensMeta.getToken(token) : void 0,
143
+ registrationLink: nft.registrationLink
144
144
  };
145
145
  }
146
146
  /**
147
+ * Whether `wallet` may open this suite's strategy today; `true` when there
148
+ * is no KYC gate.
149
+ */
150
+ async isEligibleForStrategy(wallet, targetCollateral) {
151
+ const nft = await this.degenNFT();
152
+ if (!nft) return true;
153
+ const requirements = await nft.getOpenAccountRequirements(wallet, { tokenOutAddress: targetCollateral });
154
+ return nft.isRegistered(requirements);
155
+ }
156
+ /**
147
157
  * Builds a transaction that executes a multicall on one of this suite's
148
158
  * credit accounts.
149
159
  *
@@ -278,11 +288,11 @@ var CreditSuite = class extends SDKConstruct {
278
288
  const { pool } = this.market.pool;
279
289
  const { maxDebtPerBlockMultiplier, maxDebt } = this.creditFacade;
280
290
  if (maxDebtPerBlockMultiplier === 0) return {
281
- value: 0n,
291
+ amount: this.market.toUnderlyingAmount(0n),
282
292
  limit: "debtPerBlockLimit"
283
293
  };
284
294
  const available = pool.creditManagerDebtParams.get(this.creditManager.address)?.available;
285
- return [
295
+ const { value, limit } = [
286
296
  {
287
297
  value: pool.availableLiquidity,
288
298
  limit: "poolAvailableLiquidity"
@@ -296,6 +306,10 @@ var CreditSuite = class extends SDKConstruct {
296
306
  limit: "maxDebt"
297
307
  }
298
308
  ].reduce((a, b) => b.value < a.value ? b : a);
309
+ return {
310
+ amount: this.market.toUnderlyingAmount(value),
311
+ limit
312
+ };
299
313
  }
300
314
  /**
301
315
  * The single target collateral of this suite's strategy, or `undefined` when
@@ -354,7 +368,7 @@ var CreditSuite = class extends SDKConstruct {
354
368
  * or `undefined` when credit suite does not offer a strategy opportunity.
355
369
  */
356
370
  strategyOpportunity() {
357
- const maxBorrowAmount = this.maxBorrowAmount().value;
371
+ const maxBorrowAmount = this.maxBorrowAmount().amount.value;
358
372
  if (maxBorrowAmount <= MIN_STRATEGY_BORROW_AMOUNT) return;
359
373
  const collateral = this.strategyTargetCollateral;
360
374
  if (!collateral) return;
@@ -5,14 +5,23 @@ import "../../adapters/abi/index.js";
5
5
  import { iMidasDegenNFTAbi } from "../../../../abi/rwa/iMidasDegenNFT.js";
6
6
  import "./constants.js";
7
7
  import { iMidasAccessControlAbi } from "../../../../abi/rwa/iMidasAccessControl.js";
8
+ import { KYC_REGISTRATION_LINKS } from "../../../../model/rwa.js";
9
+ import "../../../../model/index.js";
8
10
  import { decodeAbiParameters } from "viem";
9
11
  //#region src/onchain/market/rwa/midas/MidasDegenNFT.ts
10
12
  const abi = iMidasDegenNFTAbi;
13
+ /**
14
+ * Midas is an RWA protocol without a factory: accounts open through the plain
15
+ * facade. Only a Permissioned-mode gateway deploys a degen NFT, so a Midas
16
+ * strategy that does not require KYC has no NFT at all.
17
+ */
11
18
  var MidasDegenNFT = class extends BaseContract {
12
19
  protocol = "midas";
20
+ registrationLink = KYC_REGISTRATION_LINKS.midas;
13
21
  gateway;
14
22
  accessControl;
15
23
  greenlistedRole;
24
+ #mToken;
16
25
  constructor(sdk, baseParams) {
17
26
  super(sdk, {
18
27
  ...baseParams,
@@ -30,9 +39,26 @@ var MidasDegenNFT = class extends BaseContract {
30
39
  this.accessControl = accessControl;
31
40
  this.greenlistedRole = greenlistedRole;
32
41
  }
33
- /** Same predicate `MidasDegenNFT.burn` reverts on; the mToken rides along in the batch. */
34
- async checkKyc(wallet, _targetCollateral) {
35
- const [eligible, token] = await this.client.multicall({
42
+ async getTokens() {
43
+ return [await this.#mTokenAddress()];
44
+ }
45
+ /**
46
+ * Same predicate `MidasDegenNFT.burn` reverts on; the mToken rides along in
47
+ * the batch until it is cached.
48
+ */
49
+ async getOpenAccountRequirements(wallet, _props) {
50
+ const token = this.#mToken;
51
+ if (token !== void 0) return {
52
+ protocol: "midas",
53
+ token,
54
+ greenlisted: await this.client.readContract({
55
+ abi: iMidasAccessControlAbi,
56
+ address: this.accessControl,
57
+ functionName: "hasRole",
58
+ args: [this.greenlistedRole, wallet]
59
+ })
60
+ };
61
+ const [greenlisted, mToken] = await this.client.multicall({
36
62
  allowFailure: false,
37
63
  contracts: [{
38
64
  abi: iMidasAccessControlAbi,
@@ -45,11 +71,25 @@ var MidasDegenNFT = class extends BaseContract {
45
71
  functionName: "mToken"
46
72
  }]
47
73
  });
74
+ this.#mToken = mToken;
48
75
  return {
49
- eligible,
50
- token
76
+ protocol: "midas",
77
+ token: mToken,
78
+ greenlisted
51
79
  };
52
80
  }
81
+ isRegistered(requirements) {
82
+ return requirements.greenlisted;
83
+ }
84
+ getMissingRequirements() {}
85
+ async #mTokenAddress() {
86
+ if (this.#mToken === void 0) this.#mToken = await this.client.readContract({
87
+ abi: iMidasGatewayV311Abi,
88
+ address: this.gateway,
89
+ functionName: "mToken"
90
+ });
91
+ return this.#mToken;
92
+ }
53
93
  };
54
94
  //#endregion
55
95
  export { MidasDegenNFT };