adapter.trading) lets you submit and cancel orders on HIP-4 prediction market outcomes. Before you can place any orders you must authenticate using adapter.auth.initAuth() - the trading adapter returns an error result (rather than throwing) if you attempt to place an order without a valid signer. Order placement performs local validation for tick alignment, notional size, and minimum shares before signing, so most errors are caught before hitting the exchange.
placeOrder(params)
Places a single order on a HIP-4 outcome. This method never throws - check the success field and the error message on the returned result instead.
For limit orders, the SDK performs these local checks before signing:
- Tick-aligns the price to 5 significant figures.
- Validates that the notional value (
price × amount) meets the minimum (10 USDC) unlessskipMinNotionalCheckistrue. - When
markPxis provided, validates thatamountmeets the minimum shares threshold.
[0.0001, 0.9999].
Parameters
string
required
The outcome ID as a string (e.g.
"516").string
required
The side identifier. Use the coin string (e.g.
"#5160" for side 0, "#5161"
for side 1). This determines which side of the outcome you are trading.string
required
"buy" or "sell".string
required
"market" or "limit".string
Limit price as a decimal string (0–1). Required for limit orders. Ignored for
market orders (the SDK computes price from the mid with slippage).
string
required
Order size in shares.
string
default:"GTC"
Time-in-force for limit orders. One of
"GTC", "GTD", "FOK", "FAK". See
the TIF mapping table below. Ignored for market orders.number
Current market price (0–1). When provided, the SDK enforces a minimum shares check:
amount >= getMinShares(markPx), which ensures the order meets the 10 USDC minimum notional.string
Optional referral address that receives builder fees. Checksummed addresses
are accepted; the SDK lowercases the value before signing.
number
Builder fee in tenths of a basis point.
0 = no fee. 100 = 0.1%. Maximum is
1000 (1.0%).boolean
When
true, skips the SDK’s local minimum-notional and minimum-shares
pre-checks. Use this for position-closing flows where the residual size may be
below 10 USDC but the exchange still accepts the order.TIF mapping
The SDK maps SDK-level TIF values to Hyperliquid order types as follows:Return type
Promise<PredictionOrderResult> - never throws.
boolean
required
true if the order was accepted by the exchange.string
Hyperliquid order ID. Present when the order filled or is resting.
string
"filled" - fully executed. "resting" - sitting in the book. "error" -
exchange rejected the order. "unknown" - unrecognized response.Filled size. Only present when
status === "filled".string
Error message. Present when
success === false.Examples
cancelOrder(params[])
Cancels one or more resting orders. Unlike placeOrder, this method throws on failure.
Parameters
cancelOrder accepts an array of cancel requests:
string
required
The outcome ID as a string.
string
required
The Hyperliquid order ID to cancel. Obtain this from
placeOrder’s orderId
field or from adapter.account.fetchOpenOrders().string
Optional side identifier (e.g.
"#5160"). Providing this resolves the correct
side asset ID. When omitted, the SDK defaults to side 0.Return type
Promise<void> - resolves when all cancels are confirmed. Throws if authentication is missing or the exchange rejects the request.
Example
Token conversions
Four protocol-level share-conversion primitives that move value between USDC and outcome tokens without touching the orderbook. They settle directly against your spot balances at the bundle-equivalence mint price - no spread paid, no slippage, no liquidity required. See the Converting tokens concept for the math, and the Token conversions guide for end-to-end code. All four methods use the sameuserOutcome action envelope, sign via L1 agent signing, and return a WalletActionResult. None of them throw.
splitOutcome(params)
Burn X USDC and mint X Yes shares + X No shares of one outcome.
Parameters
number
required
Numeric outcome ID. Matches
market.outcomeId on a fetched HIP-4 market.string
required
USDC amount to split, as a decimal string (e.g.
"12.5"). The SDK strips
trailing zeros to match Hyperliquid’s wire format. X USDC burned → X Yes +
X No minted.Return type
Promise<WalletActionResult> - never throws.
mergeOutcome(params)
The inverse of splitOutcome. Burn X Yes + X No of one outcome and mint X USDC.
Parameters
number
required
Numeric outcome ID.
string | null
required
Paired-share count to merge, as a decimal string. Pass
null to merge the
maximum available - the protocol burns min(yes_balance, no_balance) shares.Return type
Promise<WalletActionResult> - never throws.
mergeQuestion(params)
Burn X Yes shares from every outcome of a question (including the fallback) and mint X USDC. Lets you redeem a full Yes-bundle for collateral before the question resolves.
Parameters
number
required
Numeric question ID. For multi-outcome and price-bucket markets, this is
market.questionId. Default-binary markets have no parent question - use
mergeOutcome instead.string | null
required
Yes-share count to redeem from each member outcome, as a decimal string. Pass
null to redeem the maximum - min(yes_balance) across every outcome of the
question.Return type
Promise<WalletActionResult> - never throws.
negateOutcome(params)
Burn X No shares of one outcome and mint X Yes shares of every other outcome in the same question (including the fallback). Converts “I don’t think this wins” into “I think one of the others wins” without touching the orderbook.
Parameters
number
required
Numeric question ID containing the source outcome.
number
required
Source outcome ID whose No shares are being converted. Must belong to
question.string
required
No-share count to convert, as a decimal string. After the call, your No
balance on
outcome drops by amount, and you hold amount additional Yes
shares of every other outcome under question.Return type
Promise<WalletActionResult> - never throws.
The on-wire sub-action key is
negateOutcome, matching Hyperliquid’s testnet
“Convert Outcomes” UI. Hyperliquid’s docs body shows negateQuestion in
places - that’s a typo in their docs. The SDK sends negateOutcome.