@gearbox-protocol/sdk 16.3.2 → 16.4.0-next.10
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.
- package/dist/cjs/dev/index.js +3 -2
- package/dist/cjs/dev/kycUtils.js +18 -35
- package/dist/cjs/dev/midasUtils.js +40 -11
- package/dist/cjs/dev/securitizeUtils.js +14 -10
- package/dist/cjs/dev/withdrawalUtils.js +3 -6
- package/dist/cjs/model/errors/index.js +2 -0
- package/dist/cjs/model/errors/operation-errors.js +18 -0
- package/dist/cjs/model/index.js +2 -0
- package/dist/cjs/onchain/accounts/CreditAccountsServiceV310.js +0 -1
- package/dist/cjs/onchain/accounts/intents/borrow.js +139 -0
- package/dist/cjs/onchain/accounts/intents/collateral-valuation.js +41 -0
- package/dist/cjs/onchain/accounts/intents/guards.js +15 -3
- package/dist/cjs/onchain/accounts/intents/index.js +107 -20
- package/dist/cjs/onchain/accounts/intents/leverage-band.js +2 -12
- package/dist/cjs/onchain/accounts/intents/maxBorrow.js +89 -0
- package/dist/cjs/onchain/accounts/intents/maxWithdrawCollateral.js +15 -41
- package/dist/cjs/onchain/accounts/intents/open-strategy.js +6 -45
- package/dist/cjs/onchain/accounts/intents/realize.js +54 -2
- package/dist/cjs/onchain/accounts/intents/tail.js +1 -1
- package/dist/cjs/onchain/accounts/intents/testing/sdk-mock.js +1 -0
- package/dist/cjs/onchain/accounts/intents/utils/common.js +19 -0
- package/dist/cjs/onchain/accounts/intents/utils/credit-account-slice.js +21 -0
- package/dist/cjs/onchain/accounts/intents/utils/index.js +2 -0
- package/dist/cjs/onchain/accounts/intents/utils/price-impact.js +3 -3
- package/dist/cjs/onchain/accounts/intents/withdraw-limits.js +97 -0
- package/dist/cjs/onchain/core/createAddressProvider.js +2 -5
- package/dist/cjs/onchain/index.js +6 -0
- package/dist/cjs/onchain/market/adapters/abi/conctructorAbi.js +1 -1
- package/dist/cjs/onchain/market/adapters/contracts/MidasGatewayAdapterContract.js +11 -3
- package/dist/cjs/onchain/positions/calcHealthFactor.js +3 -3
- package/dist/cjs/onchain/preview/index.js +2 -0
- package/dist/cjs/onchain/preview/preview/index.js +2 -0
- package/dist/cjs/onchain/preview/preview/midasGreenlistsAccount.js +17 -0
- package/dist/cjs/onchain/preview/preview/previewOpenStrategyPosition.js +13 -16
- package/dist/cjs/onchain/preview/preview/previewOperation.js +19 -11
- package/dist/cjs/onchain/preview/preview/replayMulticall.js +4 -3
- package/dist/cjs/onchain/validation/bundles/checkCollateralFunding.js +3 -3
- package/dist/cjs/onchain/validation/bundles/checkCreditOperation.js +4 -3
- package/dist/cjs/onchain/validation/bundles/checkMidasAccountGreenlist.js +44 -0
- package/dist/cjs/onchain/validation/bundles/checkRWAOpening.js +16 -7
- package/dist/cjs/onchain/validation/bundles/index.js +2 -0
- package/dist/cjs/onchain/validation/checkOperation.js +0 -1
- package/dist/cjs/onchain/validation/checks/checkReservePriceLimited.js +30 -0
- package/dist/cjs/onchain/validation/checks/index.js +2 -0
- package/dist/cjs/onchain/validation/index.js +4 -0
- package/dist/cjs/sdk/execute/ExecuteApi.js +65 -5
- package/dist/cjs/sdk/prepare/PrepareApi.js +89 -14
- package/dist/esm/dev/index.js +3 -3
- package/dist/esm/dev/kycUtils.js +17 -33
- package/dist/esm/dev/midasUtils.js +39 -12
- package/dist/esm/dev/securitizeUtils.js +15 -11
- package/dist/esm/dev/withdrawalUtils.js +3 -6
- package/dist/esm/model/errors/index.js +2 -2
- package/dist/esm/model/errors/operation-errors.js +17 -1
- package/dist/esm/model/index.js +2 -2
- package/dist/esm/onchain/accounts/CreditAccountsServiceV310.js +0 -1
- package/dist/esm/onchain/accounts/intents/borrow.js +137 -0
- package/dist/esm/onchain/accounts/intents/collateral-valuation.js +40 -0
- package/dist/esm/onchain/accounts/intents/guards.js +15 -3
- package/dist/esm/onchain/accounts/intents/index.js +107 -20
- package/dist/esm/onchain/accounts/intents/leverage-band.js +2 -12
- package/dist/esm/onchain/accounts/intents/maxBorrow.js +87 -0
- package/dist/esm/onchain/accounts/intents/maxWithdrawCollateral.js +15 -41
- package/dist/esm/onchain/accounts/intents/open-strategy.js +6 -45
- package/dist/esm/onchain/accounts/intents/realize.js +54 -2
- package/dist/esm/onchain/accounts/intents/tail.js +1 -1
- package/dist/esm/onchain/accounts/intents/testing/sdk-mock.js +1 -0
- package/dist/esm/onchain/accounts/intents/utils/common.js +19 -1
- package/dist/esm/onchain/accounts/intents/utils/credit-account-slice.js +21 -1
- package/dist/esm/onchain/accounts/intents/utils/index.js +3 -3
- package/dist/esm/onchain/accounts/intents/utils/price-impact.js +3 -3
- package/dist/esm/onchain/accounts/intents/withdraw-limits.js +95 -0
- package/dist/esm/onchain/core/createAddressProvider.js +2 -5
- package/dist/esm/onchain/index.js +4 -1
- package/dist/esm/onchain/market/adapters/abi/conctructorAbi.js +1 -1
- package/dist/esm/onchain/market/adapters/contracts/MidasGatewayAdapterContract.js +11 -3
- package/dist/esm/onchain/positions/calcHealthFactor.js +3 -3
- package/dist/esm/onchain/preview/index.js +2 -1
- package/dist/esm/onchain/preview/preview/index.js +2 -1
- package/dist/esm/onchain/preview/preview/midasGreenlistsAccount.js +16 -0
- package/dist/esm/onchain/preview/preview/previewOpenStrategyPosition.js +14 -17
- package/dist/esm/onchain/preview/preview/previewOperation.js +19 -11
- package/dist/esm/onchain/preview/preview/replayMulticall.js +4 -3
- package/dist/esm/onchain/validation/bundles/checkCollateralFunding.js +3 -3
- package/dist/esm/onchain/validation/bundles/checkCreditOperation.js +4 -3
- package/dist/esm/onchain/validation/bundles/checkMidasAccountGreenlist.js +43 -0
- package/dist/esm/onchain/validation/bundles/checkRWAOpening.js +16 -7
- package/dist/esm/onchain/validation/bundles/index.js +2 -1
- package/dist/esm/onchain/validation/checkOperation.js +0 -1
- package/dist/esm/onchain/validation/checks/checkReservePriceLimited.js +29 -0
- package/dist/esm/onchain/validation/checks/index.js +2 -1
- package/dist/esm/onchain/validation/index.js +3 -1
- package/dist/esm/sdk/execute/ExecuteApi.js +65 -5
- package/dist/esm/sdk/prepare/PrepareApi.js +89 -14
- package/dist/types/dev/index.d.ts +3 -3
- package/dist/types/dev/kycUtils.d.ts +1 -5
- package/dist/types/dev/midasUtils.d.ts +11 -1
- package/dist/types/model/errors/index.d.ts +2 -2
- package/dist/types/model/errors/operation-errors.d.ts +54 -1
- package/dist/types/model/index.d.ts +3 -3
- package/dist/types/model/previews.d.ts +25 -19
- package/dist/types/onchain/accounts/index.d.ts +4 -3
- package/dist/types/onchain/accounts/intents/borrow.d.ts +141 -0
- package/dist/types/onchain/accounts/intents/collateral-valuation.d.ts +42 -0
- package/dist/types/onchain/accounts/intents/guards.d.ts +18 -2
- package/dist/types/onchain/accounts/intents/index.d.ts +102 -14
- package/dist/types/onchain/accounts/intents/maxBorrow.d.ts +54 -0
- package/dist/types/onchain/accounts/intents/maxWithdrawCollateral.d.ts +3 -8
- package/dist/types/onchain/accounts/intents/open-strategy.d.ts +3 -17
- package/dist/types/onchain/accounts/intents/testing/sdk-mock.d.ts +2 -0
- package/dist/types/onchain/accounts/intents/tests/open-strategy.fixtures.d.ts +2 -2
- package/dist/types/onchain/accounts/intents/types.d.ts +41 -5
- package/dist/types/onchain/accounts/intents/utils/common.d.ts +15 -1
- package/dist/types/onchain/accounts/intents/utils/credit-account-slice.d.ts +14 -1
- package/dist/types/onchain/accounts/intents/utils/index.d.ts +3 -3
- package/dist/types/onchain/accounts/intents/withdraw-limits.d.ts +80 -0
- package/dist/types/onchain/index.d.ts +8 -4
- package/dist/types/onchain/market/adapters/contracts/MidasGatewayAdapterContract.d.ts +8 -2
- package/dist/types/onchain/preview/index.d.ts +2 -1
- package/dist/types/onchain/preview/preview/index.d.ts +2 -1
- package/dist/types/onchain/preview/preview/midasGreenlistsAccount.d.ts +13 -0
- package/dist/types/onchain/preview/preview/previewOpenStrategyPosition.d.ts +5 -3
- package/dist/types/onchain/preview/preview/replayMulticall.d.ts +8 -7
- package/dist/types/onchain/validation/bundles/checkCreditOperation.d.ts +2 -2
- package/dist/types/onchain/validation/bundles/checkMidasAccountGreenlist.d.ts +22 -0
- package/dist/types/onchain/validation/bundles/checkRWAOpening.d.ts +6 -4
- package/dist/types/onchain/validation/bundles/index.d.ts +3 -2
- package/dist/types/onchain/validation/checks/checkDebtLimits.d.ts +2 -2
- package/dist/types/onchain/validation/checks/checkReservePriceLimited.d.ts +31 -0
- package/dist/types/onchain/validation/checks/index.d.ts +2 -1
- package/dist/types/onchain/validation/index.d.ts +4 -2
- package/dist/types/onchain/validation/raise.d.ts +2 -2
- package/dist/types/sdk/execute/index.d.ts +2 -2
- package/dist/types/sdk/execute/types.d.ts +48 -6
- package/dist/types/sdk/index.d.ts +5 -4
- package/dist/types/sdk/prepare/PrepareApi.d.ts +16 -4
- package/dist/types/sdk/prepare/index.d.ts +4 -3
- package/dist/types/sdk/prepare/types.d.ts +199 -65
- package/package.json +1 -1
|
@@ -35,7 +35,7 @@ function calcHealthFactor(props) {
|
|
|
35
35
|
const scale = 10n ** BigInt(decimalsByToken.get(token) ?? 18);
|
|
36
36
|
return amount * price / scale;
|
|
37
37
|
};
|
|
38
|
-
const
|
|
38
|
+
const assetValue = snapshot.assets.reduce((acc, { token, balance }) => {
|
|
39
39
|
if (balance <= 10n) return acc;
|
|
40
40
|
const lt = BigInt(lts.get(token) ?? 0);
|
|
41
41
|
const tokenLtWeighted = (convertToUSD(token, balance, true) ?? 0n) * lt;
|
|
@@ -44,8 +44,8 @@ function calcHealthFactor(props) {
|
|
|
44
44
|
const quotaWeighted = (convertToUSD(underlying, quotaBalance) ?? 0n) * PERCENTAGE_FACTOR;
|
|
45
45
|
return acc + (quota ? BigIntMath.min(quotaWeighted, tokenLtWeighted) : tokenLtWeighted);
|
|
46
46
|
}, 0n);
|
|
47
|
-
const
|
|
48
|
-
const hf =
|
|
47
|
+
const borrowedValue = convertToUSD(underlying, snapshot.totalDebt) ?? 0n;
|
|
48
|
+
const hf = borrowedValue > 0n ? assetValue / borrowedValue : 0n;
|
|
49
49
|
return Number(hf);
|
|
50
50
|
}
|
|
51
51
|
//#endregion
|
|
@@ -11,10 +11,11 @@ import { classifyCloseOrRepay, isCloseOrRepay } from "./preview/detectCloseOrRep
|
|
|
11
11
|
import { detectDelayedClaim, resolveDelayedClaimIntent } from "./preview/detectDelayedClaim.js";
|
|
12
12
|
import { detectDelayedOperation } from "./preview/detectDelayedOperation.js";
|
|
13
13
|
import { estimateClaimableAt } from "./preview/estimateClaimableAt.js";
|
|
14
|
+
import { midasGreenlistsAccount } from "./preview/midasGreenlistsAccount.js";
|
|
14
15
|
import { previewAdjustStrategyPosition } from "./preview/previewAdjustStrategyPosition.js";
|
|
15
16
|
import { previewExitOrRepayStrategyPosition } from "./preview/previewExitOrRepayStrategyPosition.js";
|
|
16
17
|
import { makeReplayState, replayInnerOperations } from "./preview/replayInnerOperations.js";
|
|
17
18
|
import { replayMulticall } from "./preview/replayMulticall.js";
|
|
18
19
|
import { previewOperation } from "./preview/previewOperation.js";
|
|
19
20
|
import "./preview/index.js";
|
|
20
|
-
export { CreditAccountState, buildDelayedStrategyPositionOperationPreview, classifyCloseOrRepay, classifyInnerOperations, detectDelayedClaim, detectDelayedOperation, estimateClaimableAt, isCloseOrRepay, isPoolOperation, isRWAOperation, makeReplayState, parseFacadeOperationCalldata, parseOperationCalldata, parsePoolOperationCalldata, parseRWAFactoryOperationCalldata, previewAdjustStrategyPosition, previewExitOrRepayStrategyPosition, previewOperation, replayInnerOperations, replayMulticall, resolveDelayedClaimIntent };
|
|
21
|
+
export { CreditAccountState, buildDelayedStrategyPositionOperationPreview, classifyCloseOrRepay, classifyInnerOperations, detectDelayedClaim, detectDelayedOperation, estimateClaimableAt, isCloseOrRepay, isPoolOperation, isRWAOperation, makeReplayState, midasGreenlistsAccount, parseFacadeOperationCalldata, parseOperationCalldata, parsePoolOperationCalldata, parseRWAFactoryOperationCalldata, previewAdjustStrategyPosition, previewExitOrRepayStrategyPosition, previewOperation, replayInnerOperations, replayMulticall, resolveDelayedClaimIntent };
|
|
@@ -4,9 +4,10 @@ import { classifyCloseOrRepay, isCloseOrRepay } from "./detectCloseOrRepay.js";
|
|
|
4
4
|
import { detectDelayedClaim, resolveDelayedClaimIntent } from "./detectDelayedClaim.js";
|
|
5
5
|
import { detectDelayedOperation } from "./detectDelayedOperation.js";
|
|
6
6
|
import { estimateClaimableAt } from "./estimateClaimableAt.js";
|
|
7
|
+
import { midasGreenlistsAccount } from "./midasGreenlistsAccount.js";
|
|
7
8
|
import { previewAdjustStrategyPosition } from "./previewAdjustStrategyPosition.js";
|
|
8
9
|
import { previewExitOrRepayStrategyPosition } from "./previewExitOrRepayStrategyPosition.js";
|
|
9
10
|
import { makeReplayState, replayInnerOperations } from "./replayInnerOperations.js";
|
|
10
11
|
import { replayMulticall } from "./replayMulticall.js";
|
|
11
12
|
import { previewOperation } from "./previewOperation.js";
|
|
12
|
-
export { CreditAccountState, buildDelayedStrategyPositionOperationPreview, classifyCloseOrRepay, detectDelayedClaim, detectDelayedOperation, estimateClaimableAt, isCloseOrRepay, makeReplayState, previewAdjustStrategyPosition, previewExitOrRepayStrategyPosition, previewOperation, replayInnerOperations, replayMulticall, resolveDelayedClaimIntent };
|
|
13
|
+
export { CreditAccountState, buildDelayedStrategyPositionOperationPreview, classifyCloseOrRepay, detectDelayedClaim, detectDelayedOperation, estimateClaimableAt, isCloseOrRepay, makeReplayState, midasGreenlistsAccount, previewAdjustStrategyPosition, previewExitOrRepayStrategyPosition, previewOperation, replayInnerOperations, replayMulticall, resolveDelayedClaimIntent };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { MidasGatewayAdapterContract } from "../../market/adapters/contracts/MidasGatewayAdapterContract.js";
|
|
2
|
+
//#region src/onchain/preview/preview/midasGreenlistsAccount.ts
|
|
3
|
+
/**
|
|
4
|
+
* Whether the multicall grants the Midas greenlisted role to the credit
|
|
5
|
+
* account via `receiveGreenlist()`.
|
|
6
|
+
*/
|
|
7
|
+
function midasGreenlistsAccount(sdk, multicall) {
|
|
8
|
+
for (const op of multicall) {
|
|
9
|
+
if (op.operation !== "Execute") continue;
|
|
10
|
+
const adapter = sdk.getContract(op.adapter);
|
|
11
|
+
if (adapter instanceof MidasGatewayAdapterContract && adapter.isReceiveGreenlist(op.calldata)) return true;
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { midasGreenlistsAccount };
|
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
import { AP_WETH_TOKEN } from "../../constants/address-provider.js";
|
|
2
2
|
import { asEstimated } from "../../../model/previews.js";
|
|
3
|
-
import {
|
|
3
|
+
import { sdkOk } from "../../../model/result.js";
|
|
4
4
|
import "../../../model/index.js";
|
|
5
|
-
import {
|
|
5
|
+
import { midasGreenlistsAccount } from "./midasGreenlistsAccount.js";
|
|
6
6
|
import { unwrapNativeCollateral } from "./unwrapNativeCollateral.js";
|
|
7
|
-
import { makeReplayState, replayInnerOperations } from "./replayInnerOperations.js";
|
|
8
7
|
//#region src/onchain/preview/preview/previewOpenStrategyPosition.ts
|
|
9
|
-
function previewOpenStrategyPosition(sdk, input, operation) {
|
|
8
|
+
function previewOpenStrategyPosition(sdk, input, operation, replay) {
|
|
10
9
|
const { value = 0n } = input;
|
|
11
10
|
const market = sdk.marketRegister.findByCreditManager(operation.creditManager);
|
|
12
11
|
const oracle = market.priceOracle;
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
if (replayError) return sdkErr(replayError);
|
|
16
|
-
const account = state.account;
|
|
12
|
+
const { before, after } = replay;
|
|
13
|
+
const account = after.account;
|
|
17
14
|
let warning;
|
|
18
|
-
const
|
|
15
|
+
const price = (token, balance) => {
|
|
19
16
|
const priced = oracle.safeConvert(token, market.underlying, balance);
|
|
20
17
|
warning ??= priced.error;
|
|
21
18
|
return priced.value;
|
|
22
|
-
}
|
|
23
|
-
const
|
|
19
|
+
};
|
|
20
|
+
const netValue = before.balances.sum(price) + after.collateralAdded.sum(price) - after.collateralWithdrawn.sum(price);
|
|
21
|
+
const unwrapped = unwrapNativeCollateral(after.collateralAdded.toAssets(), value, sdk.addressProvider.getAddress(AP_WETH_TOKEN, 0));
|
|
24
22
|
if (!unwrapped.ok) return unwrapped;
|
|
25
23
|
const collateral = unwrapped.data;
|
|
26
24
|
const snap = account.toSnapshot(netValue + account.totalDebt);
|
|
@@ -29,16 +27,15 @@ function previewOpenStrategyPosition(sdk, input, operation) {
|
|
|
29
27
|
...asEstimated(sdk.positions.projection(snap, { availableLiquidityChange: -account.totalDebt })),
|
|
30
28
|
targetCollateral: targetAsset ? oracle.toTokenAmount(targetAsset.token, targetAsset.balance) : void 0,
|
|
31
29
|
collateralAdded: collateral.map((a) => oracle.toTokenAmount(a.token, a.balance)),
|
|
30
|
+
collateralWithdrawn: after.collateralWithdrawn.toAssets().map((a) => oracle.toTokenAmount(a.token, a.balance)),
|
|
32
31
|
warning
|
|
33
32
|
};
|
|
34
|
-
if (operation.operation === "RWAOpenCreditAccount") return sdkOk({
|
|
35
|
-
...projection,
|
|
36
|
-
operation: "RWAOpenCreditAccount",
|
|
37
|
-
rwaArgs: operation.args
|
|
38
|
-
});
|
|
39
33
|
return sdkOk({
|
|
40
34
|
...projection,
|
|
41
|
-
operation: "OpenCreditAccount"
|
|
35
|
+
operation: "OpenCreditAccount",
|
|
36
|
+
...operation.operation === "MultiCall" || operation.operation === "BotMulticall" || operation.operation === "RWAMulticall" ? { creditAccount: operation.creditAccount } : {},
|
|
37
|
+
..."args" in operation ? { rwaArgs: operation.args } : {},
|
|
38
|
+
midasGreenlistsAccount: midasGreenlistsAccount(sdk, operation.multicall)
|
|
42
39
|
});
|
|
43
40
|
}
|
|
44
41
|
/**
|
|
@@ -33,9 +33,13 @@ async function previewOperation(sdk, input, options, creditAccount) {
|
|
|
33
33
|
if (!parsed.ok) return parsed;
|
|
34
34
|
const operation = parsed.data;
|
|
35
35
|
if (isPoolOperation(operation)) return previewPoolPositionOperation(sdk, operation, options);
|
|
36
|
-
if (operation.operation === "OpenCreditAccount" || operation.operation === "RWAOpenCreditAccount")
|
|
36
|
+
if (operation.operation === "OpenCreditAccount" || operation.operation === "RWAOpenCreditAccount") {
|
|
37
|
+
const replayed = replayMulticall(sdk, operation);
|
|
38
|
+
if (!replayed.ok) return replayed;
|
|
39
|
+
return previewOpenStrategyPosition(sdk, input, operation, replayed.data);
|
|
40
|
+
}
|
|
37
41
|
if (operation.operation === "CloseCreditAccount") {
|
|
38
|
-
const resolved = await resolveCreditAccount(sdk, operation, options, creditAccount);
|
|
42
|
+
const resolved = await resolveCreditAccount(sdk, operation.creditAccount, options, creditAccount);
|
|
39
43
|
if (!resolved.ok) return resolved;
|
|
40
44
|
const replayed = replayMulticall(sdk, operation, resolved.data);
|
|
41
45
|
if (!replayed.ok) return replayed;
|
|
@@ -47,7 +51,7 @@ async function previewOperation(sdk, input, options, creditAccount) {
|
|
|
47
51
|
return preview;
|
|
48
52
|
}
|
|
49
53
|
if (operation.operation === "MultiCall" || operation.operation === "BotMulticall" || operation.operation === "RWAMulticall") {
|
|
50
|
-
const resolved = await resolveCreditAccount(sdk, operation, options, creditAccount);
|
|
54
|
+
const resolved = await resolveCreditAccount(sdk, operation.creditAccount, options, creditAccount);
|
|
51
55
|
if (!resolved.ok) return resolved;
|
|
52
56
|
const replayed = replayMulticall(sdk, operation, resolved.data);
|
|
53
57
|
if (!replayed.ok) return replayed;
|
|
@@ -64,20 +68,24 @@ async function previewOperation(sdk, input, options, creditAccount) {
|
|
|
64
68
|
* injected state when present, otherwise fetches it from the credit account
|
|
65
69
|
* compressor.
|
|
66
70
|
*/
|
|
67
|
-
async function resolveCreditAccount(sdk,
|
|
68
|
-
let resolved =
|
|
69
|
-
if (!resolved) resolved = await sdk.accounts.getCreditAccountData(
|
|
70
|
-
if (!resolved) return sdkErr(creditAccountNotFound(
|
|
71
|
+
async function resolveCreditAccount(sdk, address, options, data) {
|
|
72
|
+
let resolved = data;
|
|
73
|
+
if (!resolved) resolved = await sdk.accounts.getCreditAccountData(address, options?.blockNumber);
|
|
74
|
+
if (!resolved) return sdkErr(creditAccountNotFound(address));
|
|
71
75
|
return sdkOk(resolved);
|
|
72
76
|
}
|
|
73
77
|
/**
|
|
74
78
|
* Previews a plain/bot/RWA multicall: classifies the instant preview
|
|
75
|
-
* (zero-debt closure/repay
|
|
76
|
-
* delayed withdrawal, wraps the instant
|
|
77
|
-
* `DelayedCreditAccountOperation` together with the
|
|
78
|
-
* the state after the withdrawal is claimed.
|
|
79
|
+
* (reopening a zero-debt account, zero-debt closure/repay, or adjustment)
|
|
80
|
+
* and, when the multicall requests a delayed withdrawal, wraps the instant
|
|
81
|
+
* preview into a `DelayedCreditAccountOperation` together with the
|
|
82
|
+
* best-effort preview of the state after the withdrawal is claimed.
|
|
83
|
+
*
|
|
84
|
+
* A reopening is reported as `OpenCreditAccount` and never as a delayed
|
|
85
|
+
* withdrawal: an opening requests no redemption.
|
|
79
86
|
*/
|
|
80
87
|
async function previewMulticallOperation(sdk, input, operation, replay, blockNumber) {
|
|
88
|
+
if (replay.before.totalDebt === 0n && replay.before.quotas.toAssets(0n).length === 0 && replay.after.account.totalDebt > 0n) return previewOpenStrategyPosition(sdk, input, operation, replay);
|
|
81
89
|
let instantPreview;
|
|
82
90
|
if (isCloseOrRepay(operation.multicall)) {
|
|
83
91
|
const instant = previewExitOrRepayStrategyPosition(sdk, input, operation, false, replay);
|
|
@@ -4,11 +4,12 @@ import { CreditAccountState } from "./CreditAccountState.js";
|
|
|
4
4
|
import { makeReplayState, replayInnerOperations } from "./replayInnerOperations.js";
|
|
5
5
|
//#region src/onchain/preview/preview/replayMulticall.ts
|
|
6
6
|
/**
|
|
7
|
-
* Replays the operation's multicall
|
|
8
|
-
*
|
|
7
|
+
* Replays the operation's multicall via {@link replayInnerOperations}.
|
|
8
|
+
* When `creditAccount` is omitted, the seed is
|
|
9
|
+
* {@link CreditAccountState.beforeOpen} (a fresh opening).
|
|
9
10
|
*/
|
|
10
11
|
function replayMulticall(sdk, operation, creditAccount) {
|
|
11
|
-
const before = CreditAccountState.fromCreditAccountData(creditAccount);
|
|
12
|
+
const before = creditAccount ? CreditAccountState.fromCreditAccountData(creditAccount) : CreditAccountState.beforeOpen(operation.creditManager, sdk.marketRegister.findByCreditManager(operation.creditManager).underlying);
|
|
12
13
|
const after = makeReplayState(before.clone());
|
|
13
14
|
const error = replayInnerOperations(sdk, operation.multicall, after);
|
|
14
15
|
if (error) return sdkErr(error);
|
|
@@ -22,13 +22,13 @@ async function checkCollateralFunding(input) {
|
|
|
22
22
|
if (held.size === 0) return [];
|
|
23
23
|
let spender;
|
|
24
24
|
try {
|
|
25
|
-
if (preview.
|
|
25
|
+
if (preview.creditAccount) spender = await sdk.accounts.getApprovalAddress({
|
|
26
26
|
creditManager: preview.creditManager,
|
|
27
|
-
|
|
27
|
+
creditAccount: preview.creditAccount
|
|
28
28
|
});
|
|
29
29
|
else spender = await sdk.accounts.getApprovalAddress({
|
|
30
30
|
creditManager: preview.creditManager,
|
|
31
|
-
|
|
31
|
+
borrower: sender
|
|
32
32
|
});
|
|
33
33
|
} catch (cause) {
|
|
34
34
|
return [unexpectedFailure(cause, "resolve the approval address")];
|
|
@@ -25,7 +25,8 @@ async function checkCreditOperation(args) {
|
|
|
25
25
|
const suite = sdk.marketRegister.findCreditManager(preview.creditManager);
|
|
26
26
|
const market = suite.market;
|
|
27
27
|
const underlying = toToken(sdk, market.pool.underlying);
|
|
28
|
-
const isOpening = preview.operation === "OpenCreditAccount"
|
|
28
|
+
const isOpening = preview.operation === "OpenCreditAccount";
|
|
29
|
+
const isEmptyOpening = preview.operation === "OpenCreditAccount" && preview.totalDebt.value === 0n && preview.collateralAdded.length === 0 && preview.quotas.length === 0;
|
|
29
30
|
const protocol = [
|
|
30
31
|
...checkMarket(suite),
|
|
31
32
|
...checkDebtLimits({
|
|
@@ -33,7 +34,7 @@ async function checkCreditOperation(args) {
|
|
|
33
34
|
minDebt: suite.creditFacade.minDebt,
|
|
34
35
|
maxDebt: suite.creditFacade.maxDebt,
|
|
35
36
|
underlying,
|
|
36
|
-
allowZero: !isOpening,
|
|
37
|
+
allowZero: !isOpening || isEmptyOpening,
|
|
37
38
|
maxBorrowAmount: suite.maxBorrowAmount()
|
|
38
39
|
}),
|
|
39
40
|
...checkIncreaseDebt(suite, preview, underlying),
|
|
@@ -51,7 +52,7 @@ async function checkCreditOperation(args) {
|
|
|
51
52
|
preview,
|
|
52
53
|
sender,
|
|
53
54
|
blockNumber
|
|
54
|
-
}),
|
|
55
|
+
}), isOpening ? checkRWAOpening({
|
|
55
56
|
sdk,
|
|
56
57
|
preview,
|
|
57
58
|
sender
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { accountNotMidasGreenlisted } from "../../../model/errors/operation-errors.js";
|
|
2
|
+
import { unexpectedFailure } from "../../../model/errors/prepare-errors.js";
|
|
3
|
+
import "../../../model/index.js";
|
|
4
|
+
import { toToken } from "../helpers/token.js";
|
|
5
|
+
import "../helpers/index.js";
|
|
6
|
+
//#region src/onchain/validation/bundles/checkMidasAccountGreenlist.ts
|
|
7
|
+
/**
|
|
8
|
+
* Whether the credit account already holds the Midas greenlisted role
|
|
9
|
+
* this permissioned mToken requires of its holder.
|
|
10
|
+
*/
|
|
11
|
+
async function checkMidasAccountGreenlist(input) {
|
|
12
|
+
const { sdk, preview, nft, tokens } = input;
|
|
13
|
+
if (nft.protocol !== "midas") return [];
|
|
14
|
+
if (tokens.length === 0) return [];
|
|
15
|
+
const account = preview.creditAccount;
|
|
16
|
+
if (!account) return tokens.map((token) => accountNotMidasGreenlisted({
|
|
17
|
+
token: toToken(sdk, token),
|
|
18
|
+
creditManager: preview.creditManager
|
|
19
|
+
}));
|
|
20
|
+
return (await Promise.all(tokens.map((token) => checkAccountRole({
|
|
21
|
+
sdk,
|
|
22
|
+
nft,
|
|
23
|
+
account,
|
|
24
|
+
token,
|
|
25
|
+
preview
|
|
26
|
+
})))).flat();
|
|
27
|
+
}
|
|
28
|
+
async function checkAccountRole(input) {
|
|
29
|
+
const { sdk, nft, account, token, preview } = input;
|
|
30
|
+
try {
|
|
31
|
+
const requirements = await nft.getOpenAccountRequirements(account, { tokenOutAddress: token });
|
|
32
|
+
if (nft.isRegistered(requirements)) return [];
|
|
33
|
+
return [accountNotMidasGreenlisted({
|
|
34
|
+
token: toToken(sdk, token),
|
|
35
|
+
creditManager: preview.creditManager,
|
|
36
|
+
creditAccount: account
|
|
37
|
+
})];
|
|
38
|
+
} catch (cause) {
|
|
39
|
+
return [unexpectedFailure(cause, "read the Midas account greenlist")];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { checkMidasAccountGreenlist };
|
|
@@ -1,24 +1,33 @@
|
|
|
1
1
|
import { AddressSet } from "../../utils/AddressSet.js";
|
|
2
|
+
import { checkMidasAccountGreenlist } from "./checkMidasAccountGreenlist.js";
|
|
2
3
|
import { checkRWAOpenRequirements } from "./checkRWAOpenRequirements.js";
|
|
3
4
|
//#region src/onchain/validation/bundles/checkRWAOpening.ts
|
|
4
5
|
/**
|
|
5
6
|
* Per KYC-gated token among `collateralAdded ∪ quotas`, whether the
|
|
6
|
-
* borrower still has to register or sign before this opening can land
|
|
7
|
+
* borrower still has to register or sign before this opening can land,
|
|
8
|
+
* and whether a Midas credit account may hold the mToken.
|
|
7
9
|
*/
|
|
8
10
|
async function checkRWAOpening(input) {
|
|
9
11
|
const { sdk, preview, sender } = input;
|
|
10
12
|
const nft = await sdk.marketRegister.findCreditManager(preview.creditManager).degenNFT();
|
|
11
13
|
if (!nft) return [];
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const nftTokens = new AddressSet(await nft.getTokens());
|
|
15
|
+
let candidates = new AddressSet([...preview.collateralAdded.map((a) => a.token.address), ...preview.quotas.map((q) => q.token.address)]).asArray();
|
|
16
|
+
candidates = candidates.filter((token) => nftTokens.has(token));
|
|
17
|
+
let tokensToCheck = candidates;
|
|
18
|
+
if (tokensToCheck.length === 0 && !preview.creditAccount && nft.protocol === "midas") tokensToCheck = nftTokens.asArray();
|
|
19
|
+
return (await Promise.all([...tokensToCheck.map((token) => checkRWAOpenRequirements({
|
|
16
20
|
sdk,
|
|
17
21
|
wallet: sender,
|
|
18
22
|
creditManager: preview.creditManager,
|
|
19
23
|
token,
|
|
20
|
-
providedArgs
|
|
21
|
-
}))
|
|
24
|
+
providedArgs: preview.rwaArgs
|
|
25
|
+
})), checkMidasAccountGreenlist({
|
|
26
|
+
sdk,
|
|
27
|
+
preview,
|
|
28
|
+
nft,
|
|
29
|
+
tokens: candidates
|
|
30
|
+
})])).flat();
|
|
22
31
|
}
|
|
23
32
|
//#endregion
|
|
24
33
|
export { checkRWAOpening };
|
|
@@ -7,6 +7,7 @@ import { checkIncreaseDebt } from "./checkIncreaseDebt.js";
|
|
|
7
7
|
import { checkIncreaseQuota } from "./checkIncreaseQuota.js";
|
|
8
8
|
import { checkMarket } from "./checkMarket.js";
|
|
9
9
|
import { checkObtained } from "./checkObtained.js";
|
|
10
|
+
import { checkMidasAccountGreenlist } from "./checkMidasAccountGreenlist.js";
|
|
10
11
|
import { checkRWAOpenRequirements } from "./checkRWAOpenRequirements.js";
|
|
11
12
|
import { checkRWAOpening } from "./checkRWAOpening.js";
|
|
12
13
|
import { checkCreditOperation } from "./checkCreditOperation.js";
|
|
@@ -15,4 +16,4 @@ import { checkLiquidationFunding } from "./checkLiquidationFunding.js";
|
|
|
15
16
|
import { checkWallet } from "./checkWallet.js";
|
|
16
17
|
import { checkPoolFunding } from "./checkPoolFunding.js";
|
|
17
18
|
import { checkPoolOperation } from "./checkPoolOperation.js";
|
|
18
|
-
export { checkAccountQuotas, checkCollateralFunding, checkCreditOperation, checkHealthFactors, checkIncreaseDebt, checkIncreaseQuota, checkLiquidationEligibility, checkLiquidationFunding, checkMarket, checkObtained, checkPoolFunding, checkPoolOperation, checkRWAOpenRequirements, checkRWAOpening, checkWallet, checkWalletAllowance, checkWalletBalance };
|
|
19
|
+
export { checkAccountQuotas, checkCollateralFunding, checkCreditOperation, checkHealthFactors, checkIncreaseDebt, checkIncreaseQuota, checkLiquidationEligibility, checkLiquidationFunding, checkMarket, checkMidasAccountGreenlist, checkObtained, checkPoolFunding, checkPoolOperation, checkRWAOpenRequirements, checkRWAOpening, checkWallet, checkWalletAllowance, checkWalletBalance };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { reservePriceLimited } from "../../../model/errors/operation-errors.js";
|
|
2
|
+
import "../../../model/index.js";
|
|
3
|
+
//#region src/onchain/validation/checks/checkReservePriceLimited.ts
|
|
4
|
+
/**
|
|
5
|
+
* Whether a failed collateral check is the reserve price feed's doing.
|
|
6
|
+
*
|
|
7
|
+
* A call that hands funds over is weighed at safe prices — `min` of a token's
|
|
8
|
+
* two feeds, and nothing at all where governance registered no reserve feed —
|
|
9
|
+
* so an account that covers its debt at the main feed can still be refused.
|
|
10
|
+
* The two are worth telling apart: a position that is genuinely too small is
|
|
11
|
+
* fixed by adding collateral or requesting less, while this one is a valuation
|
|
12
|
+
* the account does not control, and requesting less only helps as far as
|
|
13
|
+
* `withdrawable` says it does.
|
|
14
|
+
*
|
|
15
|
+
* Runs after `checkCollateralised` and answers only when that one refused, so
|
|
16
|
+
* the caller keeps its own threshold rather than restating it here.
|
|
17
|
+
*/
|
|
18
|
+
function checkReservePriceLimited(args) {
|
|
19
|
+
const { healthFactor, atMainPrices, healthFactorThreshold, withdrawable } = args;
|
|
20
|
+
if (healthFactor >= healthFactorThreshold || atMainPrices < healthFactorThreshold) return [];
|
|
21
|
+
return [reservePriceLimited({
|
|
22
|
+
healthFactor,
|
|
23
|
+
atMainPrices,
|
|
24
|
+
healthFactorThreshold,
|
|
25
|
+
withdrawable
|
|
26
|
+
})];
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { checkReservePriceLimited };
|
|
@@ -13,4 +13,5 @@ import { checkPoolPaused } from "./checkPoolPaused.js";
|
|
|
13
13
|
import { checkPoolSunset } from "./checkPoolSunset.js";
|
|
14
14
|
import { checkQuotaCount } from "./checkQuotaCount.js";
|
|
15
15
|
import { checkQuotaLimit } from "./checkQuotaLimit.js";
|
|
16
|
-
|
|
16
|
+
import { checkReservePriceLimited } from "./checkReservePriceLimited.js";
|
|
17
|
+
export { checkBorrowLimit, checkCollateralised, checkCreditAccountFrozen, checkCreditManagerPaused, checkDebtLimits, checkEmergencyLiquidator, checkForbiddenToken, checkLeverage, checkLiquidatorEligible, checkMarketExpired, checkPoolLiquidity, checkPoolPaused, checkPoolSunset, checkQuotaCount, checkQuotaLimit, checkReservePriceLimited };
|
|
@@ -17,6 +17,7 @@ import { checkPoolPaused } from "./checks/checkPoolPaused.js";
|
|
|
17
17
|
import { checkPoolSunset } from "./checks/checkPoolSunset.js";
|
|
18
18
|
import { checkQuotaCount } from "./checks/checkQuotaCount.js";
|
|
19
19
|
import { checkQuotaLimit } from "./checks/checkQuotaLimit.js";
|
|
20
|
+
import { checkReservePriceLimited } from "./checks/checkReservePriceLimited.js";
|
|
20
21
|
import "./checks/index.js";
|
|
21
22
|
import { checkAccountQuotas } from "./bundles/checkAccountQuotas.js";
|
|
22
23
|
import { checkWalletAllowance } from "./bundles/checkWalletAllowance.js";
|
|
@@ -27,6 +28,7 @@ import { checkIncreaseDebt } from "./bundles/checkIncreaseDebt.js";
|
|
|
27
28
|
import { checkIncreaseQuota } from "./bundles/checkIncreaseQuota.js";
|
|
28
29
|
import { checkMarket } from "./bundles/checkMarket.js";
|
|
29
30
|
import { checkObtained } from "./bundles/checkObtained.js";
|
|
31
|
+
import { checkMidasAccountGreenlist } from "./bundles/checkMidasAccountGreenlist.js";
|
|
30
32
|
import { checkRWAOpenRequirements } from "./bundles/checkRWAOpenRequirements.js";
|
|
31
33
|
import { checkRWAOpening } from "./bundles/checkRWAOpening.js";
|
|
32
34
|
import { checkCreditOperation } from "./bundles/checkCreditOperation.js";
|
|
@@ -40,4 +42,4 @@ import { checkLiquidation } from "./checkLiquidation.js";
|
|
|
40
42
|
import { checkOperation } from "./checkOperation.js";
|
|
41
43
|
import { checkSimulation } from "./checkSimulation.js";
|
|
42
44
|
import { raise } from "./raise.js";
|
|
43
|
-
export { MIN_HEALTH_FACTOR_FACADE, MIN_HEALTH_FACTOR_FORM, MIN_HF_LIMITED, MIN_SAFE_HEALTH_FACTOR_FORM, amountOf, checkAccountQuotas, checkBorrowLimit, checkCollateralFunding, checkCollateralised, checkCreditAccountFrozen, checkCreditManagerPaused, checkCreditOperation, checkDebtLimits, checkEmergencyLiquidator, checkForbiddenToken, checkHealthFactors, checkIncreaseDebt, checkIncreaseQuota, checkLeverage, checkLiquidation, checkLiquidationEligibility, checkLiquidationFunding, checkLiquidatorEligible, checkMarket, checkMarketExpired, checkObtained, checkOperation, checkPoolFunding, checkPoolLiquidity, checkPoolOperation, checkPoolPaused, checkPoolSunset, checkQuotaCount, checkQuotaLimit, checkRWAOpenRequirements, checkRWAOpening, checkSimulation, checkWallet, checkWalletAllowance, checkWalletBalance, raise, toToken, toTokenAmount };
|
|
45
|
+
export { MIN_HEALTH_FACTOR_FACADE, MIN_HEALTH_FACTOR_FORM, MIN_HF_LIMITED, MIN_SAFE_HEALTH_FACTOR_FORM, amountOf, checkAccountQuotas, checkBorrowLimit, checkCollateralFunding, checkCollateralised, checkCreditAccountFrozen, checkCreditManagerPaused, checkCreditOperation, checkDebtLimits, checkEmergencyLiquidator, checkForbiddenToken, checkHealthFactors, checkIncreaseDebt, checkIncreaseQuota, checkLeverage, checkLiquidation, checkLiquidationEligibility, checkLiquidationFunding, checkLiquidatorEligible, checkMarket, checkMarketExpired, checkMidasAccountGreenlist, checkObtained, checkOperation, checkPoolFunding, checkPoolLiquidity, checkPoolOperation, checkPoolPaused, checkPoolSunset, checkQuotaCount, checkQuotaLimit, checkRWAOpenRequirements, checkRWAOpening, checkReservePriceLimited, checkSimulation, checkWallet, checkWalletAllowance, checkWalletBalance, raise, toToken, toTokenAmount };
|
|
@@ -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
|
|
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 (!
|
|
75
|
-
const requirements = await sdk.accounts.getOpenAccountRequirements(request.wallet, request.creditManager, { tokenOutAddress:
|
|
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",
|