Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/sdk-usdh-orders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@usdh-kit/sdk': minor
---

Add USDH-only spot order layer. The kit now exposes `placeOrder`,
`cancelOrder`, `getOpenOrders`, and `getOrderStatus`, all gated to spot pairs
where USDH is base or quote. `placeOrder` accepts a limit price (with
`tif: 'Gtc' | 'Ioc' | 'Alo'`) or, when omitted, runs as a slippage-tolerant
market order via IOC. `swap()` is unchanged. `InfoClient` gains
`frontendOpenOrders` and `orderStatus` reads to back the new methods.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ A few real flows the SDK is shaped for today. Runnable examples are still on the
- HyperEVM → HyperCore bridge with credit polling (`bridgeToCore`)
- HyperCore balance, route/preflight helpers plus `bridgeAndSwap()` orchestration
- Experimental read-only outcome market metadata, books, and mids
- USDH-only spot order helpers for placing, cancelling, and reading USDH-pair orders
- Wallet-agnostic `Signer` interface (works with viem, ethers, Privy, Turnkey, raw private key)
- Approved Hyperliquid agent wallet flow for browser apps (`approveAgent`, `accountAddress`)
- Read-only `InfoClient` (spotMeta, outcomeMeta, spot clearinghouse state, L2 book, allMids) for consumers building custom UIs
Expand Down
11 changes: 7 additions & 4 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,16 @@ kit.placeOutcomeOrder({
Build only the trading primitives needed for USDH markets:

```ts
kit.placeOrder(...)
kit.cancelOrder(...)
kit.getOpenOrders(...)
kit.getOrderStatus(...)
kit.placeOrder({ pair, side, size, price?, tif?, slippageBps? })
kit.cancelOrder({ pair, oid })
kit.getOpenOrders({ pair? })
kit.getOrderStatus({ pair, oid })
```

This should be a focused USDH-market order layer, not a full Hyperliquid SDK.
`pair` accepts the live `listPairs()` name such as `@230` and ergonomic token
aliases such as `USDH/USDC` or `HYPE/USDH`; reads remain filtered to USDH-bearing
spot pairs.

### Scope

Expand Down
23 changes: 23 additions & 0 deletions packages/sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,28 @@ const outcomeMids = await kit.getOutcomeMids()
console.log(market.name, yesBook.coin, outcomeMids[market.sides[0].coin])
```

## Trade USDH spot pairs

The order layer is scoped to USDH-bearing spot pairs. `pair` accepts the live
`pair.name` returned by `listPairs()` (usually `@<spotIndex>`) or a token alias
such as `USDH/USDC` or `HYPE/USDH`.

```ts
const order = await kit.placeOrder({
pair: 'USDH/USDC',
side: 'buy',
size: '10',
price: '1',
})

await kit.cancelOrder({ pair: 'USDH/USDC', oid: order.oid })

const openOrders = await kit.getOpenOrders({ pair: 'USDH/USDC' })
const status = await kit.getOrderStatus({ pair: 'USDH/USDC', oid: order.oid })

console.log(openOrders.length, status.status)
```

## Bridge and swap

`bridgeAndSwap()` composes the common retail flow:
Expand Down Expand Up @@ -205,6 +227,7 @@ Unexpected route, bridge, or swap failures are wrapped in `BridgeAndSwapError`.
* `bridgeAndSwap()` high-level orchestration with progress callbacks
* USDH spot market discovery and read-only books/mids for USDH pairs
* Experimental read-only outcome market metadata, books, and mids
* USDH-only spot order helpers for place, cancel, open orders, and order status
* Wallet-agnostic `Signer` interface (works with viem, ethers, Privy, Turnkey, raw private key)
* Read-only `InfoClient` (spotMeta, outcomeMeta, spot clearinghouse state, L2 book, allMids)
* Typed error hierarchy rooted at `UsdhKitError`, including `BridgeAndSwapError` phase/cause context and `isBridgeAndSwapError()` narrowing
Expand Down
14 changes: 14 additions & 0 deletions packages/sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ export {
outcomeEncoding,
outcomeTokenName,
} from './outcomes.js'
export type {
CancelOrderInput,
CancelOrderResult,
GetOpenOrdersInput,
GetOrderStatusInput,
OrderSide,
PlaceOrderInput,
PlaceOrderResult,
Tif,
} from './orders.js'
export type {
GetOutcomeBookInput,
GetOutcomeMarketInput,
Expand All @@ -30,6 +40,10 @@ export type { InfoClient, InfoClientConfig, NSigFigs } from './transport/info.js
export type {
L2Book,
L2Level,
OpenOrder,
OrderStatusDetail,
OrderStatusResponse,
OrderStatusValue,
OutcomeMeta,
OutcomeMetaOutcome,
OutcomeMetaQuestion,
Expand Down
46 changes: 44 additions & 2 deletions packages/sdk/src/kit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ import {
NetworkError,
NotImplementedError,
} from './errors.js'
import {
type CancelOrderInput,
type CancelOrderResult,
type GetOpenOrdersInput,
type GetOrderStatusInput,
type PlaceOrderInput,
type PlaceOrderResult,
createOrders,
} from './orders.js'
import {
type GetOutcomeBookInput,
type GetOutcomeMarketInput,
Expand All @@ -37,7 +46,7 @@ import {
isOrderResponse,
} from './transport/exchange.js'
import { type InfoClient, type NSigFigs, createInfoClient } from './transport/info.js'
import type { L2Book } from './transport/types.js'
import type { L2Book, OpenOrder, OrderStatusResponse } from './transport/types.js'
import type { BridgeInput, BridgeResult } from './types/bridge.js'
import type { KitConfig } from './types/config.js'
import type { Logger } from './types/logger.js'
Expand Down Expand Up @@ -97,7 +106,7 @@ export interface UsdhKit {
listPairs(opts?: ListUsdhPairsOpts): Promise<UsdhPair[]>
/** Find one USDH-bearing spot pair by base/quote token names. */
getPair(input: GetUsdhPairInput): Promise<UsdhPair>
/** Fetch the L2 book for a pair name (e.g. "USDH/USDC"). */
/** Fetch the L2 book for a live pair name, usually `@<spotIndex>`. */
getBook(pair: string, opts?: { nSigFigs?: NSigFigs }): Promise<L2Book>
/** Fetch mid prices, optionally filtered to USDH-quote pairs. */
getMids(opts?: GetMidsOpts): Promise<Record<string, string>>
Expand All @@ -109,6 +118,14 @@ export interface UsdhKit {
getOutcomeBook(input: GetOutcomeBookInput): Promise<L2Book>
/** Fetch mid prices keyed by encoded outcome side coin, e.g. `#200`. */
getOutcomeMids(): Promise<Record<string, string>>
/** Place a USDH-pair spot order. Accepts `listPairs()` names or token aliases like `USDH/USDC`. */
placeOrder(input: PlaceOrderInput): Promise<PlaceOrderResult>
/** Cancel a resting USDH-pair order by oid. */
cancelOrder(input: CancelOrderInput): Promise<CancelOrderResult>
/** List the user's USDH-pair resting open orders, optionally filtered to one pair. */
getOpenOrders(input?: GetOpenOrdersInput): Promise<OpenOrder[]>
/** Fetch a single USDH-pair order's status by pair and oid. */
getOrderStatus(input: GetOrderStatusInput): Promise<OrderStatusResponse>
}

/**
Expand Down Expand Up @@ -142,6 +159,15 @@ export function createUsdhKit(config: KitConfig): UsdhKit {
return candidate
}

const orders = createOrders({
info,
exchange,
signer: config.signer,
network: config.network,
accountAddress,
nextNonce,
})

async function swap(input: SwapInput): Promise<SwapResult> {
validateSwapInput(input)
const slippageBps = input.slippageBps ?? defaultSlippageBps
Expand Down Expand Up @@ -333,6 +359,22 @@ export function createUsdhKit(config: KitConfig): UsdhKit {
return outcomeDiscovery.getOutcomeMids()
},

placeOrder(input) {
return orders.placeOrder(input)
},

cancelOrder(input) {
return orders.cancelOrder(input)
},

getOpenOrders(input) {
return orders.getOpenOrders(input)
},

getOrderStatus(input) {
return orders.getOrderStatus(input)
},

async getQuote(input: QuoteInput): Promise<Quote> {
validateQuoteInput(input)
if (input.from === 'USDT') {
Expand Down
Loading
Loading