Skip to content
markpaper

src/signer/types.ts

v0.2.1 · 2.9 KB

Download file
// Contract of the signer sidecar (knowledge base: signing-and-sdk.md §3) as seen from TypeScript.

import type { SignerErrorKind } from './errors.js';

/** Sidecar routes. */
export const SIGNER_PATHS = {
  health: '/health',
  auth: '/auth',
  order: '/order',
  cancel: '/cancel',
  leverage: '/leverage',
} as const;

/** `SignerClient.CROSS_MARGIN_MODE` in the Python SDK. Isolated margin was not verified live. */
export const CROSS_MARGIN_MODE = 0;
/** `SignerClient.ISOLATED_MARGIN_MODE` in the Python SDK. @experimental not verified live. */
export const ISOLATED_MARGIN_MODE = 1;

/** Body of `POST /order`; the sidecar maps `ioc` to IoC + `DEFAULT_IOC_EXPIRY`, otherwise GTT + 28-day expiry. */
export interface PlaceOrderRequest {
  /** `market_id` from the meta. */
  marketIndex: number;
  /** Your unique-per-account index (see `ids.createClientOrderIndex`). */
  clientOrderIndex: number;
  /** Wire integer: `size * 10^sizeDecimals` (`numbers.toWire`). */
  baseAmount: number;
  /** Wire integer: `price * 10^priceDecimals` (`numbers.toWire`). */
  price: number;
  /** `true` = sell. */
  isAsk: boolean;
  reduceOnly?: boolean;
  /** `true` = immediate-or-cancel; `false` (default) = resting GTT. */
  ioc?: boolean;
}

/** Body of `POST /cancel`. `orderId` is the EXACT string id and is sent as the string `order_index`. */
export interface CancelOrderRequest {
  marketIndex: number;
  orderId: string;
}

/** Body of `POST /leverage`: `update_leverage(market_index, margin_mode, leverage)`. */
export interface UpdateLeverageRequest {
  marketIndex: number;
  /** Integer >= 1, at most the market cap `floor(10000 / min_initial_margin_fraction)`. */
  leverage: number;
  /** Default {@link CROSS_MARGIN_MODE}. */
  marginMode?: number;
}

/**
 * Outcome of a write. The three failure states MUST stay distinct (knowledge base: orders.md §9):
 * - `rateLimited`: our own window refused; nothing was sent; a retry next tick is safe;
 * - `rejected`: the exchange (or the sidecar) answered with an error; the outcome is known;
 * - `unknown`: timeout or loopback failure; the order MAY have gone out; never retry blindly,
 *   reconcile against the book / position instead. A cancel with `unknown` is NOT confirmed.
 */
export type SignerWriteResult =
  | { status: 'ok'; txHash: string | null; raw: unknown }
  | {
      status: 'rejected';
      error: string;
      kind: SignerErrorKind;
      code: number | undefined;
      httpStatus: number | undefined;
      raw: unknown;
    }
  | { status: 'unknown'; error: string }
  | { status: 'rateLimited'; error: string };

export interface SignerHealth {
  /** The sidecar answered at all. */
  reachable: boolean;
  /** `check_client()` passed. */
  ok: boolean;
  error: string | null;
  accountIndex: number | undefined;
  apiKeyIndex: number | undefined;
  /** Instance base URL the sidecar signs for; compare with the REST client's. */
  url: string | undefined;
}
All files