diff --git a/src/api/info/_methods/_base/_schemas.ts b/src/api/info/_methods/_base/_schemas.ts index 77f32767..59e4cef9 100644 --- a/src/api/info/_methods/_base/_schemas.ts +++ b/src/api/info/_methods/_base/_schemas.ts @@ -243,6 +243,11 @@ export type TwapState = { reduceOnly: boolean; /** Order side ("B" = Bid/Buy, "A" = Ask/Sell). */ side: "B" | "A"; + /** + * Price at which the order is terminated; `null` when unset. + * @pattern ^[0-9]+(\.[0-9]+)?$ + */ + stopPx: string | null; /** * Order size. * @pattern ^[0-9]+(\.[0-9]+)?$ @@ -250,6 +255,16 @@ export type TwapState = { sz: string; /** Start time of the TWAP order (in ms since epoch). */ timestamp: number; + /** Condition that activates the order; `null` when unset. */ + trigger: { + /** + * Trigger price. + * @pattern ^[0-9]+(\.[0-9]+)?$ + */ + px: string; + /** Activates when the mark price is above (`true`) or below (`false`) the trigger price. */ + above: boolean; + } | null; /** * User address. * @pattern ^0x[a-fA-F0-9]{40}$ diff --git a/src/api/info/_methods/twapHistory.ts b/src/api/info/_methods/twapHistory.ts index ac6c8fe1..81ea3b7f 100644 --- a/src/api/info/_methods/twapHistory.ts +++ b/src/api/info/_methods/twapHistory.ts @@ -35,11 +35,13 @@ export type TwapHistoryResponse = { * - `"finished"`: Fully executed. * - `"activated"`: Active and executing. * - `"terminated"`: Terminated. + * - `"waitingForTrigger"`: Awaiting the trigger price. + * - `"stopped"`: Terminated by the stop price. * - `"error"`: An error occurred. */ status: { /** Status of the TWAP order. */ - status: "finished" | "activated" | "terminated"; + status: "finished" | "activated" | "terminated" | "waitingForTrigger" | "stopped"; } | { /** Status of the TWAP order. */ status: "error"; diff --git a/tests/api/exchange/_t.ts b/tests/api/exchange/_t.ts index dec875d6..5e165694 100644 --- a/tests/api/exchange/_t.ts +++ b/tests/api/exchange/_t.ts @@ -242,7 +242,7 @@ export async function createTWAP( const midPx = allMids[symbol]; // Calculate order parameters - const sz = formatSize(55 / Number(midPx), szDecimals); + const sz = formatSize(110 / Number(midPx), szDecimals); // Place TWAP order const result = await client.twapOrder({ diff --git a/tests/api/exchange/twapOrder.test.ts b/tests/api/exchange/twapOrder.test.ts index 8815cf95..a881132e 100644 --- a/tests/api/exchange/twapOrder.test.ts +++ b/tests/api/exchange/twapOrder.test.ts @@ -19,7 +19,7 @@ runTest({ const szDecimals = symbolConverter.getSzDecimals("SOL")!; const midPx = allMids["SOL"]; - const sz = formatSize(60 / parseFloat(midPx), szDecimals); + const sz = formatSize(110 / parseFloat(midPx), szDecimals); const params: TwapOrderParameters[] = [ // b=true | r=false | t=false diff --git a/tests/api/info/twapHistory.test.ts b/tests/api/info/twapHistory.test.ts index d4032a5a..1d3615c6 100644 --- a/tests/api/info/twapHistory.test.ts +++ b/tests/api/info/twapHistory.test.ts @@ -11,9 +11,11 @@ const paramsSchema = valibotToJsonSchema(v.omit(TwapHistoryRequest, ["type"])); runTest({ name: "twapHistory", + isTestnet: false, codeTestFn: async (_t, client) => { const params: TwapHistoryParameters[] = [ - { user: "0xe019d6167E7e324aEd003d94098496b6d986aB05" }, + { user: "0x03ce7863a2b62f4e227fd98605b79beb32618c76" }, + { user: "0x0132157369b0d073dd99011da1777920a025fd77" }, // trigger.above: false ]; const data = await Promise.all(params.map((p) => client.twapHistory(p))); diff --git a/tests/api/subscription/_t.ts b/tests/api/subscription/_t.ts index cf85e936..82a855fd 100644 --- a/tests/api/subscription/_t.ts +++ b/tests/api/subscription/_t.ts @@ -22,16 +22,18 @@ const OFFLINE = Deno.args.includes("--offline"); export function runTest(options: { name: string; mode: "api" | "rpc"; + isTestnet?: boolean; fn: (t: Deno.TestContext, client: SubscriptionClient) => Promise; }): void { - const { name, mode, fn } = options; + const { name, mode, isTestnet = true, fn } = options; Deno.test(name, { ignore: OFFLINE }, async (t) => { await new Promise((r) => setTimeout(r, WAIT)); // delay to avoid rate limits // --- Preparation ------------------------------------------------ - const transport = new WebSocketTransport({ url: `wss://${mode}.hyperliquid-testnet.xyz/ws`, isTestnet: true }); + const domain = isTestnet ? "hyperliquid-testnet.xyz" : "hyperliquid.xyz"; + const transport = new WebSocketTransport({ url: `wss://${mode}.${domain}/ws`, isTestnet }); await transport.ready(); const subsClient = new SubscriptionClient({ transport }); diff --git a/tests/api/subscription/twapStates.test.ts b/tests/api/subscription/twapStates.test.ts index 4a84443f..1436db88 100644 --- a/tests/api/subscription/twapStates.test.ts +++ b/tests/api/subscription/twapStates.test.ts @@ -33,6 +33,8 @@ runTestWithExchange({ schemaCoverage(paramsSchema, params); schemaCoverage(responseSchema, data, [ "#/properties/states/items/items/1/properties/side/enum/1", + "#/properties/states/items/items/1/properties/stopPx/defined", + "#/properties/states/items/items/1/properties/trigger/defined", ]); }, }); diff --git a/tests/api/subscription/userEvents.test.ts b/tests/api/subscription/userEvents.test.ts index a2a56ee4..2acd933b 100644 --- a/tests/api/subscription/userEvents.test.ts +++ b/tests/api/subscription/userEvents.test.ts @@ -34,8 +34,12 @@ runTestWithExchange({ "#/anyOf/2", "#/anyOf/3", "#/anyOf/4/properties/twapHistory/items/properties/state/properties/side/enum/1", + "#/anyOf/4/properties/twapHistory/items/properties/state/properties/stopPx/defined", + "#/anyOf/4/properties/twapHistory/items/properties/state/properties/trigger/defined", "#/anyOf/4/properties/twapHistory/items/properties/status/anyOf/0/properties/status/enum/0", "#/anyOf/4/properties/twapHistory/items/properties/status/anyOf/0/properties/status/enum/2", + "#/anyOf/4/properties/twapHistory/items/properties/status/anyOf/0/properties/status/enum/3", + "#/anyOf/4/properties/twapHistory/items/properties/status/anyOf/0/properties/status/enum/4", "#/anyOf/4/properties/twapHistory/items/properties/status/anyOf/1", "#/anyOf/4/properties/twapHistory/items/properties/twapId/missing", "#/anyOf/5/properties/twapSliceFills/items/properties/fill/properties/side/enum/1", diff --git a/tests/api/subscription/userTwapHistory.test.ts b/tests/api/subscription/userTwapHistory.test.ts index 05b9152a..515d2905 100644 --- a/tests/api/subscription/userTwapHistory.test.ts +++ b/tests/api/subscription/userTwapHistory.test.ts @@ -16,10 +16,13 @@ const paramsSchema = valibotToJsonSchema(v.omit(UserTwapHistoryRequest, ["type"] runTest({ name: "userTwapHistory", mode: "api", + isTestnet: false, fn: async (_t, client) => { const params: UserTwapHistoryParameters[] = [ - { user: "0x563C175E6f11582f65D6d9E360A618699DEe14a9" }, - { user: "0xe019d6167E7e324aEd003d94098496b6d986aB05" }, + { user: "0x03ce7863a2b62f4e227fd98605b79beb32618c76" }, // trigger.above: true + { user: "0x0132157369b0d073dd99011da1777920a025fd77" }, // trigger.above: false + { user: "0x051748895c6ed4fab50828bebe8e62e665134d23" }, // "stopped" + { user: "0x06d5af06a3a7d29909e1cdc7a9deded2fb14ab57" }, // "error" ]; const data = await collectEventsOverTime(async (cb) => { @@ -29,6 +32,7 @@ runTest({ schemaCoverage(paramsSchema, params); schemaCoverage(responseSchema, data, [ "#/properties/isSnapshot/missing", + "#/properties/history/items/properties/twapId/missing", ]); }, });