@somnia-chain/markets-sdk / index / PerpOrderMarginQuote
Interface: PerpOrderMarginQuote
Defined in: packages/sdk/src/perp/margin.ts:1848
The placement gates and the lock they are measured against.
Properties
increasingQuantity
increasingQuantity:
bigint
Defined in: packages/sdk/src/perp/margin.ts:1850
The part of the order that increases the position — the only part that locks.
reducingQuantity
reducingQuantity:
bigint
Defined in: packages/sdk/src/perp/margin.ts:1852
The part absorbed by existing exposure. Locks nothing.
lockAmount
lockAmount:
bigint
Defined in: packages/sdk/src/perp/margin.ts:1854
Total collateral the pool will lock.
initialMarginPortion
initialMarginPortion:
bigint
Defined in: packages/sdk/src/perp/margin.ts:1856
The initial-margin component of lockAmount.
adverseGapPortion
adverseGapPortion:
bigint
Defined in: packages/sdk/src/perp/margin.ts:1858
The adverse mark-to-entry component, zero on a favourable entry.
leverageSurcharge
leverageSurcharge:
bigint
Defined in: packages/sdk/src/perp/margin.ts:1860
Extra margin a leverage cap stricter than the market's IMF demands.
feeHeadroom
feeHeadroom:
bigint
Defined in: packages/sdk/src/perp/margin.ts:1878
The pool's worst-case fee reserve for this order (PerpPool._feeHeadroom).
Not part of lockAmount and not charged — perps locks only initial margin
and takes fees from the unlocked balance at fill. It exists solely as an auto-pull
addend, so that pulling exactly the lock cannot leave a max-leverage open at
equity = IM − fees against an IM requirement, i.e. in MarginCall at birth.
The rate is an envelope, not a prediction: an order rests as a maker or crosses as a taker but never both, so it takes the larger of the two — with a negative (rebate) maker rate floored at zero first, since a rebate must not shrink the reserve below the taker case — plus the order's builder fee. Ceil-rounded, on the full order notional rather than the increasing leg, because fees are charged on the whole fill.
Reported whatever topUpRequired does, but it only enters the arithmetic when auto-pull is modelled.
topUpRequired
topUpRequired:
bigint
Defined in: packages/sdk/src/perp/margin.ts:1899
What auto-pull would REQUEST in total (MarginBank.quoteOrderTopUp) — 0n when
PerpOrderMarginQuoteInputs.wallet is omitted, i.e. when auto-pull is not
being modelled at all.
Not the owner's wallet debit once a main is in play. It is the requirement, and ownWalletPull / mainWalletPull are the two wallets that meet it. Showing this figure as the child's spend over-states it by exactly the main's leg.
lockAmount + feeHeadroom + leverageSurcharge less the unlocked balance, floored at
zero. Order-local by design: it excludes the initial margin of the account's
positions in other markets, so it is exactly sufficient for a FLAT account and
best-effort for one already carrying exposure — a pre-existing cross-market deficit
still fails meetsInitialMargin. Auto-pull funds an ORDER, not an ACCOUNT.
A 0n is three different things, which is why it should be read beside the balance
rather than alone: no pull needed, or one of the pool's three declines — a purely
reducing order (closing never debits a wallet), an account already in debt (a pull
would silently cure bad debt), or a voucher-blocked increase.
walletCoversTopUp
walletCoversTopUp:
boolean
Defined in: packages/sdk/src/perp/margin.ts:1919
The funding wallets can together cover topUpRequired — the owner's own balance and allowance, plus a linked main's capacity when one was supplied.
Vacuously true when no pull is needed or auto-pull is not modelled. What a
false MEANS depends on whether a main is in play, and the two are not the same
outcome:
- No main. The pool asks for a fixed
topUpRequired, so thetransferFrominsidedepositForreverts and the placement fails on the TOKEN's error rather than a margin gate — deliberate, because that error names the fix. This is a placement gate and it folds into sufficient. - With a main. Both legs are
min(...)-sized and neither can revert, so the pool pulls what it can and the margin gates judge the result. This is then INFORMATIONAL and does NOT fold into sufficient: the order can be accepted with the lock funded and the fee reserve short, which is precisely what feeHeadroom exists to avoid. Read afalsehere as "the position may be born close to its own initial margin", not as "this will be rejected".
ownWalletPull
ownWalletPull:
bigint
Defined in: packages/sdk/src/perp/margin.ts:1926
How much of topUpRequired the OWNER's own wallet would supply.
min(topUpRequired, min(balance, allowance)). The owner's wallet always pays first,
so a child holding some collateral spends its own before it touches its main's.
mainWalletPull
mainWalletPull:
bigint
Defined in: packages/sdk/src/perp/margin.ts:1942
How much of topUpRequired a linked MAIN's wallet would supply — the residual the owner's own wallet could not cover, capped at PerpOrderMarginQuoteInputs.mainWalletCapacity.
0n with no main, 0n for an account that funds itself, and 0n while
mainFundingBlocked. Non-zero is the only proof another wallet is actually
debited — an eligible payer alone is not, since the order may need no top-up or
the owner's own wallet may cover all of it. This is the number to show a trader
before they sign.
ownWalletPull + mainWalletPull is what the pull actually moves, and it is BELOW
topUpRequired exactly when walletCoversTopUp is false — neither leg
reverts on a short wallet, so the shortfall surfaces at the margin gates instead.
hasCollateralForLock
hasCollateralForLock:
boolean
Defined in: packages/sdk/src/perp/margin.ts:1950
Gate 1 — the unlocked balance covers the lock, after any auto-pull.
With PerpOrderMarginQuoteInputs.wallet supplied this is the real post-pull
gate. Without it, the in-bank balance alone — conservative rather than wrong on the
self-send path, since the pool tops up before lockCollateral runs.
meetsInitialMargin
meetsInitialMargin:
boolean
Defined in: packages/sdk/src/perp/margin.ts:1964
Gate 2 — post-lock equity still meets the initial-margin requirement, after any auto-pull (the top-up lands in the unlocked balance that seeds equity).
Note this is NOT monotone in quantity once auto-pull is modelled, and the reason is
worth knowing: in the pulled regime the surcharge cancels from both sides and the
gate reduces to (equity − unlocked) + feeHeadroom ≥ imRequirement, whose only
quantity-dependent term GROWS. An account whose existing positions sit below their
own initial margin can therefore be rejected at a middling size and accepted at a
far larger one, whose headroom over-pulls enough to cover the deficit.
client.getMaxPerpOrderSize deliberately does not offer sizes from that disconnected
upper region.
mainFundingBlocked
mainFundingBlocked:
boolean
Defined in: packages/sdk/src/perp/margin.ts:1970
The main's leg was withheld because the account still owes a prior payer — see PerpOrderMarginQuoteInputs.mainFundingBlocked. Placement is not blocked outright, only the main's contribution.
voucherBlocked
voucherBlocked:
boolean
Defined in: packages/sdk/src/perp/margin.ts:1972
The order would revert on the voucher allowlist / unset-cap guard.
restrictedBlocked
restrictedBlocked:
boolean
Defined in: packages/sdk/src/perp/margin.ts:1977
The market is close-only and this order has an increasing leg, so placement reverts
MarketRestricted. Never blocks a pure reduce.
isolationBlocked
isolationBlocked:
boolean
Defined in: packages/sdk/src/perp/margin.ts:1983
The account is in isolated margin with a footprint in a DIFFERENT market, so
placement reverts IsolatedMarketBlocked. Unlike every other gate here this blocks
the reducing legs too — it is about which market may be traded, not about margin.
sufficient
sufficient:
boolean
Defined in: packages/sdk/src/perp/margin.ts:1985
Every gate passes.