Closing a position
Closing is one EIP-712 op. The trick is signerAccount.addr: for closes it's the virtual account, not the sub-account.
Why? Because as far as the Symmio core is concerned, it's that virtual address that holds the quote. The core looks up quotes[quoteId].partyA and checks that the caller (after the AccountLayer's signer-context forwarding) matches. That partyA is the VA. Sign as the sub-account and the core rejects the call with an authorization error that doesn't exactly say "wrong account"; it just fails.
Compute close price
Slippage runs in the opposite direction to opens: when you close a long, you're selling, so you accept a lower price; when you close a short, you're buying back, so you accept a higher price.
CLOSE LONG
price = mark × (1 − slippage / 100)
CLOSE SHORT
price = mark × (1 + slippage / 100)
Quantize to price_precision and convert to wei.
Sign one SignedOperation
The envelope is the same SignedOperation struct as for opens, the domain is the same SymmioInstantLayer, and the signer is the same session key. The fields that differ:
target: Symmio Core (same assendQuote)signerAccount.addr: virtual accountcallData: selector0x501e891ffollowed by ABI-encoded(quoteId: uint256, closePrice: uint256, quantityToClose: uint256, orderType: uint8, deadline: uint256).orderType = 1for MARKET.
POST as a JSON array
POST <instant-close endpoint>
Content-Type: application/json
[
{
"signedOperation": { ... },
"signature": "0x..."
}
]Note the array. Open is a JSON object, close is a JSON array. Mixing them up may cause failures on the server side.
The solver responds with 200 null when the close is queued. The notifications WS will show FillCloseRequest once it fills on-chain.
Last updated

