OpenPond
1Branch0Tags
GL
glucryptoMerge commit 'refs/tmp/prod-master'
typescript
import { z } from "zod"; import { wallet, WalletFullContext } from "opentool/wallet"; import { store } from "opentool/store"; import { buildHyperliquidMarketIdentity, cancelHyperliquidOrders, cancelHyperliquidOrdersByCloid, isHyperliquidSpotSymbol, normalizeHyperliquidBaseSymbol, parseSpotPairSymbol, resolveHyperliquidChainConfig, resolveHyperliquidOrderSymbol, resolveHyperliquidPair, } from "opentool/adapters/hyperliquid"; export const profile = { description: "Cancel a Hyperliquid order by oid or client order id (cloid). Logs to store.", }; export const schema = z.object({ oid: z.union([ z.number().int().nonnegative(), z.string().regex(/^\d+$/, "oid must be a positive integer"), ]).optional(), cloid: z .string() .regex(/^0x[a-fA-F0-9]{32}$/, "cloid must be a 0x-prefixed 16-byte hex") .optional(), symbol: z.string().min(1, "symbol is required").default("BTC-USD"), environment: z.enum(["mainnet", "testnet"]).default("testnet"), }); export async function POST(req: Request): Promise<Response> { const body = await req.json().catch(() => ({})); const { oid, cloid, symbol, environment } = schema.parse(body); const rawSymbol = symbol.trim(); const orderSymbol = resolveHyperliquidOrderSymbol(rawSymbol); if (!orderSymbol) { return Response.json( { ok: false, error: "symbol must be a valid Hyperliquid market" }, { status: 400 } ); } const pair = resolveHyperliquidPair(rawSymbol); const parsedPair = pair ? parseSpotPairSymbol(pair) : null; const assetSymbol = normalizeHyperliquidBaseSymbol(rawSymbol) ?? normalizeHyperliquidBaseSymbol(orderSymbol) ?? orderSymbol; const isSpot = isHyperliquidSpotSymbol(orderSymbol); const marketIdentity = buildHyperliquidMarketIdentity({ environment, symbol: pair ?? orderSymbol, rawSymbol, isSpot, base: parsedPair?.base ?? null, quote: parsedPair?.quote ?? null, }); if (!marketIdentity) { return Response.json( { ok: false, error: "Unable to resolve market identity for cancel." }, { status: 400 } ); } if (!oid && !cloid) { return Response.json( { ok: false, error: "oid or cloid is required" }, { status: 400 } ); } const chainConfig = resolveHyperliquidChainConfig(environment); const ctx = await wallet({ chain: chainConfig.chain, rpcUrl: chainConfig.rpcUrl ?? process.env.RPC_URL, }); let result: unknown; if (cloid) { result = await cancelHyperliquidOrdersByCloid({ wallet: ctx as WalletFullContext, environment, cancels: [{ symbol: orderSymbol, cloid: cloid as `0x${string}` }], }); } else { const numericOid = typeof oid === "string" ? Number.parseInt(oid, 10) : oid; result = await cancelHyperliquidOrders({ wallet: ctx as WalletFullContext, environment, cancels: [{ symbol: orderSymbol, oid: numericOid! }], }); } await store({ source: "hyperliquid", ref: (cloid ?? oid ?? "").toString(), status: "cancelled", walletAddress: ctx.address, action: "order", network: environment === "mainnet" ? "hyperliquid" : "hyperliquid-testnet", market: marketIdentity, metadata: { symbol: orderSymbol, assetSymbol, pair: pair ?? null, rawSymbol, cancelled: cloid ?? oid, environment, }, }); return Response.json({ ok: true, result }); }