Build, preview, and check
Turn a prepared operation into transaction calldata, assess its projected effect, and check its prerequisites. Continue here from Open, Manage, or Delayed withdrawals.
Use the already-connected sdk and supply the sender's address as owner.
No wallet connection or signer is required. The result is a transaction
payload; signing and execution are up to you.
Build the transaction
Choose the builder for your operation. Each snippet defines chainId and
tx for the shared preview below. If an operation already produced tx,
such as a quota update, skip to
Preview and check with its chainId and owner.
Open a leveraged position
Use strategy, selectedStrategy, params, and the successful sim from
Open.
owner is the address funding and owning the new Credit Account.
const chainId = strategy.chainId; const targetToken = params.targetToken ?? selectedStrategy.data.targetCollateral.address; const tx = await sdk.opportunities.execute.buildTx({ kind: "open", chainId, creditManager: strategy.creditManager, wallet: owner, collateral: params.collateral, ethAmount: 0n, targetToken, sim, });
Update a leveraged position
Use the selected position and successful sim from an operation in
Manage or from
finalizing a delayed withdrawal.
For a routed operation, pass the chosen route's result, not the two-route
container. Quota updates already produced tx and do not use this builder.
const chainId = position.chainId; const tx = await sdk.opportunities.execute.buildTx({ kind: "account", chainId, creditAccount: position.creditAccount, wallet: owner, sim, });
Preview and check
previewOperation() estimates the transaction's effect. checkOperation()
checks the operation's prerequisites, including token approvals, balances,
market limits, and the chosen HF thresholds. For an opening or reopening,
it also checks applicable KYC/registration requirements. Neither call signs
or broadcasts a transaction.
const preview = await sdk.preview.previewOperation({ chainId, to: tx.to, calldata: tx.callData, value: BigInt(tx.value), sender: owner, }); if (!preview.ok) throw preview.error; const issues = await sdk.preview.checkOperation( { chainId, preview: preview.data, sender: owner }, { minHealthFactor: 10_500, // Require HF >= 1.05 at main prices (basis points) minSafeHealthFactor: 10_500, // Require HF >= 1.05 at safe prices }, );
These thresholds leave a buffer above the liquidation boundary, HF 1.0. Choose the buffer for your risk policy; omitting a threshold disables that check. They are SDK validation settings, not constraints added to the calldata.
Read the preview result
preview.ok means the SDK could produce a preview; it does not mean the
operation passed validation. Read preview.data.operation to identify the
result's structure. It describes the decoded transaction, so do not infer
it solely from the preparation method you called.
operation | Meaning |
|---|---|
"OpenCreditAccount" | Opening a leveraged position; also used when borrowing again on an existing account with zero debt and no quotas |
"AdjustCreditAccount" | Account adjustment, including quota changes and partial repayments |
"RepayCreditAccount" | Full repayment |
"CloseCreditAccount" | Exit |
"DelayedCreditAccountOperation" | instantPreview describes the account after the request; delayedPreview is the best-effort result after claiming and resuming the recorded operation. estClaimableAt Optional is the estimated claimable time in Unix seconds |
For delayed operations, inspect both nested previews. checkOperation() checks
only instantPreview; it does not validate the future claim. If no intent was
recorded, delayedPreview describes the claim alone. Follow
Delayed withdrawals when it matures.
The fields below are on preview.data for immediate operations, or on each
nested preview for a delayed operation. Compare them with the current
leveraged position, if any, and the outcome you requested. For immediate
operations and instantPreview, fields prefixed with est use the minimum
swap outputs encoded in calldata; preparation reports expected outputs
instead. delayedPreview uses oracle-based estimates for future conversions,
so its amounts are not guaranteed swap minimums.
| Field | Type | Meaning |
|---|---|---|
creditAccount Optional on opening | Address | undefined | Account affected; when updating a position, check that it matches the selected account |
creditManager | Address | Credit Manager identifying the strategy affected |
name | string | Strategy name |
underlyingToken | UnderlyingToken | Asset used to denominate value and debt; the unwrapped asset for RWA markets |
targetCollateral Optional on opening | TokenAmount | undefined | Opening only: target collateral and its balance at minimum swap output; absent when nothing is quoted |
targetCollateral | Token | null | Adjustment, repayment, exit, or delayed request: target token metadata, without a balance |
totalDebt | TokenAmount | Debt after the operation, including interest and fees |
estTotalValue | TokenAmount | Projected value remaining in the account |
estNetValue | TokenAmount | Remaining equity: account value minus debt |
estAssets | TokenAmount[] | Projected token balances remaining in the account |
quotas | TokenAmount[] | Resulting quotas; each token identifies collateral, but value is in market underlying base units |
estLeverage | number | Resulting leverage as a multiple: 4 means 4× |
estHealthFactor | number | HF in basis points: 12500 means 1.25; below 10000 is liquidatable |
estSafeHealthFactor | number | HF using safe collateral prices, in the same units |
estBorrowRate.base | number | Annual base borrowing cost including the protocol interest fee, in basis points |
estBorrowRate.totalOnDebt | number | Annual borrowing cost including quotas, relative to debt, in basis points |
estBorrowRate.total | number | Annual borrowing cost including quotas, relative to account value, in basis points |
estBorrowRate.quotas | TokenQuotaRate[] | Per-collateral quota cost; each rate is in basis points relative to account value |
estTimeToLiquidation | bigint | null | Estimated milliseconds to HF 1 with fixed collateral value and borrowing rate; excludes collateral yield. null if debt has no rate or the account is already liquidatable |
estLiquidationPrice | bigint | null | Immediate HF 1 price threshold, in underlying per collateral token scaled by 10 ** 8; excludes future accrual and quota caps. null unless a single non-underlying collateral applies |
collateralAdded, collateralWithdrawn | TokenAmount[] | Tokens supplied and returned by an opening, adjustment, or repayment; exits report receivedAmount instead |
totalDebtChange | TokenAmount | Adjustment only: debt after minus debt before; negative means debt was repaid |
assetsChange | TokenAmount[] | Adjustment only: token balances after minus balances before |
quotasChange | TokenAmount[] | Adjustment only: quotas after minus quotas before, in market underlying base units, with each token identifying the collateral |
debtRepaid | TokenAmount | Repayment only: positive amount of debt settled |
receivedAmount | TokenAmount | Exit only: output returned to the recipient; minimum for an immediate exit, estimated for delayed completion |
permanent | boolean | Repayment or exit only: whether the Credit Account is permanently closed; false means it remains open |
warning Optional | UnpriceableTokenError | A token could not be priced and was excluded from valuation; investigate before relying on the value and HF figures |
TokenAmount contains token, value (bigint base units), and valueUsd
(number or null when unavailable). Format amounts using their token's
decimals, except quotas and quotasChange: those use market underlying
decimals even though their token metadata identifies collateral. Rates use
basis points: 520 means 5.2%.
Resolve validation issues
issues is an OperationValidationError[]. An empty array means no issues
were found by the applicable checks, not that a transaction was executed or
successfully simulated. Each issue has a machine-readable code and an
explanatory message; use code to access its details. For example,
insufficientAllowance includes owner, spender, required, and allowed;
insufficientCollateral includes healthFactor, healthFactorThreshold, and
safePrices. Review the projected outcome even when issues is empty.
Resolve prerequisites, including the approvals described in the action guide.
insufficientAllowance is a pre-transaction validation issue, not a failed
transaction. Approval execution belongs to your chosen execution flow.
After an approval confirms or the inputs change, repeat the action's
preparation and build steps, selecting its route if applicable. For a direct
quota transaction, repeat the quota update steps. Preview and check the new
tx, then resolve any remaining issues.
Transaction payload
The output is tx, to hand to your chosen execution system:
| Field | Meaning |
|---|---|
tx.to | Destination contract |
tx.callData | Encoded calldata; use as data in an Ethereum transaction request |
tx.value | Native-token amount in wei; convert with BigInt(tx.value) if required by the executor |
Keep chainId and owner with this payload: they identify the chain and
sender used for the checks. Signing and execution are up to you. If execution
is delayed, prepare, build, and check again. After execution, use
Monitor to read the leveraged position.