Skip to content
markpaper

src/signer/health.ts

v0.1.0 · 3.6 KB

Download file
export interface SidecarHealthView {
  pubkey: string | null;
  authority: string | null;
  traderPda: string | null;
  traderPdaIndex: number | null;
  subaccountIndex: number | null;
  readonly: boolean;
  signerLoaded: boolean;
  bindingOk: boolean;
  bindingProblems: string[];
  positionAuthority: string | null;
  solLamports: bigint | null;
  keyRiskWarning: string | null;
  keyRiskSwap: string | null;
  capabilitiesState: string | null;
  collateralQuoteLots: bigint | null;
  rpcOk: boolean;
  inflight: number | null;
  stale: number | null;
  maxOrderNotionalUsd: number | null;
  maxOrderNotionalMode: PhoenixOrderCapMode | null;
  maxOrderCollateralMult: number | null;
  maxOrderNotionalFixedUsd: number | null;
  maxOrderNotionalUnknown: boolean | null;
}
export type PhoenixOrderCapMode = 'off' | 'fixed' | 'collateral' | 'min';
const ORDER_CAP_MODES: readonly PhoenixOrderCapMode[] = ['off', 'fixed', 'collateral', 'min'];
function usdOrNull(v: unknown): number | null {
  if (typeof v === 'number') return Number.isFinite(v) && v >= 0 ? v : null;
  if (typeof v === 'string' && /^\d{1,15}(\.\d{1,6})?$/.test(v)) return Number(v);
  return null;
}
export function decodeSidecarHealth(body: unknown): SidecarHealthView | null {
  if (!body || typeof body !== 'object' || Array.isArray(body)) return null;
  const b = body as Record<string, unknown>;
  const s = (v: unknown): string | null => (typeof v === 'string' && v ? v : null);
  const n = (v: unknown): number | null => (typeof v === 'number' && Number.isInteger(v) ? v : null);
  let sol: bigint | null = null;
  if (typeof b.solLamports === 'string' && /^\d{1,20}$/.test(b.solLamports)) sol = BigInt(b.solLamports);
  let collateral: bigint | null = null;
  if (typeof b.collateralQuoteLots === 'string' && /^-?\d{1,19}$/.test(b.collateralQuoteLots))
    collateral = BigInt(b.collateralQuoteLots);
  const caps = b.capabilities as
    | {
        state?: unknown;
      }
    | null
    | undefined;
  const risk = b.keyRisk as
    | {
        warning?: unknown;
        positionAuthoritySwap?: unknown;
      }
    | null
    | undefined;
  return {
    pubkey: s(b.pubkey),
    authority: s(b.authority),
    traderPda: s(b.traderPda),
    traderPdaIndex: n(b.traderPdaIndex),
    subaccountIndex: n(b.subaccountIndex),
    readonly: b.readonly === true,
    signerLoaded: b.signerLoaded === true,
    bindingOk: b.bindingOk === true,
    bindingProblems: Array.isArray(b.bindingProblems)
      ? b.bindingProblems.filter((x): x is string => typeof x === 'string')
      : [],
    positionAuthority: s(b.positionAuthority),
    solLamports: sol,
    keyRiskWarning: s(risk?.warning),
    keyRiskSwap: s(risk?.positionAuthoritySwap),
    capabilitiesState: s(caps?.state),
    collateralQuoteLots: collateral,
    rpcOk: b.rpcOk === true,
    inflight: typeof b.inflight === 'number' && Number.isInteger(b.inflight) && b.inflight >= 0 ? b.inflight : null,
    stale: typeof b.stale === 'number' && Number.isInteger(b.stale) && b.stale >= 0 ? b.stale : null,
    maxOrderNotionalUsd: usdOrNull(b.maxOrderNotionalUsd),
    maxOrderNotionalMode: ORDER_CAP_MODES.includes(b.maxOrderNotionalMode as PhoenixOrderCapMode)
      ? (b.maxOrderNotionalMode as PhoenixOrderCapMode)
      : null,
    maxOrderCollateralMult:
      typeof b.maxOrderCollateralMult === 'number' &&
      Number.isFinite(b.maxOrderCollateralMult) &&
      b.maxOrderCollateralMult > 0
        ? b.maxOrderCollateralMult
        : null,
    maxOrderNotionalFixedUsd: usdOrNull(b.maxOrderNotionalFixedUsd),
    maxOrderNotionalUnknown: typeof b.maxOrderNotionalUnknown === 'boolean' ? b.maxOrderNotionalUnknown : null,
  };
}
All files