{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/logger.ts","../src/signer/node.ts","../src/errors.ts","../src/signer/core.ts","../src/constants.ts","../src/helpers.ts","../src/rest/nonce-manager.ts","../src/rest/client.ts","../src/ws/client.ts","../src/client.ts","../src/onboarding.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","/**\n * Injectable logger. The SDK never logs on its own — it routes through whatever the host app installs\n * via {@link setLogger}. The default is a no-op so the SDK is silent unless a logger is provided.\n *\n * This replaces the internal `Logger` dependency the code carried inside loky-backend; the SDK must not\n * pull in an application logging stack.\n */\nexport interface LighterLogger {\n    debug(message: string): void;\n    info(message: string): void;\n    warn(message: string): void;\n    error(message: string): void;\n}\n\nconst noopLogger: LighterLogger = {\n    debug: () => {},\n    info: () => {},\n    warn: () => {},\n    error: () => {},\n};\n\nlet activeLogger: LighterLogger = noopLogger;\n\n/** Install a logger (e.g. console, pino, winston). Pass nothing / a partial to reset to no-op. */\nexport function setLogger(logger: Partial<LighterLogger> | null | undefined): void {\n    if (!logger) {\n        activeLogger = noopLogger;\n        return;\n    }\n    activeLogger = {\n        debug: logger.debug ? logger.debug.bind(logger) : noopLogger.debug,\n        info: logger.info ? logger.info.bind(logger) : noopLogger.info,\n        warn: logger.warn ? logger.warn.bind(logger) : noopLogger.warn,\n        error: logger.error ? logger.error.bind(logger) : noopLogger.error,\n    };\n}\n\n/** Internal accessor used across the SDK. Always reads the currently-installed logger. */\nexport const Logger: LighterLogger = {\n    debug: (m) => activeLogger.debug(m),\n    info: (m) => activeLogger.info(m),\n    warn: (m) => activeLogger.warn(m),\n    error: (m) => activeLogger.error(m),\n};\n","import fs from \"fs\";\nimport path from \"path\";\nimport { createRequire } from \"module\";\nimport { _setSignerInstantiator, _resetSigner, finalizeExports, type LighterWasmExports } from \"./core\";\n\n/**\n * Node WASM loader for the signer. Reads `lighterSigner.wasm` + Go's `wasm_exec.js` from disk and\n * instantiates them in-process. Importing this module registers the loader (side effect), which is why the\n * Node aggregate `./signer` imports it. Browser bundles never import this file, so `fs`/`path`/`module`\n * stay out of the browser build.\n *\n * BUILD: `GOOS=js GOARCH=wasm go build -o lighterSigner.wasm ./wasm/` from lighter-go, then copy\n * `lighterSigner.wasm` and Go's runtime glue `wasm_exec.js` next to this file (see scripts/build-wasm.sh).\n * `scripts/copy-wasm.mjs` copies both into `dist/` during build.\n */\n\n/**\n * Directory holding `lighterSigner.wasm` + `wasm_exec.js`. Defaults to this module's own directory\n * (works for both `dist/` after build and `src/signer/` under test); a host that bundles the SDK — where\n * `__dirname` no longer points at the artifacts — can override it via `setSignerArtifactDir` or the\n * `LIGHTER_SIGNER_DIR` env var.\n */\nlet artifactDirOverride: string | null =\n    (typeof process !== \"undefined\" && process.env && process.env.LIGHTER_SIGNER_DIR) || null;\n\n/** Point the signer at the directory containing `lighterSigner.wasm` and `wasm_exec.js`. */\nexport function setSignerArtifactDir(dir: string): void {\n    artifactDirOverride = dir;\n    _resetSigner(); // force a reload so the next signing call picks up the new location.\n}\n\nfunction resolveArtifactDir(): string {\n    return artifactDirOverride || __dirname;\n}\n\nasync function nodeInstantiate(): Promise<LighterWasmExports> {\n    const dir = resolveArtifactDir();\n    const wasmFile = path.join(dir, \"lighterSigner.wasm\");\n    const wasmExecGlue = path.join(dir, \"wasm_exec.js\");\n    if (!fs.existsSync(wasmFile) || !fs.existsSync(wasmExecGlue)) {\n        throw new Error(\n            `LighterSigner::Signer artifacts missing. Expected ${wasmFile} and ${wasmExecGlue}. ` +\n                `Compile github.com/elliottech/lighter-go (wasm/ package) to WASM and place the artifacts there, ` +\n                `or point the SDK at them with setSignerArtifactDir()/LIGHTER_SIGNER_DIR.`,\n        );\n    }\n    // Go's wasm_exec.js runtime glue registers the global `Go` used to instantiate the module. It is a\n    // CommonJS script (it `require`s node's fs/crypto internally), so load it through a real CJS require\n    // built from this module's path — works from both the CJS and ESM builds.\n    const nodeRequire = createRequire(__filename);\n    nodeRequire(wasmExecGlue);\n    const GoRuntime = (globalThis as any).Go;\n    if (!GoRuntime) {\n        throw new Error(\"LighterSigner::Go WASM runtime glue did not register globalThis.Go\");\n    }\n    const go = new GoRuntime();\n    const bytes = fs.readFileSync(wasmFile);\n    const { instance } = await WebAssembly.instantiate(bytes, go.importObject);\n    // Do not await go.run — the Go program ends in `select {}` and stays resident to serve exports.\n    void go.run(instance);\n    // Give the runtime a tick to register its globals.\n    await new Promise((resolve) => setImmediate(resolve));\n    return finalizeExports(globalThis);\n}\n\n_setSignerInstantiator(nodeInstantiate);\n","/**\n * Typed error hierarchy so callers can branch on failure kind instead of string-matching messages.\n * All SDK errors extend {@link LighterError}.\n */\nexport class LighterError extends Error {\n    constructor(message: string) {\n        super(message);\n        this.name = new.target.name;\n        // Keep the prototype chain correct when targeting ES5-ish runtimes.\n        Object.setPrototypeOf(this, new.target.prototype);\n    }\n}\n\n/** A REST/API call failed: non-2xx HTTP, a non-200 `code`, or an unparseable body. */\nexport class LighterApiError extends LighterError {\n    constructor(\n        message: string,\n        /** The Lighter response `code`, if present. */\n        public readonly code?: number,\n        /** The HTTP status, if available. */\n        public readonly status?: number,\n        /** The failing method label (e.g. \"createLimitOrder\"). */\n        public readonly method?: string,\n    ) {\n        super(message);\n    }\n}\n\n/** The WASM signer rejected a request (bad params, out-of-range value, or an internal signer error). */\nexport class LighterSignerError extends LighterError {\n    constructor(message: string, public readonly method?: string) {\n        super(message);\n    }\n}\n\n/** Client-side validation failed before hitting the network (bad size, unknown symbol, missing config). */\nexport class LighterValidationError extends LighterError {}\n","import { Logger } from \"../logger\";\nimport { LighterSignerError } from \"../errors\";\n\n/**\n * Environment-neutral Lighter signing core.\n *\n * Lighter uses a ZK-rollup signature scheme (Poseidon hash over the Goldilocks field, Schnorr-style)\n * with no JavaScript implementation, so signing runs elliottech's official Go signer compiled to\n * WebAssembly. This module holds the ABI-level sign functions; loading the WASM is delegated to a\n * pluggable *instantiator* so the same signing code runs under Node (fs) and the browser (fetch).\n *\n * The Node aggregate `./signer` registers the fs instantiator on import; browser consumers call\n * `initLighterSigner` from `./signer/browser`. Both resolve to a {@link LighterWasmExports} of Go globals.\n */\n\n/** Auth context handed to the Go client (CreateClient) before each signing call. */\nexport interface LighterClientContext {\n    url: string;\n    /** 304 = zk mainnet, 300 = testnet, 466324 = robinhood mainnet. */\n    chainId: number;\n    apiPrivateKey: string;\n    accountIndex: number;\n    apiKeyIndex: number;\n}\n\nexport interface LighterCreateOrderInput {\n    marketIndex: number;\n    clientOrderIndex: number;\n    /** Base amount as an integer scaled by the market's size_decimals (uint48; must be 0..2^48-1). */\n    baseAmount: bigint | number;\n    /** Price as an integer scaled by the market's price_decimals (must fit uint32). 0 = unset. */\n    price: number;\n    isAsk: boolean;\n    orderType: number;\n    timeInForce: number;\n    reduceOnly: boolean;\n    triggerPrice?: number;\n    /** IOC/market orders must use 0 (NilOrderExpiry); GTT orders pass an epoch-ms expiry. */\n    orderExpiry: number;\n    /** Integrator (builder) fee routing; omit or 0 = Nil. Fee is a uint32 fraction of 1e6 (500 = 5 bps). */\n    integratorAccountIndex?: number;\n    integratorTakerFee?: number;\n    integratorMakerFee?: number;\n    nonce: number;\n}\n\nexport interface LighterCancelOrderInput {\n    marketIndex: number;\n    orderIndex: number;\n    nonce: number;\n}\n\nexport interface LighterModifyOrderInput {\n    marketIndex: number;\n    /** The order index (id) to modify. */\n    orderIndex: number;\n    /** New base amount, integer scaled by size_decimals. */\n    baseAmount: bigint | number;\n    /** New price, integer scaled by price_decimals (uint32). */\n    price: number;\n    /** New trigger price for stop/tp orders, integer scaled by price_decimals (0 if none). */\n    triggerPrice?: number;\n    nonce: number;\n}\n\nexport interface LighterUpdateLeverageInput {\n    marketIndex: number;\n    /** Integer initial-margin fraction (fraction/100 = margin%). */\n    fraction: number;\n    /** 0 = cross, 1 = isolated. */\n    marginMode: number;\n    nonce: number;\n}\n\n/** The signed transaction the REST client POSTs to /api/v1/sendTx. */\nexport interface LighterSignedTx {\n    txType: number;\n    txInfo: string;\n    txHash?: string;\n}\n\n/** base_amount is a uint48 field in the order tx; the Go signer rejects anything larger. 2^48 - 1. */\nconst MAX_BASE_AMOUNT = 281474976710655;\n\ntype WasmFn = (...args: any[]) => any;\nexport interface LighterWasmExports {\n    GenerateAPIKey: WasmFn;\n    CreateClient: WasmFn;\n    CreateAuthToken: WasmFn;\n    SignCreateOrder: WasmFn;\n    SignCancelOrder: WasmFn;\n    SignCancelAllOrders: WasmFn;\n    SignModifyOrder: WasmFn;\n    SignUpdateLeverage: WasmFn;\n    SignUpdateMargin: WasmFn;\n    SignWithdraw: WasmFn;\n    SignTransfer: WasmFn;\n    SignCreateGroupedOrders: WasmFn;\n    SignChangePubKey: WasmFn;\n    SignApproveIntegrator: WasmFn;\n}\n\n/** A function that loads/instantiates the WASM signer and returns its exported Go globals. */\nexport type SignerInstantiator = () => Promise<LighterWasmExports>;\n\nlet instantiator: SignerInstantiator | null = null;\nlet signerPromise: Promise<LighterWasmExports> | null = null;\n\n/** Register the environment-specific WASM loader. Resets any cached instance. Internal. */\nexport function _setSignerInstantiator(fn: SignerInstantiator): void {\n    instantiator = fn;\n    signerPromise = null;\n}\n\n/** Drop the cached signer instance so the next call re-instantiates. Internal. */\nexport function _resetSigner(): void {\n    signerPromise = null;\n}\n\n/**\n * Validate that the Go runtime registered the expected signer globals and snapshot them. Called by each\n * instantiator after `go.run(instance)` + a tick. `g` is the global object the WASM wrote onto.\n */\nexport function finalizeExports(g: any): LighterWasmExports {\n    if (typeof g.SignCreateOrder !== \"function\" || typeof g.CreateClient !== \"function\") {\n        throw new LighterSignerError(\"LighterSigner::WASM module did not register the expected signer globals\");\n    }\n    return {\n        GenerateAPIKey: g.GenerateAPIKey,\n        CreateClient: g.CreateClient,\n        CreateAuthToken: g.CreateAuthToken,\n        SignCreateOrder: g.SignCreateOrder,\n        SignCancelOrder: g.SignCancelOrder,\n        SignCancelAllOrders: g.SignCancelAllOrders,\n        SignModifyOrder: g.SignModifyOrder,\n        SignUpdateLeverage: g.SignUpdateLeverage,\n        SignUpdateMargin: g.SignUpdateMargin,\n        SignWithdraw: g.SignWithdraw,\n        SignTransfer: g.SignTransfer,\n        SignCreateGroupedOrders: g.SignCreateGroupedOrders,\n        SignChangePubKey: g.SignChangePubKey,\n        SignApproveIntegrator: g.SignApproveIntegrator,\n    };\n}\n\nasync function ensureSignerLoaded(): Promise<LighterWasmExports> {\n    if (!instantiator) {\n        throw new LighterSignerError(\n            \"LighterSigner::No signer loader registered. Import the SDK root (Node) or call initLighterSigner() \" +\n                \"from '@hitesh23k/lighter-sdk/browser' before signing.\",\n        );\n    }\n    if (!signerPromise) {\n        signerPromise = instantiator().catch((error) => {\n            signerPromise = null; // allow retry after a fixed deploy / re-init\n            throw error;\n        });\n    }\n    return signerPromise;\n}\n\n/** Register/refresh the Go client for this account+key+chain before signing. */\nfunction ensureClient(exports: LighterWasmExports, ctx: LighterClientContext): void {\n    const result = exports.CreateClient(ctx.url, ctx.apiPrivateKey, ctx.chainId, ctx.apiKeyIndex, ctx.accountIndex);\n    if (result && result.error) {\n        throw new LighterSignerError(`LighterSigner::CreateClient::${result.error}`);\n    }\n}\n\nfunction toSignedTx(result: any, methodName: string): LighterSignedTx {\n    if (!result || typeof result !== \"object\") {\n        throw new LighterSignerError(`LighterSigner::${methodName}::signer returned unexpected value: ${String(result)}`);\n    }\n    if (result.error) {\n        throw new LighterSignerError(`LighterSigner::${methodName}::${result.error}`);\n    }\n    if (typeof result.txType !== \"number\" || typeof result.txInfo !== \"string\") {\n        throw new LighterSignerError(`LighterSigner::${methodName}::signer returned unexpected shape: ${JSON.stringify(result)}`);\n    }\n    return { txType: result.txType, txInfo: result.txInfo, txHash: result.txHash };\n}\n\nfunction toSafeInt(value: bigint | number, field: string): number {\n    const n = typeof value === \"bigint\" ? Number(value) : value;\n    if (!Number.isSafeInteger(n)) {\n        throw new LighterSignerError(`LighterSigner::${field} exceeds safe integer range: ${value}`);\n    }\n    return n;\n}\n\n/**\n * Convert a scaled base amount to the number the WASM ABI expects, validating the uint48 field width the\n * signer enforces. Passing a string or BigInt to the WASM panics it, and a value above 2^48-1 is rejected\n * with an opaque error — so we surface a clear, actionable message here instead.\n */\nfunction toBaseAmountArg(value: bigint | number): number {\n    if (typeof value === \"bigint\") {\n        if (value < 0n || value > BigInt(MAX_BASE_AMOUNT)) {\n            throw new LighterSignerError(`LighterSigner::baseAmount out of range: ${value} (must be 0..${MAX_BASE_AMOUNT}, uint48)`);\n        }\n        return Number(value);\n    }\n    if (!Number.isInteger(value) || value < 0 || value > MAX_BASE_AMOUNT) {\n        throw new LighterSignerError(`LighterSigner::baseAmount out of range: ${value} (must be an integer 0..${MAX_BASE_AMOUNT}, uint48)`);\n    }\n    return value;\n}\n\nexport async function signCreateOrder(ctx: LighterClientContext, input: LighterCreateOrderInput): Promise<LighterSignedTx> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    Logger.debug(\n        `LighterSigner::signCreateOrder::account=${ctx.accountIndex}, market=${input.marketIndex}, isAsk=${input.isAsk}, nonce=${input.nonce}`,\n    );\n    // Positional ABI (19 args): marketIndex, clientOrderIndex, baseAmount, price, isAsk, orderType,\n    // timeInForce, reduceOnly, triggerPrice, orderExpiry, integratorAccountIndex, integratorTakerFee,\n    // integratorMakerFee, selfTradeBehaviorMode, selfTradeEqualityMode, skipNonce, nonce, apiKeyIndex, accountIndex.\n    const result = exports.SignCreateOrder(\n        input.marketIndex,\n        input.clientOrderIndex,\n        toBaseAmountArg(input.baseAmount),\n        input.price,\n        input.isAsk ? 1 : 0,\n        input.orderType,\n        input.timeInForce,\n        input.reduceOnly ? 1 : 0,\n        input.triggerPrice ?? 0,\n        input.orderExpiry,\n        input.integratorAccountIndex ?? 0, // integratorAccountIndex (0 = NilIntegratorIndex)\n        input.integratorTakerFee ?? 0, // integratorTakerFee (uint32 fraction of 1e6)\n        input.integratorMakerFee ?? 0, // integratorMakerFee (uint32 fraction of 1e6)\n        0, // selfTradeBehaviorMode (SelfTradeBehaviorExpireMaker)\n        0, // selfTradeEqualityMode (SelfTradeEqualityAccountIndex)\n        0, // skipNonce\n        input.nonce,\n        ctx.apiKeyIndex,\n        ctx.accountIndex,\n    );\n    return toSignedTx(result, \"signCreateOrder\");\n}\n\nexport interface LighterApiKeyPair {\n    privateKey: string;\n    publicKey: string;\n}\n\n/** Generate a fresh Ed25519 API keypair (for code-based provisioning; association still needs ChangePubKey). */\nexport async function generateApiKey(): Promise<LighterApiKeyPair> {\n    const exports = await ensureSignerLoaded();\n    const result = exports.GenerateAPIKey();\n    if (!result || result.error || typeof result.privateKey !== \"string\" || typeof result.publicKey !== \"string\") {\n        throw new LighterSignerError(`LighterSigner::generateApiKey::${result?.error || \"unexpected response\"}`);\n    }\n    return { privateKey: result.privateKey, publicKey: result.publicKey };\n}\n\nexport interface LighterChangePubKeyInput {\n    /** New API public key (hex) being registered at (accountIndex, apiKeyIndex). */\n    publicKey: string;\n    nonce: number;\n    /** Skip nonce handling (for a brand-new api_key_index whose nonce bootstraps at 0). */\n    skipNonce?: boolean;\n}\n\nexport interface LighterChangePubKeyResult {\n    txType: number;\n    /** Signed tx JSON: the L2 self-signature (`Sig`) is set; `L1Sig` is empty and filled by the account owner's wallet. */\n    txInfo: string;\n    txHash?: string;\n    /** The L1 message the account owner's EVM wallet must sign; its signature merges into `txInfo.L1Sig`. */\n    messageToSign: string;\n}\n\n/**\n * Produce the L2 self-signed ChangePubKey tx that registers a new API public key. `ctx.apiPrivateKey` MUST\n * be the NEW key's private key (the self-signature proves control of the new key). The returned `txInfo`\n * has an empty `L1Sig`; the account owner's wallet signs `messageToSign` and that signature is merged into\n * `L1Sig` before submitting to /sendTx (tx_type 8).\n */\nexport async function signChangePubKey(ctx: LighterClientContext, input: LighterChangePubKeyInput): Promise<LighterChangePubKeyResult> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    // Positional ABI (5 args): pubKeyHex, skipNonce, nonce, apiKeyIndex, accountIndex.\n    const result = exports.SignChangePubKey(\n        input.publicKey,\n        input.skipNonce ? 1 : 0,\n        input.nonce,\n        ctx.apiKeyIndex,\n        ctx.accountIndex,\n    );\n    if (!result || typeof result !== \"object\") {\n        throw new LighterSignerError(`LighterSigner::signChangePubKey::signer returned unexpected value: ${String(result)}`);\n    }\n    if (result.error) {\n        throw new LighterSignerError(`LighterSigner::signChangePubKey::${result.error}`);\n    }\n    if (typeof result.txType !== \"number\" || typeof result.txInfo !== \"string\" || typeof result.messageToSign !== \"string\") {\n        throw new LighterSignerError(`LighterSigner::signChangePubKey::signer returned unexpected shape: ${JSON.stringify(result)}`);\n    }\n    return { txType: result.txType, txInfo: result.txInfo, txHash: result.txHash, messageToSign: result.messageToSign };\n}\n\nexport interface LighterApproveIntegratorInput {\n    /** The integrator (partner) account_index that may collect fees on this account's orders. */\n    integratorAccountIndex: number;\n    /** Max perps taker fee the integrator may charge, as a uint32 fraction of 1e6 (500 = 5 bps). */\n    maxPerpsTakerFee: number;\n    maxPerpsMakerFee: number;\n    /** Max spot fees (set 0 for perps-only integrators). */\n    maxSpotTakerFee: number;\n    maxSpotMakerFee: number;\n    /** Absolute approval expiry in epoch MILLISECONDS (Lighter reads this field as ms, not seconds). */\n    approvalExpiryMs: number;\n    nonce: number;\n}\n\nexport interface LighterApproveIntegratorResult {\n    txType: number;\n    /** Signed tx JSON: the L2 `Sig` is set; `L1Sig` is empty and filled by the account owner's wallet. */\n    txInfo: string;\n    txHash?: string;\n    /** The L1 message the account owner's EVM wallet must personal_sign; merged into `txInfo.L1Sig`. */\n    messageToSign: string;\n}\n\n/**\n * Produce the L2-signed ApproveIntegrator tx (tx_type 45) authorising `integratorAccountIndex` to charge\n * up to the given max fees on this account's orders until `approvalExpiryMs`. The integrator account is a\n * different L1 than the user, so Lighter REQUIRES an L1 signature: the returned `txInfo` has an empty\n * `L1Sig`, and the account owner's wallet personal_signs `messageToSign`; that signature is merged into\n * `L1Sig` before submitting to /sendTx. `ctx.apiPrivateKey` is the user's custodial (registered) API key.\n */\nexport async function signApproveIntegrator(ctx: LighterClientContext, input: LighterApproveIntegratorInput): Promise<LighterApproveIntegratorResult> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    Logger.debug(\n        `LighterSigner::signApproveIntegrator::account=${ctx.accountIndex}, integrator=${input.integratorAccountIndex}, nonce=${input.nonce}`,\n    );\n    // Positional ABI (10 args): integratorIndex, maxPerpsTakerFee, maxPerpsMakerFee, maxSpotTakerFee,\n    // maxSpotMakerFee, approvalExpiry (ms), skipNonce, nonce, apiKeyIndex, accountIndex.\n    const result = exports.SignApproveIntegrator(\n        input.integratorAccountIndex,\n        input.maxPerpsTakerFee,\n        input.maxPerpsMakerFee,\n        input.maxSpotTakerFee,\n        input.maxSpotMakerFee,\n        toSafeInt(input.approvalExpiryMs, \"approvalExpiryMs\"),\n        0, // skipNonce\n        input.nonce,\n        ctx.apiKeyIndex,\n        ctx.accountIndex,\n    );\n    if (!result || typeof result !== \"object\") {\n        throw new LighterSignerError(`LighterSigner::signApproveIntegrator::signer returned unexpected value: ${String(result)}`);\n    }\n    if (result.error) {\n        throw new LighterSignerError(`LighterSigner::signApproveIntegrator::${result.error}`);\n    }\n    if (typeof result.txType !== \"number\" || typeof result.txInfo !== \"string\" || typeof result.messageToSign !== \"string\") {\n        throw new LighterSignerError(`LighterSigner::signApproveIntegrator::signer returned unexpected shape: ${JSON.stringify(result)}`);\n    }\n    return { txType: result.txType, txInfo: result.txInfo, txHash: result.txHash, messageToSign: result.messageToSign };\n}\n\nexport async function signModifyOrder(ctx: LighterClientContext, input: LighterModifyOrderInput): Promise<LighterSignedTx> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    Logger.debug(`LighterSigner::signModifyOrder::account=${ctx.accountIndex}, market=${input.marketIndex}, orderIndex=${input.orderIndex}, nonce=${input.nonce}`);\n    // Positional ABI (14 args): marketIndex, index, baseAmount, price, triggerPrice,\n    // integratorAccountIndex, integratorTakerFee, integratorMakerFee, selfTradeBehaviorMode,\n    // selfTradeEqualityMode, skipNonce, nonce, apiKeyIndex, accountIndex.\n    const result = exports.SignModifyOrder(\n        input.marketIndex,\n        input.orderIndex,\n        toBaseAmountArg(input.baseAmount),\n        input.price,\n        input.triggerPrice ?? 0,\n        0, // integratorAccountIndex (Nil)\n        0, // integratorTakerFee (Nil)\n        0, // integratorMakerFee (Nil)\n        0, // selfTradeBehaviorMode\n        0, // selfTradeEqualityMode\n        0, // skipNonce\n        input.nonce,\n        ctx.apiKeyIndex,\n        ctx.accountIndex,\n    );\n    return toSignedTx(result, \"signModifyOrder\");\n}\n\nexport async function signUpdateLeverage(ctx: LighterClientContext, input: LighterUpdateLeverageInput): Promise<LighterSignedTx> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    Logger.debug(`LighterSigner::signUpdateLeverage::account=${ctx.accountIndex}, market=${input.marketIndex}, fraction=${input.fraction}, marginMode=${input.marginMode}`);\n    // ABI (7 args): marketIndex, fraction, marginMode, skipNonce, nonce, apiKeyIndex, accountIndex.\n    const result = exports.SignUpdateLeverage(\n        input.marketIndex,\n        input.fraction,\n        input.marginMode,\n        0, // skipNonce\n        input.nonce,\n        ctx.apiKeyIndex,\n        ctx.accountIndex,\n    );\n    return toSignedTx(result, \"signUpdateLeverage\");\n}\n\n/** Mint a short-lived auth token for account-scoped GET reads (trades, fundings, …). */\nexport async function createAuthToken(ctx: LighterClientContext, deadlineUnixSec = 0): Promise<string> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    // ABI (3 args): deadline, apiKeyIndex, accountIndex. deadline=0 → default (~7h).\n    const result = exports.CreateAuthToken(deadlineUnixSec, ctx.apiKeyIndex, ctx.accountIndex);\n    if (!result || result.error || typeof result.authToken !== \"string\") {\n        throw new LighterSignerError(`LighterSigner::createAuthToken::${result?.error || \"unexpected response\"}`);\n    }\n    return result.authToken;\n}\n\nexport async function signCancelOrder(ctx: LighterClientContext, input: LighterCancelOrderInput): Promise<LighterSignedTx> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    Logger.debug(`LighterSigner::signCancelOrder::account=${ctx.accountIndex}, market=${input.marketIndex}, orderIndex=${input.orderIndex}`);\n    // Positional ABI (6 args): marketIndex, orderIndex, skipNonce, nonce, apiKeyIndex, accountIndex.\n    const result = exports.SignCancelOrder(\n        input.marketIndex,\n        input.orderIndex,\n        0, // skipNonce\n        input.nonce,\n        ctx.apiKeyIndex,\n        ctx.accountIndex,\n    );\n    return toSignedTx(result, \"signCancelOrder\");\n}\n\nexport interface LighterCancelAllOrdersInput {\n    /** 0 = immediate, 1 = scheduled (at `time`), 2 = abort a scheduled cancel. Default immediate. */\n    timeInForce?: number;\n    /** Epoch-ms trigger for a scheduled cancel (timeInForce 1); 0/omitted for immediate. */\n    time?: number;\n    /** Market index to cancel, or 255 for ALL markets (the signer rejects other out-of-range values). */\n    marketIndex: number;\n    nonce: number;\n}\n\n/**\n * Sign an atomic CancelAllOrders tx (tx_type 16) — cancels every resting order (marketIndex 255) or all\n * orders in one market, in a single transaction. Preferred over cancelling order-by-order: one nonce, one\n * round trip, and no window for fills between per-order cancels.\n */\nexport async function signCancelAllOrders(ctx: LighterClientContext, input: LighterCancelAllOrdersInput): Promise<LighterSignedTx> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    Logger.debug(`LighterSigner::signCancelAllOrders::account=${ctx.accountIndex}, market=${input.marketIndex}, tif=${input.timeInForce ?? 0}`);\n    // Positional ABI (7 args): timeInForce, time, cancelAllMarketIndex, skipNonce, nonce, apiKeyIndex, accountIndex.\n    const result = exports.SignCancelAllOrders(\n        input.timeInForce ?? 0,\n        toSafeInt(input.time ?? 0, \"time\"),\n        input.marketIndex,\n        0, // skipNonce\n        input.nonce,\n        ctx.apiKeyIndex,\n        ctx.accountIndex,\n    );\n    return toSignedTx(result, \"signCancelAllOrders\");\n}\n\nexport interface LighterUpdateMarginInput {\n    marketIndex: number;\n    /** USDC amount as an integer scaled to USDC decimals. */\n    usdcAmount: bigint | number;\n    /** 0 = add margin (isolated), 1 = remove margin. */\n    direction: number;\n    nonce: number;\n}\n\n/** Sign an add/remove isolated-margin tx (tx_type 29) for a market. */\nexport async function signUpdateMargin(ctx: LighterClientContext, input: LighterUpdateMarginInput): Promise<LighterSignedTx> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    Logger.debug(`LighterSigner::signUpdateMargin::account=${ctx.accountIndex}, market=${input.marketIndex}, direction=${input.direction}`);\n    // ABI (7 args): marketIndex, usdcAmount, direction, skipNonce, nonce, apiKeyIndex, accountIndex.\n    const result = exports.SignUpdateMargin(\n        input.marketIndex,\n        toSafeInt(input.usdcAmount, \"usdcAmount\"),\n        input.direction,\n        0, // skipNonce\n        input.nonce,\n        ctx.apiKeyIndex,\n        ctx.accountIndex,\n    );\n    return toSignedTx(result, \"signUpdateMargin\");\n}\n\nexport interface LighterWithdrawInput {\n    /** Asset index (1-based; USDC = 1). Defaults to 1. */\n    assetIndex?: number;\n    /** 0 = standard, 1 = fast. Defaults to 0. */\n    routeType?: number;\n    /** Amount as an integer scaled to the asset's decimals (uint64). */\n    amount: bigint | number;\n    nonce: number;\n}\n\n/** Sign a withdrawal tx (tx_type 13) moving funds out of the L2 account to the L1 owner. */\nexport async function signWithdraw(ctx: LighterClientContext, input: LighterWithdrawInput): Promise<LighterSignedTx> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    Logger.debug(`LighterSigner::signWithdraw::account=${ctx.accountIndex}, asset=${input.assetIndex ?? 1}, amount=${input.amount}`);\n    // ABI (7 args): assetIndex, routeType, amount, skipNonce, nonce, apiKeyIndex, accountIndex.\n    const result = exports.SignWithdraw(\n        input.assetIndex ?? 1,\n        input.routeType ?? 0,\n        toSafeInt(input.amount, \"amount\"),\n        0, // skipNonce\n        input.nonce,\n        ctx.apiKeyIndex,\n        ctx.accountIndex,\n    );\n    return toSignedTx(result, \"signWithdraw\");\n}\n\nexport interface LighterTransferInput {\n    toAccountIndex: number;\n    /** Asset index (1-based; USDC = 1). Defaults to 1. */\n    assetIndex?: number;\n    fromRouteType?: number;\n    toRouteType?: number;\n    /** Amount as an integer scaled to the asset's decimals. */\n    amount: bigint | number;\n    /** USDC fee (scaled). Defaults to 0. */\n    usdcFee?: bigint | number;\n    /** 32-byte memo as hex (64 hex chars, or 66 with `0x`). Defaults to a zero memo. */\n    memo?: string;\n    nonce: number;\n}\n\n/** Sign a transfer tx (tx_type 12) moving funds to another Lighter account. */\nexport async function signTransfer(ctx: LighterClientContext, input: LighterTransferInput): Promise<LighterSignedTx> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    Logger.debug(`LighterSigner::signTransfer::account=${ctx.accountIndex}, to=${input.toAccountIndex}, amount=${input.amount}`);\n    // ABI (11 args): toAccountIndex, assetIndex, fromRouteType, toRouteType, amount, usdcFee, memo,\n    // skipNonce, nonce, apiKeyIndex, accountIndex.\n    const result = exports.SignTransfer(\n        input.toAccountIndex,\n        input.assetIndex ?? 1,\n        input.fromRouteType ?? 0,\n        input.toRouteType ?? 0,\n        toSafeInt(input.amount, \"amount\"),\n        toSafeInt(input.usdcFee ?? 0, \"usdcFee\"),\n        input.memo ?? \"0x\" + \"00\".repeat(32),\n        0, // skipNonce\n        input.nonce,\n        ctx.apiKeyIndex,\n        ctx.accountIndex,\n    );\n    return toSignedTx(result, \"signTransfer\");\n}\n\n/** One leg of a grouped order. Trigger/child legs (TP/SL) use baseAmount 0 (they close the main fill). */\nexport interface LighterGroupedOrder {\n    marketIndex: number;\n    clientOrderIndex: number;\n    /** Integer scaled by size_decimals (uint48). 0 for TP/SL legs in an OTOCO bracket. */\n    baseAmount: bigint | number;\n    /** Integer scaled by price_decimals (uint32). Worst-case bound for market/trigger legs. */\n    price: number;\n    isAsk: boolean;\n    orderType: number;\n    timeInForce: number;\n    reduceOnly: boolean;\n    triggerPrice?: number;\n    orderExpiry: number;\n}\n\nexport interface LighterCreateGroupedOrdersInput {\n    /** LighterConstant.GROUPING_TYPE: OTO (1), OCO (2), or OTOCO (3, a bracket). */\n    groupingType: number;\n    orders: LighterGroupedOrder[];\n    integratorAccountIndex?: number;\n    integratorTakerFee?: number;\n    integratorMakerFee?: number;\n    nonce: number;\n}\n\n/**\n * Sign a grouped-orders tx (tx_type 28) — OTO/OCO/OTOCO. The OTOCO form is a bracket: a main entry order\n * plus reduce-only take-profit and stop-loss legs (their baseAmount is 0; they close whatever the main fills).\n */\nexport async function signCreateGroupedOrders(ctx: LighterClientContext, input: LighterCreateGroupedOrdersInput): Promise<LighterSignedTx> {\n    const exports = await ensureSignerLoaded();\n    ensureClient(exports, ctx);\n    Logger.debug(`LighterSigner::signCreateGroupedOrders::account=${ctx.accountIndex}, grouping=${input.groupingType}, legs=${input.orders.length}`);\n    // The WASM expects an array of PascalCase order objects; marshal + validate each base amount (uint48).\n    const orders = input.orders.map((o) => ({\n        MarketIndex: o.marketIndex,\n        ClientOrderIndex: o.clientOrderIndex,\n        BaseAmount: toBaseAmountArg(o.baseAmount),\n        Price: o.price,\n        IsAsk: o.isAsk ? 1 : 0,\n        Type: o.orderType,\n        TimeInForce: o.timeInForce,\n        ReduceOnly: o.reduceOnly ? 1 : 0,\n        TriggerPrice: o.triggerPrice ?? 0,\n        OrderExpiry: o.orderExpiry,\n    }));\n    // ABI (11 args): groupingType, orders[], integratorAccountIndex, integratorTakerFee, integratorMakerFee,\n    // selfTradeBehaviorMode, selfTradeEqualityMode, skipNonce, nonce, apiKeyIndex, accountIndex.\n    const result = exports.SignCreateGroupedOrders(\n        input.groupingType,\n        orders,\n        input.integratorAccountIndex ?? 0,\n        input.integratorTakerFee ?? 0,\n        input.integratorMakerFee ?? 0,\n        0, // selfTradeBehaviorMode\n        0, // selfTradeEqualityMode\n        0, // skipNonce\n        input.nonce,\n        ctx.apiKeyIndex,\n        ctx.accountIndex,\n    );\n    return toSignedTx(result, \"signCreateGroupedOrders\");\n}\n","/**\n * Static Lighter protocol constants: venues, hosts, signer chain ids, endpoint paths, and the\n * enum codes used across the order/leverage/tx APIs. Product-neutral — no integrator/partner accounts\n * are baked in; a builder (integrator) fee is supplied per-client by the caller (see LighterRestClient).\n */\nexport default class LighterConstant {\n    public static readonly NETWORK = \"lighter\";\n\n    /** Chain ids passed to the Go signer's CreateClient. */\n    public static readonly CHAIN_ID_MAINNET = 304;\n    public static readonly CHAIN_ID_TESTNET = 300;\n\n    /**\n     * Perp venues. The zk-Lighter L2 (USDC) and the Robinhood-Chain Lighter instance (USDG) are separate\n     * Lighter deployments: same signing scheme and REST shapes, but a different host, signer chainId, and\n     * account namespace (a user's account_index on one is unrelated to the other).\n     */\n    public static readonly VENUE = {\n        ZK: \"zk\",\n        ROBINHOOD: \"robinhood\",\n    } as const;\n\n    /**\n     * Host + signer chainId per venue. Robinhood-Chain Lighter mainnet signs with chainId 466324\n     * (NOT 4663 — that is Robinhood Chain's Ethereum L2 id, a different number).\n     */\n    public static readonly VENUE_CONFIG = {\n        zk: {\n            mainnetBaseUrl: \"https://mainnet.zklighter.elliot.ai\",\n            testnetBaseUrl: \"https://testnet.zklighter.elliot.ai\",\n            chainIdMainnet: 304,\n            chainIdTestnet: 300,\n        },\n        robinhood: {\n            mainnetBaseUrl: \"https://api.rh.lighter.xyz\",\n            testnetBaseUrl: \"https://api.rh-testnet.lighter.xyz\",\n            chainIdMainnet: 466324,\n            chainIdTestnet: 300,\n        },\n    } as const;\n\n    /** Resolve base URL + signer chainId for a venue and network. */\n    public static resolveVenue(venue: string, isMainnet: boolean): { baseUrl: string; chainId: number } {\n        const map = LighterConstant.VENUE_CONFIG as Record<\n            string,\n            { mainnetBaseUrl: string; testnetBaseUrl: string; chainIdMainnet: number; chainIdTestnet: number }\n        >;\n        const cfg = map[venue];\n        if (!cfg) {\n            // Fail loud rather than silently signing/routing an unknown venue against the zk host+chainId.\n            throw new Error(`LighterConstant::resolveVenue::Unknown Lighter venue \"${venue}\"`);\n        }\n        return {\n            baseUrl: isMainnet ? cfg.mainnetBaseUrl : cfg.testnetBaseUrl,\n            chainId: isMainnet ? cfg.chainIdMainnet : cfg.chainIdTestnet,\n        };\n    }\n\n    /** API-key indexes {0,1,2,3} are reserved by Lighter for desktop/mobile; programmatic keys start at 4. */\n    public static readonly RESERVED_API_KEY_INDEX_MAX = 3;\n\n    /** api_key_index is a uint8 in the signer ABI, so the usable programmatic range is 4..255. */\n    public static readonly MAX_API_KEY_INDEX = 255;\n\n    public static readonly ENDPOINTS = {\n        status: \"/api/v1/status\",\n        tokenlist: \"/api/v1/tokenlist\",\n        orderBooks: \"/api/v1/orderBooks\",\n        orderBookDetails: \"/api/v1/orderBookDetails\",\n        account: \"/api/v1/account\",\n        accountsByL1Address: \"/api/v1/accountsByL1Address\",\n        apikeys: \"/api/v1/apikeys\",\n        accountLimits: \"/api/v1/accountLimits\",\n        accountActiveOrders: \"/api/v1/accountActiveOrders\",\n        accountInactiveOrders: \"/api/v1/accountInactiveOrders\",\n        positionFunding: \"/api/v1/positionFunding\",\n        pnl: \"/api/v1/pnl\",\n        trades: \"/api/v1/trades\",\n        recentTrades: \"/api/v1/recentTrades\",\n        fundings: \"/api/v1/fundings\",\n        fundingRates: \"/api/v1/funding-rates\",\n        candles: \"/api/v1/candles\",\n        markPriceCandles: \"/api/v1/markPriceCandles\",\n        nextNonce: \"/api/v1/nextNonce\",\n        transaction: \"/api/v1/transaction\",\n        sendTx: \"/api/v1/sendTx\",\n        sendTxBatch: \"/api/v1/sendTxBatch\",\n    } as const;\n\n    /**\n     * uint8 transaction-type codes for POST /sendTx. The WASM signer returns the txType alongside\n     * the signed txInfo, so these are informational/fallback — confirm exact values against\n     * `github.com/elliottech/lighter-go` constants before relying on them directly.\n     */\n    public static readonly TX_TYPE = {\n        changePubKey: 8,\n        transfer: 12,\n        withdraw: 13,\n        createOrder: 14,\n        cancelOrder: 15,\n        cancelAllOrders: 16,\n        modifyOrder: 17,\n        updateLeverage: 20,\n        createGroupedOrders: 28,\n        updateMargin: 29,\n        approveIntegrator: 45,\n    } as const;\n\n    /** Grouped-order strategies for SignCreateGroupedOrders (verified against the signer). */\n    public static readonly GROUPING_TYPE = {\n        /** One-Triggers-Other: a main order that, once filled, activates a second (2 orders). */\n        OTO: 1,\n        /** One-Cancels-Other: two equal-size orders; filling one cancels the other (2 orders). */\n        OCO: 2,\n        /** One-Triggers-A-One-Cancels-Other (bracket): main entry + TP + SL (3 orders). */\n        OTOCO: 3,\n    } as const;\n\n    /** SignUpdateMargin direction. */\n    public static readonly MARGIN_DIRECTION = {\n        ADD: 0,\n        REMOVE: 1,\n    } as const;\n\n    /** Withdraw/transfer route types (0 = standard/slow, 1 = fast). */\n    public static readonly ROUTE_TYPE = {\n        STANDARD: 0,\n        FAST: 1,\n    } as const;\n\n    /** USDC asset index (asset indices are 1-based; the signer rejects 0). */\n    public static readonly ASSET_INDEX_USDC = 1;\n\n    /** A zero 32-byte transfer memo (the signer requires a 32-byte hex memo). */\n    public static readonly ZERO_MEMO = \"0x\" + \"00\".repeat(32);\n\n    /** A reasonable default ApproveIntegrator validity window (epoch MS). The user re-approves after this. */\n    public static readonly INTEGRATOR_APPROVAL_TTL_MS = 365 * 24 * 60 * 60 * 1000;\n\n    /** Lighter order-type codes (verified against elliottech/lighter-python SignerClient). */\n    public static readonly ORDER_TYPE = {\n        LIMIT: 0,\n        MARKET: 1,\n        STOP_LOSS: 2,\n        STOP_LOSS_LIMIT: 3,\n        TAKE_PROFIT: 4,\n        TAKE_PROFIT_LIMIT: 5,\n        TWAP: 6,\n    } as const;\n\n    /** Lighter time-in-force codes (verified against elliottech/lighter-python SignerClient). */\n    public static readonly TIME_IN_FORCE = {\n        IMMEDIATE_OR_CANCEL: 0,\n        GOOD_TILL_TIME: 1,\n        POST_ONLY: 2,\n    } as const;\n\n    /** Lighter uses `is_ask`: true = sell/short leg, false = buy/long leg. */\n    public static readonly IS_ASK = {\n        SHORT: true,\n        LONG: false,\n    } as const;\n\n    /** Margin modes for SignUpdateLeverage. */\n    public static readonly MARGIN_MODE = {\n        CROSS: 0,\n        ISOLATED: 1,\n    } as const;\n\n    /** client_order_index is a uint48 in the order tx; must stay below 2^48. */\n    public static readonly MAX_CLIENT_ORDER_INDEX = 281474976710655;\n\n    /** base_amount is a uint48 in the order tx (the WASM signer rejects larger values). 2^48 - 1. */\n    public static readonly MAX_BASE_AMOUNT = 281474976710655;\n\n    /** SignCancelAllOrders market index sentinel: 255 = cancel across all markets (verified against the signer). */\n    public static readonly CANCEL_ALL_MARKETS = 255;\n\n    /** SignCancelAllOrders time-in-force: 0 = immediate, 1 = scheduled (at `time`), 2 = abort a scheduled cancel. */\n    public static readonly CANCEL_ALL_TIME_IN_FORCE = {\n        IMMEDIATE: 0,\n        SCHEDULED: 1,\n        ABORT: 2,\n    } as const;\n\n    /**\n     * Initial-margin-fraction scale: an integer `fraction` maps to margin% = fraction/100, so\n     * leverage = 10000 / fraction (e.g. 500 → 5.00% → 20x). 1x = 10000 (the upper bound).\n     */\n    public static readonly MARGIN_FRACTION_SCALE = 10000;\n\n    /** Funding is paid hourly on Lighter perps. */\n    public static readonly FUNDING_INTERVAL_SECONDS = 3600;\n\n    /** Integrator (builder) fee is a uint32 fraction of this tick: 500 = 5 bps. Lighter caps perps at 10 bps. */\n    public static readonly INTEGRATOR_FEE_TICK = 1_000_000;\n}\n","import LighterConstant from \"./constants\";\n\n/**\n * Pure, dependency-free helpers for Lighter's fixed-point encoding and URL building. Lighter encodes\n * base amounts with a market's `size_decimals` and prices with its `price_decimals`; these convert\n * between human decimals and the scaled integers the signer/API expect.\n */\nexport default class LighterHelper {\n    public static toQueryString(params: Record<string, unknown>): string {\n        const searchParams = new URLSearchParams();\n        Object.entries(params).forEach(([key, value]) => {\n            if (value !== undefined && value !== null && value !== \"\") {\n                searchParams.append(key, String(value));\n            }\n        });\n        return searchParams.toString();\n    }\n\n    public static buildUrl(baseUrl: string, endpoint: string, query?: Record<string, unknown>): string {\n        const normalizedBase = baseUrl.endsWith(\"/\") ? baseUrl.slice(0, -1) : baseUrl;\n        const normalizedEndpoint = endpoint.startsWith(\"/\") ? endpoint : `/${endpoint}`;\n        const queryString = query ? LighterHelper.toQueryString(query) : \"\";\n        return queryString ? `${normalizedBase}${normalizedEndpoint}?${queryString}` : `${normalizedBase}${normalizedEndpoint}`;\n    }\n\n    /**\n     * Scale a decimal value to Lighter's integer representation (floor extra precision).\n     * Lighter base amounts use `size_decimals` and prices use `price_decimals`.\n     */\n    public static scaleToInt(value: number | string, decimals: number): bigint {\n        const s = String(value).trim();\n        const neg = s.startsWith(\"-\");\n        const unsigned = neg ? s.slice(1) : s;\n        const [intPartRaw, fracRaw = \"\"] = unsigned.split(\".\");\n        const intPart = intPartRaw || \"0\";\n        const fracPart = fracRaw.padEnd(decimals, \"0\").slice(0, decimals); // floor extra precision\n        const scaled = BigInt(intPart) * 10n ** BigInt(decimals) + BigInt(fracPart || \"0\");\n        return neg ? -scaled : scaled;\n    }\n\n    public static toBaseAmount(size: number | string, sizeDecimals: number): bigint {\n        return LighterHelper.scaleToInt(size, sizeDecimals);\n    }\n\n    public static toPriceInt(price: number | string, priceDecimals: number): bigint {\n        return LighterHelper.scaleToInt(price, priceDecimals);\n    }\n\n    /** Floor `value` to the nearest multiple of `step` (both integers already scaled to the same decimals). */\n    public static floorToStep(value: bigint, step: bigint): bigint {\n        if (step <= 0n) return value;\n        return (value / step) * step;\n    }\n\n    /** Convert a scaled integer back to a human-readable decimal string. */\n    public static fromScaledInt(value: bigint, decimals: number): string {\n        const negative = value < 0n;\n        const abs = negative ? -value : value;\n        const base = 10n ** BigInt(decimals);\n        const integer = abs / base;\n        const fraction = abs % base;\n        const fracStr = fraction.toString().padStart(decimals, \"0\").replace(/0+$/, \"\");\n        return `${negative ? \"-\" : \"\"}${integer.toString()}${fracStr ? \".\" + fracStr : \"\"}`;\n    }\n\n    /**\n     * Convert a target leverage to Lighter's integer initial-margin fraction.\n     * leverage = SCALE / fraction, so fraction = round(SCALE / leverage). Clamped to\n     * [minFraction, SCALE] — `minFraction` (the market's min_initial_margin_fraction) caps leverage,\n     * SCALE (=10000) is 1x.\n     */\n    public static leverageToMarginFraction(leverage: number, minFraction?: number): number {\n        const scale = LighterConstant.MARGIN_FRACTION_SCALE;\n        const raw = Math.round(scale / Math.max(1, leverage));\n        const floor = minFraction && minFraction > 0 ? minFraction : 1;\n        return Math.min(scale, Math.max(floor, raw));\n    }\n}\n","/**\n * Per-(account:apiKey) nonce sequencer for Lighter's signed write path.\n *\n * Lighter transactions from one api key must carry strictly increasing, contiguous nonces, and the\n * sequencer rejects reuse. Fetching `nextNonce` per call and signing races under any concurrency: two\n * overlapping writes both read the same server nonce and one is silently rejected. This serializes\n * sign+send per key, advances a local nonce only on success, and resyncs from the server on any failure\n * (so a non-nonce error doesn't leave a permanent gap).\n */\nexport default class NonceManager {\n    /** Next nonce to use per key; absent = must (re)fetch from the server. */\n    private next: Map<string, number> = new Map();\n    /** Tail of the per-key serialization chain (never rejects — errors surface via the returned promise). */\n    private tail: Map<string, Promise<unknown>> = new Map();\n\n    constructor(private readonly fetchNext: (accountIndex: number, apiKeyIndex: number) => Promise<number>) {}\n\n    private key(accountIndex: number, apiKeyIndex: number): string {\n        return `${accountIndex}:${apiKeyIndex}`;\n    }\n\n    /**\n     * Run `fn(nonce)` (which must sign AND send the tx) under an exclusive, correctly-sequenced nonce for\n     * this key. Calls are serialized: a second concurrent write waits for the first to finish, guaranteeing\n     * distinct increasing nonces. The local nonce advances only when `fn` resolves; on rejection it is\n     * cleared so the next call refetches from the server.\n     */\n    public async withNonce<T>(accountIndex: number, apiKeyIndex: number, fn: (nonce: number) => Promise<T>): Promise<T> {\n        const key = this.key(accountIndex, apiKeyIndex);\n        const prior = this.tail.get(key) ?? Promise.resolve();\n        const run = prior.then(async () => {\n            let nonce = this.next.get(key);\n            if (nonce === undefined) {\n                nonce = await this.fetchNext(accountIndex, apiKeyIndex);\n            }\n            try {\n                const result = await fn(nonce);\n                this.next.set(key, nonce + 1); // advance only after a successful send\n                return result;\n            } catch (error) {\n                this.next.delete(key); // resync from the server on the next call\n                throw error;\n            }\n        });\n        // The lock chain must never reject, or it would poison every subsequent call for this key.\n        this.tail.set(key, run.then(() => undefined, () => undefined));\n        return run;\n    }\n\n    /** Force a resync (drop the local nonce) for a key — e.g. after an out-of-band nonce error. */\n    public resync(accountIndex: number, apiKeyIndex: number): void {\n        this.next.delete(this.key(accountIndex, apiKeyIndex));\n    }\n}\n","import { Logger } from \"../logger\";\nimport LighterConstant from \"../constants\";\nimport LighterHelper from \"../helpers\";\n// Import the pure sign functions from core (NOT the Node aggregate) so the REST client carries no fs\n// loader — the loader is registered by whichever entry is used (Node index, or initLighterSigner in browser).\nimport {\n    signCreateOrder,\n    signCancelOrder,\n    signCancelAllOrders,\n    signModifyOrder,\n    signUpdateLeverage,\n    signUpdateMargin,\n    signWithdraw,\n    signTransfer,\n    signCreateGroupedOrders,\n    signApproveIntegrator,\n    createAuthToken,\n    type LighterClientContext,\n    type LighterGroupedOrder,\n} from \"../signer/core\";\nimport NonceManager from \"./nonce-manager\";\nimport { LighterApiError } from \"../errors\";\nimport {\n    LighterRestClientConfig,\n    LighterIntegratorConfig,\n    LighterSignerContext,\n    LighterOrderBookDetail,\n    LighterOrderBookDetailsResponse,\n    LighterFundingRate,\n    LighterFundingRatesResponse,\n    LighterAccount,\n    LighterAccountResponse,\n    LighterNextNonceResponse,\n    LighterSendTxResponse,\n    LighterTrade,\n    LighterPositionFunding,\n    LighterTokenListItem,\n    LighterCandlesResponse,\n    LighterCreateMarketOrderParams,\n    LighterCreateLimitOrderParams,\n    LighterActiveOrder,\n    LighterApiKeyEntry,\n    LighterPosition,\n} from \"../types\";\n\n/**\n * REST client for a single Lighter venue (zk or robinhood) + network. Covers the public read endpoints,\n * account-scoped authed reads, and the signed write path (/sendTx). Signing is delegated to the WASM\n * signer; the caller passes a {@link LighterSignerContext} (decrypted API key + account/key indices) per\n * write call, so the client holds no secrets.\n */\nexport default class LighterRestClient {\n    private readonly baseUrl: string;\n    private readonly chainId: number;\n    private readonly venue: string;\n    private readonly isMainnet: boolean;\n    private readonly integrator: LighterIntegratorConfig | null;\n    /** Cached auth tokens per account+key; refreshed before expiry. */\n    private authTokenCache: Map<string, { token: string; expiresAtMs: number }> = new Map();\n    private static readonly AUTH_TOKEN_TTL_MS = 6 * 60 * 60 * 1000; // refresh well before the ~7h server deadline\n    /** Serializes signed writes per account+key and sequences their nonces (see NonceManager). */\n    private readonly nonces: NonceManager;\n\n    constructor(config: LighterRestClientConfig = {}) {\n        const venue = config.venue || LighterConstant.VENUE.ZK;\n        const isMainnet = config.isMainnet !== false; // default mainnet\n        const resolved = LighterConstant.resolveVenue(venue, isMainnet);\n        // baseUrl override is honoured (rare); the signer chainId always comes from the venue + network.\n        this.baseUrl = config.baseUrl || resolved.baseUrl;\n        this.chainId = resolved.chainId;\n        this.venue = venue;\n        this.isMainnet = isMainnet;\n        this.integrator = config.integrator || null;\n        this.nonces = new NonceManager((accountIndex, apiKeyIndex) => this.getNextNonce(accountIndex, apiKeyIndex));\n    }\n\n    private clientContext(ctx: LighterSignerContext): LighterClientContext {\n        return {\n            url: this.baseUrl,\n            chainId: this.chainId,\n            apiPrivateKey: ctx.apiPrivateKey,\n            accountIndex: ctx.accountIndex,\n            apiKeyIndex: ctx.apiKeyIndex,\n        };\n    }\n\n    private async authToken(ctx: LighterSignerContext): Promise<string> {\n        const key = `${ctx.accountIndex}:${ctx.apiKeyIndex}`;\n        const cached = this.authTokenCache.get(key);\n        if (cached && cached.expiresAtMs > Date.now()) {\n            return cached.token;\n        }\n        const token = await createAuthToken(this.clientContext(ctx));\n        this.authTokenCache.set(key, { token, expiresAtMs: Date.now() + LighterRestClient.AUTH_TOKEN_TTL_MS });\n        return token;\n    }\n\n    // ==================== READ PATH (no signer) ====================\n\n    public async getOrderBookDetails(): Promise<LighterOrderBookDetail[]> {\n        const res = await this.getJson<LighterOrderBookDetailsResponse>(\n            \"getOrderBookDetails\",\n            LighterConstant.ENDPOINTS.orderBookDetails,\n        );\n        return res.order_book_details || [];\n    }\n\n    /** Full token list incl. asset_type (CRYPTO/RWA) and categories. Public, no auth. */\n    public async getTokenList(): Promise<LighterTokenListItem[]> {\n        const res = await this.getJson<{ code?: number; tokens: LighterTokenListItem[] }>(\n            \"getTokenList\",\n            LighterConstant.ENDPOINTS.tokenlist,\n        );\n        return res.tokens || [];\n    }\n\n    /**\n     * Funding rates. The `/funding-rates` endpoint AGGREGATES several venues (binance, bybit, hyperliquid,\n     * lighter), so this defaults to Lighter's own rows only — otherwise a naive `find(symbol)` can return\n     * another exchange's rate. Pass `{ exchange: null }` for the raw aggregated set, or another venue name.\n     */\n    public async getFundingRates(options: { exchange?: string | null } = {}): Promise<LighterFundingRate[]> {\n        const res = await this.getJson<LighterFundingRatesResponse>(\n            \"getFundingRates\",\n            LighterConstant.ENDPOINTS.fundingRates,\n        );\n        const rows = res.funding_rates || [];\n        const exchange = options.exchange === undefined ? LighterConstant.NETWORK : options.exchange;\n        if (exchange === null) return rows;\n        return rows.filter((r) => String(r.exchange || \"\").toLowerCase() === String(exchange).toLowerCase());\n    }\n\n    /** Raw aggregated funding rates across ALL venues (binance/bybit/hyperliquid/lighter). */\n    public async getAllFundingRates(): Promise<LighterFundingRate[]> {\n        return this.getFundingRates({ exchange: null });\n    }\n\n    public async getAccount(accountIndex: number): Promise<LighterAccount | null> {\n        const res = await this.getJson<LighterAccountResponse>(\n            \"getAccount\",\n            LighterConstant.ENDPOINTS.account,\n            { by: \"index\", value: accountIndex },\n        );\n        return res.account || res.accounts?.[0] || null;\n    }\n\n    public async getAccountsByL1Address(l1Address: string): Promise<LighterAccount[]> {\n        // The endpoint returns `sub_accounts` (whose id field is `index`, not `account_index`); `accounts`\n        // is a defensive fallback. Case-insensitive on the L1 address.\n        const res = await this.getJson<LighterAccountResponse & { sub_accounts?: LighterAccount[] }>(\n            \"getAccountsByL1Address\",\n            LighterConstant.ENDPOINTS.accountsByL1Address,\n            { l1_address: l1Address },\n        );\n        return res.sub_accounts || res.accounts || [];\n    }\n\n    /**\n     * The account's registered API keys. `api_key_index=255` returns all slots. Used to pick a free\n     * programmatic slot (>= 4). Public read (returns public keys, no secrets).\n     */\n    public async getApiKeys(accountIndex: number): Promise<LighterApiKeyEntry[]> {\n        const res = await this.getJson<{ code?: number; api_keys?: LighterApiKeyEntry[]; apikeys?: LighterApiKeyEntry[] }>(\n            \"getApiKeys\",\n            LighterConstant.ENDPOINTS.apikeys,\n            { account_index: accountIndex, api_key_index: 255 },\n        );\n        return res.api_keys || res.apikeys || [];\n    }\n\n    public async getPositions(accountIndex: number): Promise<LighterPosition[]> {\n        const account = await this.getAccount(accountIndex);\n        return account?.positions || [];\n    }\n\n    /** Account-scoped fills. Requires auth (minted per account+key and cached). */\n    public async getAccountTrades(\n        ctx: LighterSignerContext,\n        params: { marketId?: number; limit?: number; orderIndex?: number } = {},\n    ): Promise<LighterTrade[]> {\n        const token = await this.authToken(ctx);\n        const query: Record<string, unknown> = {\n            sort_by: \"timestamp\",\n            sort_dir: \"desc\",\n            limit: params.limit ?? 50,\n            account_index: ctx.accountIndex,\n            type: \"trade\",\n        };\n        if (params.marketId !== undefined) query.market_id = params.marketId;\n        if (params.orderIndex !== undefined) query.order_index = params.orderIndex;\n        const res = await this.getJsonAuthed<{ code?: number; trades: LighterTrade[] }>(\n            \"getAccountTrades\",\n            LighterConstant.ENDPOINTS.trades,\n            token,\n            query,\n        );\n        return res.trades || [];\n    }\n\n    /**\n     * Resting (active) orders for an account. Requires auth. `marketId` defaults to all markets.\n     * Used to resolve a user-facing order id -> `order_index` (+ market) for cancel/modify, and to\n     * enumerate orders for a cancel-all.\n     */\n    public async getActiveOrders(\n        ctx: LighterSignerContext,\n        params: { marketId?: number } = {},\n    ): Promise<LighterActiveOrder[]> {\n        const token = await this.authToken(ctx);\n        const query: Record<string, unknown> = { account_index: ctx.accountIndex };\n        if (params.marketId !== undefined) query.market_id = params.marketId;\n        const res = await this.getJsonAuthed<{ code?: number; orders?: LighterActiveOrder[]; active_orders?: LighterActiveOrder[] }>(\n            \"getActiveOrders\",\n            LighterConstant.ENDPOINTS.accountActiveOrders,\n            token,\n            query,\n        );\n        return res.orders || res.active_orders || [];\n    }\n\n    /**\n     * VERIFY ON-CHAIN that the account has approved the configured integrator. Lighter exposes NO read API\n     * for integrator approvals (not in accountLimits/account, no dedicated endpoint), so we PROBE: attempt a\n     * tiny far-from-market resting limit carrying the integrator fee. Lighter rejects it with \"integrator is\n     * not approved\" for an unapproved / insufficient-max-fee / expired account, and accepts it otherwise\n     * (Lighter itself checks the approved account, max fee and expiry). On acceptance we immediately cancel\n     * the canary and return true. Non-integrator errors are rethrown (indeterminate).\n     */\n    public async probeIntegratorApproved(ctx: LighterSignerContext): Promise<boolean> {\n        if (!this.integrator) {\n            throw new Error(\"Lighter integrator is not configured for this client\");\n        }\n        const details = await this.getOrderBookDetails();\n        const market = details.find((d) => String(d.symbol || \"\").toUpperCase() === \"BTC\") || details[0];\n        if (!market) throw new Error(\"No market available to probe integrator approval\");\n\n        const baseAmount = LighterHelper.toBaseAmount(Number(market.min_base_amount), market.size_decimals);\n        // Far below mid so the canary rests without filling; carries the integrator fee so Lighter validates approval.\n        const price = Number(LighterHelper.toPriceInt(Number(market.last_trade_price) * 0.5, market.price_decimals));\n        const clientOrderIndex = (Date.now() * 1000) % LighterConstant.MAX_CLIENT_ORDER_INDEX;\n\n        try {\n            await this.createLimitOrder(ctx, {\n                marketIndex: market.market_id,\n                baseAmount,\n                price,\n                isAsk: false,\n                clientOrderIndex,\n                timeInForce: \"gtc\",\n                applyIntegratorFee: true,\n            });\n        } catch (error: any) {\n            if (/integrator is not approved|integrator.*not.*approv/i.test(String(error?.message || \"\"))) return false;\n            throw error;\n        }\n\n        // Accepted => approved. Best-effort cancel the resting canary.\n        try {\n            const active = await this.getActiveOrders(ctx, { marketId: market.market_id });\n            const canary = active.find((o) => String(o.client_order_index) === String(clientOrderIndex));\n            if (canary && Number.isFinite(Number(canary.order_index))) {\n                await this.cancelOrder(ctx, {\n                    marketIndex: Number(canary.market_index ?? canary.market_id ?? market.market_id),\n                    orderIndex: Number(canary.order_index),\n                });\n            }\n        } catch (cleanupError: any) {\n            Logger.warn(`LighterRestClient::probeIntegratorApproved::canary cleanup failed: ${cleanupError?.message}`);\n        }\n        return true;\n    }\n\n    /** An account's realized funding payments per position. Requires auth. */\n    public async getPositionFunding(\n        ctx: LighterSignerContext,\n        params: { marketId?: number; limit?: number; startTimestamp?: number; endTimestamp?: number } = {},\n    ): Promise<LighterPositionFunding[]> {\n        const token = await this.authToken(ctx);\n        const query: Record<string, unknown> = {\n            account_index: ctx.accountIndex,\n            limit: params.limit ?? 100,\n        };\n        if (params.marketId !== undefined) query.market_id = params.marketId;\n        if (params.startTimestamp !== undefined) query.start_timestamp = params.startTimestamp;\n        if (params.endTimestamp !== undefined) query.end_timestamp = params.endTimestamp;\n        const res = await this.getJsonAuthed<{ code?: number; position_fundings: LighterPositionFunding[] }>(\n            \"getPositionFunding\",\n            LighterConstant.ENDPOINTS.positionFunding,\n            token,\n            query,\n        );\n        return res.position_fundings || [];\n    }\n\n    /**\n     * OHLCV candles. All of market_id, resolution, start/end_timestamp (ms) and count_back are\n     * required by the API. Response: { code, r, c: [{ t,o,h,l,c,v,V,i }] } (max 500 per call).\n     */\n    public async getCandles(params: {\n        market_id: number;\n        resolution: string;\n        start_timestamp: number;\n        end_timestamp: number;\n        count_back: number;\n        set_timestamp_to_end?: boolean;\n    }): Promise<LighterCandlesResponse> {\n        return this.getJson<LighterCandlesResponse>(\"getCandles\", LighterConstant.ENDPOINTS.candles, params);\n    }\n\n    /**\n     * Mark-price OHLCV candles. Mark price (not last trade) drives margin and liquidation, so use these for\n     * risk math. Same required params as {@link getCandles}.\n     */\n    public async getMarkPriceCandles(params: {\n        market_id: number;\n        resolution: string;\n        start_timestamp: number;\n        end_timestamp: number;\n        count_back: number;\n        set_timestamp_to_end?: boolean;\n    }): Promise<LighterCandlesResponse> {\n        return this.getJson<LighterCandlesResponse>(\"getMarkPriceCandles\", LighterConstant.ENDPOINTS.markPriceCandles, params);\n    }\n\n    /** Full order books (levels) for all markets, or one market when `marketId` is given. */\n    public async getOrderBooks(marketId?: number): Promise<any> {\n        return this.getJson<any>(\n            \"getOrderBooks\",\n            LighterConstant.ENDPOINTS.orderBooks,\n            marketId !== undefined ? { market_id: marketId } : undefined,\n        );\n    }\n\n    /** Public recent trades for a market (no auth). */\n    public async getRecentTrades(marketId: number, limit = 100): Promise<LighterTrade[]> {\n        const res = await this.getJson<{ code?: number; trades?: LighterTrade[] }>(\n            \"getRecentTrades\",\n            LighterConstant.ENDPOINTS.recentTrades,\n            { market_id: marketId, limit },\n        );\n        return res.trades || [];\n    }\n\n    /** Account tier + trading limits (rate/volume/size caps). Requires auth (account-scoped). */\n    public async getAccountLimits(ctx: LighterSignerContext): Promise<any> {\n        const token = await this.authToken(ctx);\n        return this.getJsonAuthed<any>(\"getAccountLimits\", LighterConstant.ENDPOINTS.accountLimits, token, {\n            account_index: ctx.accountIndex,\n        });\n    }\n\n    /**\n     * Closed / historical (inactive) orders for an account — needed for reconciliation. Requires auth.\n     * `marketId` defaults to all markets.\n     */\n    public async getInactiveOrders(\n        ctx: LighterSignerContext,\n        params: { marketId?: number; limit?: number } = {},\n    ): Promise<LighterActiveOrder[]> {\n        const token = await this.authToken(ctx);\n        const query: Record<string, unknown> = { account_index: ctx.accountIndex, limit: params.limit ?? 100 };\n        if (params.marketId !== undefined) query.market_id = params.marketId;\n        const res = await this.getJsonAuthed<{ code?: number; orders?: LighterActiveOrder[] }>(\n            \"getInactiveOrders\",\n            LighterConstant.ENDPOINTS.accountInactiveOrders,\n            token,\n            query,\n        );\n        return res.orders || [];\n    }\n\n    public async getNextNonce(accountIndex: number, apiKeyIndex: number): Promise<number> {\n        const res = await this.getJson<LighterNextNonceResponse>(\n            \"getNextNonce\",\n            LighterConstant.ENDPOINTS.nextNonce,\n            { account_index: accountIndex, api_key_index: apiKeyIndex },\n        );\n        return res.nonce;\n    }\n\n    /** Look up a transaction by hash. Response shape is passthrough (includes a `status`). */\n    public async getTransaction(hash: string): Promise<any> {\n        return this.getJson<any>(\"getTransaction\", LighterConstant.ENDPOINTS.transaction, { by: \"hash\", value: hash });\n    }\n\n    /**\n     * Poll a transaction by hash until it reaches a terminal state (executed/committed or failed/rejected)\n     * or `timeoutMs` elapses. Returns the final transaction object. Statuses are matched case-insensitively.\n     */\n    public async waitForTransaction(\n        hash: string,\n        opts: { timeoutMs?: number; intervalMs?: number } = {},\n    ): Promise<any> {\n        const timeoutMs = opts.timeoutMs ?? 30000;\n        const intervalMs = opts.intervalMs ?? 1000;\n        const deadline = Date.now() + timeoutMs;\n        const terminal = /^(executed|committed|failed|rejected)$/i;\n        let last: any = null;\n        while (Date.now() < deadline) {\n            try {\n                const res = await this.getTransaction(hash);\n                last = res?.transaction ?? res;\n                const status = String(last?.status ?? \"\");\n                if (terminal.test(status)) return last;\n            } catch (err) {\n                // transient (tx not yet indexed) — keep polling until the deadline\n                last = last ?? { error: (err as Error)?.message };\n            }\n            await new Promise((r) => setTimeout(r, intervalMs));\n        }\n        throw new LighterApiError(`waitForTransaction::timed out after ${timeoutMs}ms for ${hash}`, undefined, undefined, \"waitForTransaction\");\n    }\n\n    // ==================== WRITE PATH (signer) ====================\n\n    /**\n     * Integrator (builder) fee params for the signer. Only attached when the caller opts in\n     * (`applyIntegratorFee`) AND an integrator is configured on this client.\n     */\n    private integratorInput(applyIntegratorFee?: boolean): {\n        integratorAccountIndex?: number;\n        integratorTakerFee?: number;\n        integratorMakerFee?: number;\n    } {\n        if (!applyIntegratorFee || !this.integrator) return {};\n        return {\n            integratorAccountIndex: this.integrator.accountIndex,\n            integratorTakerFee: this.integrator.takerFee,\n            integratorMakerFee: this.integrator.makerFee,\n        };\n    }\n\n    public async createMarketOrder(\n        ctx: LighterSignerContext,\n        params: LighterCreateMarketOrderParams,\n    ): Promise<LighterSendTxResponse> {\n        // A Lighter market order is an IOC limit that fills up to a worst-case price bound. price 0 means a\n        // buy can never fill (limit 0) and a sell has NO slippage protection — so a bound is required.\n        const price = params.price !== undefined ? Number(params.price) : 0;\n        if (!Number.isFinite(price) || price <= 0) {\n            throw new Error(\n                \"LighterRestClient::createMarketOrder::a positive worst-case price bound is required (integer scaled by price_decimals); use the high-level client's slippage, or pass params.price\",\n            );\n        }\n        return this.nonces.withNonce(ctx.accountIndex, ctx.apiKeyIndex, async (nonce) => {\n            const signed = await signCreateOrder(this.clientContext(ctx), {\n                marketIndex: params.marketIndex,\n                clientOrderIndex: params.clientOrderIndex,\n                baseAmount: params.baseAmount,\n                price,\n                isAsk: params.isAsk,\n                orderType: LighterConstant.ORDER_TYPE.MARKET,\n                timeInForce: LighterConstant.TIME_IN_FORCE.IMMEDIATE_OR_CANCEL,\n                reduceOnly: params.reduceOnly,\n                orderExpiry: 0, // IOC/market orders require NilOrderExpiry (0)\n                ...this.integratorInput(params.applyIntegratorFee),\n                nonce,\n            });\n            return this.sendTx(\"createMarketOrder\", signed.txType, signed.txInfo);\n        });\n    }\n\n    /**\n     * Place a resting LIMIT order. `timeInForce`/`postOnly` map to Lighter's TIF:\n     * ioc -> IMMEDIATE_OR_CANCEL (expiry 0), alo/postOnly -> POST_ONLY, gtc (default) -> GOOD_TILL_TIME.\n     * GTT orders require a non-nil expiry; -1 lets the signer set 28 days (Lighter's max resting life).\n     */\n    public async createLimitOrder(\n        ctx: LighterSignerContext,\n        params: LighterCreateLimitOrderParams,\n    ): Promise<LighterSendTxResponse> {\n        const isIoc = params.timeInForce === \"ioc\";\n        const isPostOnly = params.postOnly === true || params.timeInForce === \"alo\";\n        const timeInForce = isIoc\n            ? LighterConstant.TIME_IN_FORCE.IMMEDIATE_OR_CANCEL\n            : isPostOnly\n                ? LighterConstant.TIME_IN_FORCE.POST_ONLY\n                : LighterConstant.TIME_IN_FORCE.GOOD_TILL_TIME;\n        return this.nonces.withNonce(ctx.accountIndex, ctx.apiKeyIndex, async (nonce) => {\n            const signed = await signCreateOrder(this.clientContext(ctx), {\n                marketIndex: params.marketIndex,\n                clientOrderIndex: params.clientOrderIndex,\n                baseAmount: params.baseAmount,\n                price: Number(params.price),\n                isAsk: params.isAsk,\n                orderType: LighterConstant.ORDER_TYPE.LIMIT,\n                timeInForce,\n                reduceOnly: Boolean(params.reduceOnly),\n                orderExpiry: isIoc ? 0 : -1, // IOC uses NilOrderExpiry; resting orders get the signer's 28d max\n                ...this.integratorInput(params.applyIntegratorFee),\n                nonce,\n            });\n            return this.sendTx(\"createLimitOrder\", signed.txType, signed.txInfo);\n        });\n    }\n\n    /**\n     * Place a reduce-only TAKE_PROFIT or STOP_LOSS trigger order (native TP/SL for a single-leg position).\n     * Lighter requires: perps market, IOC, a non-nil trigger price and a non-nil expiry (we pass -1 → 28d),\n     * and price >= 1 (worst-case execution bound).\n     */\n    public async createTriggerOrder(\n        ctx: LighterSignerContext,\n        params: {\n            marketIndex: number;\n            baseAmount: bigint | number;\n            isAsk: boolean;\n            /** ORDER_TYPE.TAKE_PROFIT or ORDER_TYPE.STOP_LOSS. */\n            orderType: number;\n            /** Trigger price, integer scaled by price_decimals (uint32). */\n            triggerPrice: number;\n            /** Worst-case execution price bound, integer scaled by price_decimals (uint32, >= 1). */\n            price: number;\n            clientOrderIndex: number;\n            /** Attach the configured integrator (builder) fee — only for accounts that have approved. */\n            applyIntegratorFee?: boolean;\n        },\n    ): Promise<LighterSendTxResponse> {\n        return this.nonces.withNonce(ctx.accountIndex, ctx.apiKeyIndex, async (nonce) => {\n            const signed = await signCreateOrder(this.clientContext(ctx), {\n                marketIndex: params.marketIndex,\n                clientOrderIndex: params.clientOrderIndex,\n                baseAmount: params.baseAmount,\n                price: params.price,\n                isAsk: params.isAsk,\n                orderType: params.orderType,\n                timeInForce: LighterConstant.TIME_IN_FORCE.IMMEDIATE_OR_CANCEL,\n                reduceOnly: true,\n                triggerPrice: params.triggerPrice,\n                orderExpiry: -1, // trigger orders require a non-nil expiry; -1 → signer sets 28 days (max)\n                ...this.integratorInput(params.applyIntegratorFee),\n                nonce,\n            });\n            return this.sendTx(\"createTriggerOrder\", signed.txType, signed.txInfo);\n        });\n    }\n\n    /** Set per-market leverage. `leverage` is converted to Lighter's margin fraction (clamped by min). */\n    public async updateLeverage(\n        ctx: LighterSignerContext,\n        params: { marketIndex: number; leverage: number; marginMode?: number; minFraction?: number },\n    ): Promise<LighterSendTxResponse> {\n        const fraction = LighterHelper.leverageToMarginFraction(params.leverage, params.minFraction);\n        return this.nonces.withNonce(ctx.accountIndex, ctx.apiKeyIndex, async (nonce) => {\n            const signed = await signUpdateLeverage(this.clientContext(ctx), {\n                marketIndex: params.marketIndex,\n                fraction,\n                marginMode: params.marginMode ?? LighterConstant.MARGIN_MODE.CROSS,\n                nonce,\n            });\n            return this.sendTx(\"updateLeverage\", signed.txType, signed.txInfo);\n        });\n    }\n\n    public async cancelOrder(\n        ctx: LighterSignerContext,\n        params: { marketIndex: number; orderIndex: number },\n    ): Promise<LighterSendTxResponse> {\n        return this.nonces.withNonce(ctx.accountIndex, ctx.apiKeyIndex, async (nonce) => {\n            const signed = await signCancelOrder(this.clientContext(ctx), {\n                marketIndex: params.marketIndex,\n                orderIndex: params.orderIndex,\n                nonce,\n            });\n            return this.sendTx(\"cancelOrder\", signed.txType, signed.txInfo);\n        });\n    }\n\n    /**\n     * Atomically cancel every resting order (marketIndex 255 = all markets, the default) or all orders in a\n     * single market, in ONE tx (tx_type 16). Preferred over cancelling order-by-order — one nonce, one round\n     * trip, no window for fills between per-order cancels.\n     */\n    public async cancelAllOrders(\n        ctx: LighterSignerContext,\n        params: { marketIndex?: number; timeInForce?: number; time?: number } = {},\n    ): Promise<LighterSendTxResponse> {\n        return this.nonces.withNonce(ctx.accountIndex, ctx.apiKeyIndex, async (nonce) => {\n            const signed = await signCancelAllOrders(this.clientContext(ctx), {\n                marketIndex: params.marketIndex ?? LighterConstant.CANCEL_ALL_MARKETS,\n                timeInForce: params.timeInForce,\n                time: params.time,\n                nonce,\n            });\n            return this.sendTx(\"cancelAllOrders\", signed.txType, signed.txInfo);\n        });\n    }\n\n    /** Modify a resting order's size/price/trigger. */\n    public async modifyOrder(\n        ctx: LighterSignerContext,\n        params: { marketIndex: number; orderIndex: number; baseAmount: bigint | number; price: number; triggerPrice?: number },\n    ): Promise<LighterSendTxResponse> {\n        return this.nonces.withNonce(ctx.accountIndex, ctx.apiKeyIndex, async (nonce) => {\n            const signed = await signModifyOrder(this.clientContext(ctx), {\n                marketIndex: params.marketIndex,\n                orderIndex: params.orderIndex,\n                baseAmount: params.baseAmount,\n                price: params.price,\n                triggerPrice: params.triggerPrice,\n                nonce,\n            });\n            return this.sendTx(\"modifyOrder\", signed.txType, signed.txInfo);\n        });\n    }\n\n    /** Add or remove isolated margin on a market (tx 29). `usdcAmount` is scaled to USDC decimals. */\n    public async updateMargin(\n        ctx: LighterSignerContext,\n        params: { marketIndex: number; usdcAmount: bigint | number; direction: number },\n    ): Promise<LighterSendTxResponse> {\n        return this.nonces.withNonce(ctx.accountIndex, ctx.apiKeyIndex, async (nonce) => {\n            const signed = await signUpdateMargin(this.clientContext(ctx), {\n                marketIndex: params.marketIndex,\n                usdcAmount: params.usdcAmount,\n                direction: params.direction,\n                nonce,\n            });\n            return this.sendTx(\"updateMargin\", signed.txType, signed.txInfo);\n        });\n    }\n\n    /** Withdraw funds from the L2 account back to the L1 owner (tx 13). `amount` scaled to asset decimals. */\n    public async withdraw(\n        ctx: LighterSignerContext,\n        params: { amount: bigint | number; assetIndex?: number; routeType?: number },\n    ): Promise<LighterSendTxResponse> {\n        return this.nonces.withNonce(ctx.accountIndex, ctx.apiKeyIndex, async (nonce) => {\n            const signed = await signWithdraw(this.clientContext(ctx), {\n                amount: params.amount,\n                assetIndex: params.assetIndex,\n                routeType: params.routeType,\n                nonce,\n            });\n            return this.sendTx(\"withdraw\", signed.txType, signed.txInfo);\n        });\n    }\n\n    /**\n     * Transfer funds to another Lighter account (tx 12). `amount` scaled to asset decimals.\n     *\n     * ADVANCED: a transfer additionally requires the account owner's L1 (EVM) signature merged into the tx's\n     * `L1Sig` field — the L2 signature alone is rejected (\"fail to l1 signature\"). This method signs only the\n     * L2 part; the caller is responsible for constructing + merging the L1 signature per Lighter's transfer\n     * message spec before it will be accepted. Withdrawals do NOT need this.\n     */\n    public async transfer(\n        ctx: LighterSignerContext,\n        params: { toAccountIndex: number; amount: bigint | number; assetIndex?: number; usdcFee?: bigint | number; memo?: string },\n    ): Promise<LighterSendTxResponse> {\n        return this.nonces.withNonce(ctx.accountIndex, ctx.apiKeyIndex, async (nonce) => {\n            const signed = await signTransfer(this.clientContext(ctx), {\n                toAccountIndex: params.toAccountIndex,\n                amount: params.amount,\n                assetIndex: params.assetIndex,\n                usdcFee: params.usdcFee,\n                memo: params.memo,\n                nonce,\n            });\n            return this.sendTx(\"transfer\", signed.txType, signed.txInfo);\n        });\n    }\n\n    /**\n     * Submit a grouped order (tx 28): OTO / OCO / OTOCO (bracket). Orders are pre-scaled legs; use the\n     * high-level client's `placeBracketOrder` for a human-unit API.\n     */\n    public async createGroupedOrders(\n        ctx: LighterSignerContext,\n        params: { groupingType: number; orders: LighterGroupedOrder[]; applyIntegratorFee?: boolean },\n    ): Promise<LighterSendTxResponse> {\n        return this.nonces.withNonce(ctx.accountIndex, ctx.apiKeyIndex, async (nonce) => {\n            const signed = await signCreateGroupedOrders(this.clientContext(ctx), {\n                groupingType: params.groupingType,\n                orders: params.orders,\n                ...this.integratorInput(params.applyIntegratorFee),\n                nonce,\n            });\n            return this.sendTx(\"createGroupedOrders\", signed.txType, signed.txInfo);\n        });\n    }\n\n    /**\n     * Submit a fully-signed ChangePubKey tx (tx_type 8) whose txInfo already has both the L2 self-signature\n     * and the merged-in L1 signature. Used to bind a new API key on-chain.\n     */\n    public async sendChangePubKey(txType: number, txInfo: string): Promise<LighterSendTxResponse> {\n        return this.sendTx(\"sendChangePubKey\", txType, txInfo);\n    }\n\n    /**\n     * L2-sign an ApproveIntegrator (tx_type 45) authorising this client's configured integrator account to\n     * charge up to its fee on the account's orders, until now+TTL (ms). The returned `txInfo` has an empty\n     * `L1Sig`; the account owner's wallet personal_signs `messageToSign` and that signature is spliced into\n     * `L1Sig` before `sendApproveIntegrator`. `nonce` is returned so the caller can persist it (the signed\n     * nonce is part of the L1 message, so it cannot be changed after the user signs).\n     */\n    public async buildApproveIntegrator(\n        ctx: LighterSignerContext,\n        approvalExpiryMs: number,\n    ): Promise<{ txType: number; txInfo: string; messageToSign: string; nonce: number; integratorAccountIndex: number }> {\n        if (!this.integrator) {\n            throw new Error(\"Lighter integrator is not configured for this client\");\n        }\n        const nonce = await this.getNextNonce(ctx.accountIndex, ctx.apiKeyIndex);\n        const signed = await signApproveIntegrator(this.clientContext(ctx), {\n            integratorAccountIndex: this.integrator.accountIndex,\n            maxPerpsTakerFee: this.integrator.takerFee,\n            maxPerpsMakerFee: this.integrator.makerFee,\n            maxSpotTakerFee: 0,\n            maxSpotMakerFee: 0,\n            approvalExpiryMs,\n            nonce,\n        });\n        return { txType: signed.txType, txInfo: signed.txInfo, messageToSign: signed.messageToSign, nonce, integratorAccountIndex: this.integrator.accountIndex };\n    }\n\n    /** Submit the ApproveIntegrator tx (L1Sig already merged in) to /sendTx. */\n    public async sendApproveIntegrator(txType: number, txInfo: string): Promise<LighterSendTxResponse> {\n        return this.sendTx(\"sendApproveIntegrator\", txType, txInfo);\n    }\n\n    private async sendTx(methodName: string, txType: number, txInfo: string): Promise<LighterSendTxResponse> {\n        const url = LighterHelper.buildUrl(this.baseUrl, LighterConstant.ENDPOINTS.sendTx);\n        const form = new URLSearchParams();\n        form.append(\"tx_type\", String(txType));\n        form.append(\"tx_info\", txInfo);\n        Logger.debug(`LighterRestClient::sendTx::method=${methodName}, txType=${txType}`);\n        const response = await fetch(url, {\n            method: \"POST\",\n            headers: { \"Content-Type\": \"application/x-www-form-urlencoded\", Accept: \"application/json\" },\n            body: form.toString(),\n        });\n        const rawText = await response.text();\n        let parsed: LighterSendTxResponse | null = null;\n        if (rawText) {\n            try {\n                parsed = JSON.parse(rawText) as LighterSendTxResponse;\n            } catch {\n                throw new LighterApiError(`LighterRestClient::${methodName}::non-JSON response: ${rawText}`, undefined, response.status, methodName);\n            }\n        }\n        if (!response.ok || !parsed || (parsed.code !== undefined && parsed.code !== 200)) {\n            const message = parsed?.message || rawText || `Lighter sendTx failed with status ${response.status}`;\n            Logger.error(`LighterRestClient::${methodName}::${message}`);\n            throw new LighterApiError(String(message), parsed?.code, response.status, methodName);\n        }\n        return parsed;\n    }\n\n    private async getJsonAuthed<T extends { code?: number; message?: string }>(\n        methodName: string,\n        endpoint: string,\n        token: string,\n        query?: Record<string, unknown>,\n    ): Promise<T> {\n        return this.getJson<T>(methodName, endpoint, query, { Authorization: token });\n    }\n\n    private async getJson<T extends { code?: number; message?: string }>(\n        methodName: string,\n        endpoint: string,\n        query?: Record<string, unknown>,\n        headers?: Record<string, string>,\n    ): Promise<T> {\n        const url = LighterHelper.buildUrl(this.baseUrl, endpoint, query);\n        Logger.debug(`LighterRestClient::request::url=${url}`);\n        const response = await fetch(url, { method: \"GET\", headers: { Accept: \"application/json\", ...(headers || {}) } });\n        const rawText = await response.text();\n        let parsed: T | null = null;\n        if (rawText) {\n            try {\n                parsed = JSON.parse(rawText) as T;\n            } catch {\n                throw new LighterApiError(`LighterRestClient::${methodName}::non-JSON response: ${rawText}`, undefined, response.status, methodName);\n            }\n        }\n        if (!response.ok || !parsed || (parsed.code !== undefined && parsed.code !== 200)) {\n            const message = parsed?.message || rawText || `Lighter request failed with status ${response.status}`;\n            Logger.error(`LighterRestClient::${methodName}::${message}`);\n            throw new LighterApiError(String(message), parsed?.code, response.status, methodName);\n        }\n        return parsed;\n    }\n}\n","import { Logger } from \"../logger\";\nimport LighterConstant from \"../constants\";\nimport {\n    LighterWsConfig,\n    LighterWsMessage,\n    LighterWsEvent,\n    LighterWsHandler,\n    LighterChannelHandler,\n    WebSocketCtor,\n    WebSocketLike,\n    Unsubscribe,\n} from \"./types\";\n\n// WebSocket.readyState OPEN is 1 in both the browser and the `ws` package.\nconst WS_OPEN = 1;\n\n/** Resolve a WebSocket constructor: caller-injected → global (browser / Node >= 22) → optional `ws` package. */\nasync function resolveWebSocketCtor(inject?: WebSocketCtor): Promise<WebSocketCtor> {\n    if (inject) return inject;\n    const g = globalThis as any;\n    if (typeof g.WebSocket !== \"undefined\") return g.WebSocket as WebSocketCtor;\n    try {\n        // Indirect specifier so this stays a runtime-only optional dependency (not statically resolved by\n        // the type checker or bundled). `ws` is declared under optionalDependencies.\n        const wsModuleName = \"ws\";\n        const mod: any = await import(wsModuleName);\n        return (mod.default ?? mod.WebSocket) as WebSocketCtor;\n    } catch {\n        throw new Error(\n            \"LighterWs::No WebSocket implementation available. On Node < 22, install the optional `ws` \" +\n                \"package or pass { WebSocketImpl } in the config.\",\n        );\n    }\n}\n\n/**\n * WebSocket client for Lighter's streaming API. Handles connection lifecycle, keepalive (server closes\n * idle sockets after 2 minutes), automatic reconnect with exponential backoff, and re-subscription of all\n * active channels after a reconnect. Works in the browser (global `WebSocket`) and Node (the `ws` package\n * or global `WebSocket` on Node >= 22).\n *\n * Dispatch: every inbound frame goes to `on(\"message\", …)` listeners; channel frames additionally go to the\n * handlers registered for their channel. Channel matching normalizes `:`/`/` separators so it is robust to\n * the server echoing `order_book:1` vs `order_book/1`.\n */\nexport default class LighterWs {\n    private readonly url: string;\n    private readonly keepAliveMs: number;\n    private readonly autoReconnect: boolean;\n    private readonly reconnectBaseMs: number;\n    private readonly reconnectMaxMs: number;\n    private readonly wsCtorInject?: WebSocketCtor;\n\n    private readonly getAuthToken?: () => string | Promise<string>;\n\n    private ws: WebSocketLike | null = null;\n    private wsCtor: WebSocketCtor | null = null;\n    private closedByUser = false;\n    /** True once a socket has opened at least once — gates auto-reconnect so a failed initial connect stays dead. */\n    private everConnected = false;\n    private reconnectAttempts = 0;\n    private keepAliveTimer: ReturnType<typeof setInterval> | null = null;\n    private reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n    /** Channels the caller wants subscribed; resent on every (re)connect. */\n    private desiredChannels: Set<string> = new Set();\n    /** Per-channel handlers, keyed by normalized channel string. */\n    private channelHandlers: Map<string, Set<LighterChannelHandler>> = new Map();\n    /** Lifecycle/message listeners. */\n    private listeners: Map<LighterWsEvent, Set<LighterWsHandler>> = new Map();\n\n    constructor(config: LighterWsConfig = {}) {\n        const isMainnet = config.isMainnet !== false;\n        if (config.url) {\n            this.url = config.url;\n        } else {\n            const venue = config.venue || LighterConstant.VENUE.ZK;\n            const { baseUrl } = LighterConstant.resolveVenue(venue, isMainnet);\n            const wssBase = baseUrl.replace(/^http/i, \"ws\"); // https -> wss, http -> ws\n            this.url = `${wssBase}/stream${config.readonly ? \"?readonly=true\" : \"\"}`;\n        }\n        this.keepAliveMs = config.keepAliveMs ?? 30000;\n        this.autoReconnect = config.autoReconnect !== false;\n        this.reconnectBaseMs = config.reconnectBaseMs ?? 1000;\n        this.reconnectMaxMs = config.reconnectMaxMs ?? 30000;\n        this.wsCtorInject = config.WebSocketImpl;\n        this.getAuthToken = config.getAuthToken;\n    }\n\n    /** Account-scoped channels whose subscribe frame must carry an `auth` token. */\n    private static needsAuth(channel: string): boolean {\n        return (\n            channel.startsWith(\"account_\") ||\n            channel.startsWith(\"user_stats\") ||\n            channel.startsWith(\"pool_\") ||\n            channel.startsWith(\"notification\") ||\n            channel === \"rfq\"\n        );\n    }\n\n    // ==================== lifecycle ====================\n\n    /** Open the socket. Resolves once connected (or rejects if the first connect fails). */\n    public async connect(): Promise<void> {\n        this.closedByUser = false;\n        if (!this.wsCtor) this.wsCtor = await resolveWebSocketCtor(this.wsCtorInject);\n        await this.openSocket();\n    }\n\n    private openSocket(): Promise<void> {\n        return new Promise<void>((resolve, reject) => {\n            const Ctor = this.wsCtor as WebSocketCtor;\n            let settled = false;\n            let socket: WebSocketLike;\n            try {\n                socket = new Ctor(this.url);\n            } catch (err) {\n                reject(err);\n                return;\n            }\n            this.ws = socket;\n\n            socket.onopen = () => {\n                this.reconnectAttempts = 0;\n                this.everConnected = true;\n                Logger.debug(`LighterWs::open::${this.url}`);\n                this.startKeepAlive();\n                // (Re)subscribe every desired channel (auth tokens are re-minted here for account channels).\n                for (const channel of this.desiredChannels) void this.sendSubscribe(channel);\n                this.emit(\"open\", undefined);\n                if (!settled) {\n                    settled = true;\n                    resolve();\n                }\n            };\n\n            socket.onmessage = (ev: any) => this.handleMessage(ev?.data);\n\n            socket.onerror = (ev: any) => {\n                const message = ev?.message || ev?.error?.message || \"websocket error\";\n                Logger.error(`LighterWs::error::${message}`);\n                this.emit(\"error\", ev);\n                if (!settled) {\n                    settled = true;\n                    reject(new Error(`LighterWs::connect failed: ${message}`));\n                }\n            };\n\n            socket.onclose = () => {\n                Logger.debug(\"LighterWs::close\");\n                this.stopKeepAlive();\n                this.ws = null;\n                this.emit(\"close\", undefined);\n                // Only auto-reconnect a previously-established connection; a failed initial connect stays dead\n                // (the connect() promise already rejected — don't spin a hidden background loop).\n                if (this.everConnected && !this.closedByUser && this.autoReconnect) this.scheduleReconnect();\n            };\n        });\n    }\n\n    /** Close the socket and cancel reconnection/keepalive. */\n    public close(): void {\n        this.closedByUser = true;\n        if (this.reconnectTimer) {\n            clearTimeout(this.reconnectTimer);\n            this.reconnectTimer = null;\n        }\n        this.stopKeepAlive();\n        try {\n            this.ws?.close();\n        } catch {\n            /* ignore */\n        }\n        this.ws = null;\n    }\n\n    private scheduleReconnect(): void {\n        if (this.reconnectTimer) return;\n        const backoff = Math.min(this.reconnectMaxMs, this.reconnectBaseMs * 2 ** this.reconnectAttempts);\n        // Full jitter to avoid a thundering herd of clients reconnecting in lockstep.\n        const delay = Math.floor(Math.random() * backoff);\n        this.reconnectAttempts += 1;\n        Logger.debug(`LighterWs::reconnect scheduled in ${delay}ms (attempt ${this.reconnectAttempts})`);\n        this.reconnectTimer = setTimeout(() => {\n            this.reconnectTimer = null;\n            this.emit(\"reconnect\", this.reconnectAttempts);\n            this.openSocket().catch((err) => {\n                Logger.error(`LighterWs::reconnect failed: ${err?.message}`);\n                if (!this.closedByUser && this.autoReconnect) this.scheduleReconnect();\n            });\n        }, delay);\n    }\n\n    private startKeepAlive(): void {\n        this.stopKeepAlive();\n        // Any application-level frame satisfies the server's 2-minute keepalive requirement. We send a small\n        // JSON ping well inside that window; it also works in the browser (no ws-level ping frame there).\n        this.keepAliveTimer = setInterval(() => {\n            if (this.ws && this.ws.readyState === WS_OPEN) {\n                try {\n                    this.ws.send(JSON.stringify({ type: \"ping\" }));\n                } catch (err: any) {\n                    Logger.warn(`LighterWs::keepalive send failed: ${err?.message}`);\n                }\n            }\n        }, this.keepAliveMs);\n        // Don't let the keepalive timer hold a Node process open.\n        (this.keepAliveTimer as any)?.unref?.();\n    }\n\n    private stopKeepAlive(): void {\n        if (this.keepAliveTimer) {\n            clearInterval(this.keepAliveTimer);\n            this.keepAliveTimer = null;\n        }\n    }\n\n    // ==================== messaging ====================\n\n    private handleMessage(raw: any): void {\n        let msg: LighterWsMessage;\n        try {\n            const text = typeof raw === \"string\" ? raw : raw?.toString?.() ?? \"\";\n            msg = JSON.parse(text) as LighterWsMessage;\n        } catch {\n            Logger.warn(\"LighterWs::handleMessage::non-JSON frame ignored\");\n            return;\n        }\n        // Server-initiated ping: reply so the connection stays healthy.\n        if (msg.type === \"ping\") {\n            if (this.ws && this.ws.readyState === WS_OPEN) {\n                try {\n                    this.ws.send(JSON.stringify({ type: \"pong\" }));\n                } catch {\n                    /* ignore */\n                }\n            }\n            return;\n        }\n        // Our keepalive's pong reply is transport noise, not application data — don't surface it.\n        if (msg.type === \"pong\") return;\n        this.emit(\"message\", msg);\n        if (msg.channel) {\n            const handlers = this.channelHandlers.get(LighterWs.normalizeChannel(msg.channel));\n            if (handlers) for (const h of handlers) h(msg);\n        }\n    }\n\n    private async sendSubscribe(channel: string): Promise<void> {\n        const frame: Record<string, unknown> = { type: \"subscribe\", channel };\n        if (LighterWs.needsAuth(channel)) {\n            if (!this.getAuthToken) {\n                // Should not happen — subscribe() rejects this up front — but guard the reconnect path too.\n                Logger.error(`LighterWs::cannot subscribe to authed channel \"${channel}\" without getAuthToken`);\n                return;\n            }\n            try {\n                frame.auth = await this.getAuthToken();\n            } catch (err: any) {\n                Logger.error(`LighterWs::getAuthToken failed for \"${channel}\": ${err?.message}`);\n                return;\n            }\n        }\n        this.sendFrame(frame);\n    }\n\n    private sendUnsubscribe(channel: string): void {\n        this.sendFrame({ type: \"unsubscribe\", channel });\n    }\n\n    private sendFrame(frame: Record<string, unknown>): void {\n        if (this.ws && this.ws.readyState === WS_OPEN) {\n            this.ws.send(JSON.stringify(frame));\n        }\n        // If not open yet, desiredChannels drives a resubscribe on the next open.\n    }\n\n    private static normalizeChannel(channel: string): string {\n        return channel.replace(/:/g, \"/\");\n    }\n\n    // ==================== subscriptions ====================\n\n    /**\n     * Subscribe to a raw channel string (e.g. \"order_book/1\", \"account_all/7\"). Returns an unsubscribe\n     * handle. Safe to call before `connect()`: the subscription is (re)sent on every connect.\n     */\n    public subscribe(channel: string, handler: LighterChannelHandler): Unsubscribe {\n        if (LighterWs.needsAuth(channel) && !this.getAuthToken) {\n            throw new Error(\n                `LighterWs::channel \"${channel}\" is account-scoped and requires auth — pass getAuthToken in the LighterWs config (or use LighterClient with a signer).`,\n            );\n        }\n        const key = LighterWs.normalizeChannel(channel);\n        this.desiredChannels.add(channel);\n        let set = this.channelHandlers.get(key);\n        if (!set) {\n            set = new Set();\n            this.channelHandlers.set(key, set);\n        }\n        set.add(handler);\n        void this.sendSubscribe(channel);\n\n        return () => {\n            const handlers = this.channelHandlers.get(key);\n            if (handlers) {\n                handlers.delete(handler);\n                if (handlers.size === 0) {\n                    this.channelHandlers.delete(key);\n                    this.desiredChannels.delete(channel);\n                    this.sendUnsubscribe(channel);\n                }\n            }\n        };\n    }\n\n    /** Order book snapshot + batched deltas for a market. */\n    public subscribeOrderBook(marketIndex: number, handler: LighterChannelHandler): Unsubscribe {\n        return this.subscribe(`order_book/${marketIndex}`, handler);\n    }\n\n    /** Public trade prints for a market. */\n    public subscribeTrades(marketIndex: number, handler: LighterChannelHandler): Unsubscribe {\n        return this.subscribe(`trade/${marketIndex}`, handler);\n    }\n\n    /** Best bid/offer ticker for a market. */\n    public subscribeTicker(marketIndex: number, handler: LighterChannelHandler): Unsubscribe {\n        return this.subscribe(`ticker/${marketIndex}`, handler);\n    }\n\n    /** Rolling market stats for one market, or all markets with \"all\". */\n    public subscribeMarketStats(marketIndexOrAll: number | \"all\", handler: LighterChannelHandler): Unsubscribe {\n        return this.subscribe(`market_stats/${marketIndexOrAll}`, handler);\n    }\n\n    /** All account state (balances, positions, orders) for an account. */\n    public subscribeAccountAll(accountIndex: number, handler: LighterChannelHandler): Unsubscribe {\n        return this.subscribe(`account_all/${accountIndex}`, handler);\n    }\n\n    /** All open/closed orders for an account. */\n    public subscribeAccountOrders(accountIndex: number, handler: LighterChannelHandler): Unsubscribe {\n        return this.subscribe(`account_all_orders/${accountIndex}`, handler);\n    }\n\n    /** All positions for an account. */\n    public subscribeAccountPositions(accountIndex: number, handler: LighterChannelHandler): Unsubscribe {\n        return this.subscribe(`account_all_positions/${accountIndex}`, handler);\n    }\n\n    /** All fills for an account. */\n    public subscribeAccountTrades(accountIndex: number, handler: LighterChannelHandler): Unsubscribe {\n        return this.subscribe(`account_all_trades/${accountIndex}`, handler);\n    }\n\n    // ==================== event listeners ====================\n\n    /** Register a lifecycle/message listener. Returns an unsubscribe handle. */\n    public on(event: LighterWsEvent, handler: LighterWsHandler): Unsubscribe {\n        let set = this.listeners.get(event);\n        if (!set) {\n            set = new Set();\n            this.listeners.set(event, set);\n        }\n        set.add(handler);\n        return () => this.listeners.get(event)?.delete(handler);\n    }\n\n    private emit(event: LighterWsEvent, payload: any): void {\n        const set = this.listeners.get(event);\n        if (!set) return;\n        for (const h of set) {\n            try {\n                h(payload);\n            } catch (err: any) {\n                Logger.error(`LighterWs::listener for \"${event}\" threw: ${err?.message}`);\n            }\n        }\n    }\n\n    /** True when the socket is open. */\n    public get isConnected(): boolean {\n        return !!this.ws && this.ws.readyState === WS_OPEN;\n    }\n}\n","import { Logger } from \"./logger\";\nimport LighterConstant from \"./constants\";\nimport LighterHelper from \"./helpers\";\nimport LighterRestClient from \"./rest/client\";\nimport LighterWs from \"./ws/client\";\nimport { createAuthToken, type LighterGroupedOrder } from \"./signer/core\";\nimport { LighterValidationError } from \"./errors\";\nimport {\n    LighterRestClientConfig,\n    LighterVenue,\n    LighterSignerContext,\n    LighterOrderBookDetail,\n    LighterSendTxResponse,\n    LighterPosition,\n    LighterAccount,\n    LighterActiveOrder,\n} from \"./types\";\nimport type { LighterChannelHandler, Unsubscribe } from \"./ws/types\";\n\n/** Long = buy (is_ask false); short = sell (is_ask true). */\nexport type OrderSide = \"long\" | \"short\";\n\n/** Default market-order slippage bound (5%) when the caller doesn't specify one. */\nconst DEFAULT_MARKET_SLIPPAGE = 0.05;\n/** Refresh cached market data (incl. last price for slippage bounds) if older than this before a market order. */\nconst DEFAULT_MARKET_STALENESS_MS = 15_000;\n/** USDC collateral decimals — margin/withdraw/transfer amounts scale by 10^6. */\nconst USDC_DECIMALS = 6;\n/**\n * Resting lifetime for a bracket's TP/SL (and limit-entry) legs. Grouped-order legs require a concrete\n * future epoch-ms expiry (the -1 sentinel that single trigger orders accept is NOT honoured here).\n * ~27 days, just under Lighter's 28-day maximum.\n */\nconst BRACKET_LEG_TTL_MS = 27 * 24 * 60 * 60 * 1000;\n\n/** Uniform random in [0,1) preferring crypto entropy (collision-resistant client_order_index across processes). */\nfunction randomUnit(): number {\n    const c = (globalThis as any).crypto;\n    if (c && typeof c.getRandomValues === \"function\") {\n        const buf = new Uint32Array(1);\n        c.getRandomValues(buf);\n        return buf[0] / 0x100000000;\n    }\n    // eslint-disable-next-line no-restricted-properties\n    return Math.random();\n}\n\n/** Resolved, cached per-market metadata used to scale human values to the API's integers. */\nexport interface LighterMarketMeta {\n    marketId: number;\n    symbol: string;\n    priceDecimals: number;\n    sizeDecimals: number;\n    /** Minimum order size in human token units. */\n    minBaseAmount: number;\n    /** Minimum order notional in human quote units. */\n    minQuoteAmount: number;\n    /** Max leverage the market allows (= SCALE / min_initial_margin_fraction); 0 when the market omits it. */\n    maxLeverage: number;\n    minInitialMarginFraction: number;\n    lastTradePrice: number;\n}\n\nexport interface LighterClientConfig extends LighterRestClientConfig {\n    /** Default signer context for write calls, so per-call ctx is optional. */\n    signer?: LighterSignerContext;\n    /** Default market-order slippage bound (fraction) when a call omits `slippage`. Default 0.05 (5%). */\n    defaultSlippage?: number;\n    /** Refresh market data before a market order if older than this (ms). Default 15000. */\n    marketStalenessMs?: number;\n    /** Provider for the WS account-channel auth token; wired into the internal WS client. */\n    getAuthToken?: () => string | Promise<string>;\n    /** Advanced/testing override for the underlying REST client. */\n    restClient?: LighterRestClient;\n    /** Advanced/testing override for the underlying WS client. */\n    wsClient?: LighterWs;\n}\n\nexport interface PlaceMarketOrderParams {\n    symbol: string;\n    side: OrderSide;\n    /** Order size in human token units (scaled to size_decimals internally). */\n    size: number | string;\n    reduceOnly?: boolean;\n    /** Optional slippage bound (fraction, e.g. 0.02 = 2%) applied to last price for a worst-case price. */\n    slippage?: number;\n    applyIntegratorFee?: boolean;\n    clientOrderIndex?: number;\n}\n\nexport interface PlaceLimitOrderParams {\n    symbol: string;\n    side: OrderSide;\n    /** Size in human token units. */\n    size: number | string;\n    /** Limit price in human quote units (scaled to price_decimals internally). */\n    price: number | string;\n    timeInForce?: \"gtc\" | \"ioc\" | \"alo\";\n    postOnly?: boolean;\n    reduceOnly?: boolean;\n    applyIntegratorFee?: boolean;\n    clientOrderIndex?: number;\n}\n\nexport interface PlaceBracketOrderParams {\n    symbol: string;\n    /** Entry side. Take-profit/stop-loss close the opposite way automatically. */\n    side: OrderSide;\n    /** Entry size in human token units. */\n    size: number | string;\n    /** Entry as a market order (default) or a resting limit at `price`. */\n    entry?: { type: \"market\"; slippage?: number } | { type: \"limit\"; price: number | string };\n    /** Take-profit trigger price (human quote units). Provide TP and/or SL — at least one is required. */\n    takeProfit?: number | string;\n    /** Stop-loss trigger price (human quote units). */\n    stopLoss?: number | string;\n    applyIntegratorFee?: boolean;\n}\n\n/**\n * High-level, venue-aware convenience client over {@link LighterRestClient} and {@link LighterWs}. It\n * resolves markets by symbol, scales human sizes/prices to Lighter's integer encoding using each market's\n * decimals, maps long/short to is_ask, and streams by symbol. It is pure sugar — every low-level path is\n * still reachable through `.rest` and `.ws`.\n */\nexport default class LighterClient {\n    public readonly rest: LighterRestClient;\n    private readonly venue: LighterVenue;\n    private readonly isMainnet: boolean;\n    private readonly defaultSigner?: LighterSignerContext;\n    private readonly defaultSlippage: number;\n    private readonly marketStalenessMs: number;\n    private readonly getAuthToken?: () => string | Promise<string>;\n    private wsClient: LighterWs | null;\n    private readonly wsInjected: boolean;\n\n    private marketsBySymbol: Map<string, LighterMarketMeta> | null = null;\n    private marketsById: Map<number, LighterMarketMeta> | null = null;\n    private marketsLoadedAt = 0;\n    private coiCounter = 0;\n\n    constructor(config: LighterClientConfig = {}) {\n        this.venue = config.venue || LighterConstant.VENUE.ZK;\n        this.isMainnet = config.isMainnet !== false;\n        this.defaultSigner = config.signer;\n        this.defaultSlippage = config.defaultSlippage ?? DEFAULT_MARKET_SLIPPAGE;\n        this.marketStalenessMs = config.marketStalenessMs ?? DEFAULT_MARKET_STALENESS_MS;\n        this.getAuthToken = config.getAuthToken;\n        this.rest =\n            config.restClient ||\n            new LighterRestClient({ venue: this.venue, isMainnet: this.isMainnet, baseUrl: config.baseUrl, integrator: config.integrator });\n        this.wsClient = config.wsClient || null;\n        this.wsInjected = !!config.wsClient;\n    }\n\n    // ==================== markets ====================\n\n    /** Fetch + cache market metadata (idempotent unless `force`). Auto-called by symbol-based methods. */\n    public async loadMarkets(force = false): Promise<void> {\n        if (this.marketsBySymbol && !force) return;\n        const details = await this.rest.getOrderBookDetails();\n        const bySymbol = new Map<string, LighterMarketMeta>();\n        const byId = new Map<number, LighterMarketMeta>();\n        for (const d of details) {\n            const meta = LighterClient.toMeta(d);\n            if (!meta.symbol) continue;\n            bySymbol.set(meta.symbol, meta);\n            byId.set(meta.marketId, meta);\n        }\n        this.marketsBySymbol = bySymbol;\n        this.marketsById = byId;\n        this.marketsLoadedAt = Date.now();\n        Logger.debug(`LighterClient::loadMarkets::${bySymbol.size} markets`);\n    }\n\n    /** Reload market data if the cache is older than `maxAgeMs` (keeps the market-order price bound fresh). */\n    private async ensureFreshMarkets(maxAgeMs: number): Promise<void> {\n        if (!this.marketsBySymbol || Date.now() - this.marketsLoadedAt > maxAgeMs) {\n            await this.loadMarkets(true);\n        }\n    }\n\n    private static toMeta(d: LighterOrderBookDetail): LighterMarketMeta {\n        const minFraction = Number(d.min_initial_margin_fraction || 0);\n        const maxLeverage = minFraction > 0 ? Math.floor(LighterConstant.MARGIN_FRACTION_SCALE / minFraction) : 0;\n        return {\n            marketId: d.market_id,\n            symbol: String(d.symbol || \"\").toUpperCase(),\n            priceDecimals: d.price_decimals,\n            sizeDecimals: d.size_decimals,\n            minBaseAmount: Number(d.min_base_amount || 0),\n            minQuoteAmount: Number(d.min_quote_amount || 0),\n            maxLeverage,\n            minInitialMarginFraction: minFraction,\n            lastTradePrice: Number(d.last_trade_price || 0),\n        };\n    }\n\n    /** All cached markets (loads on first call). */\n    public async markets(): Promise<LighterMarketMeta[]> {\n        await this.loadMarkets();\n        return [...(this.marketsBySymbol as Map<string, LighterMarketMeta>).values()];\n    }\n\n    /** Resolve a market by symbol from cache; throws if not loaded/unknown. Call `loadMarkets()` first. */\n    public market(symbol: string): LighterMarketMeta {\n        if (!this.marketsBySymbol) {\n            throw new Error(\"LighterClient::market::markets not loaded — await loadMarkets() first\");\n        }\n        const meta = this.marketsBySymbol.get(symbol.toUpperCase());\n        if (!meta) throw new Error(`LighterClient::market::unknown symbol \"${symbol}\"`);\n        return meta;\n    }\n\n    /** Market index for a symbol (loads markets if needed). */\n    public async marketId(symbol: string): Promise<number> {\n        await this.loadMarkets();\n        return this.market(symbol).marketId;\n    }\n\n    // ==================== trading ====================\n\n    private requireSigner(ctx?: LighterSignerContext): LighterSignerContext {\n        const signer = ctx || this.defaultSigner;\n        if (!signer) throw new Error(\"LighterClient::a signer context is required (pass one or set config.signer)\");\n        return signer;\n    }\n\n    private nextClientOrderIndex(explicit?: number): number {\n        if (explicit !== undefined) return explicit;\n        // uint48 client_order_index: 29 high bits of ms time + 19 low bits of (random + per-call counter).\n        // Randomness makes it collision-resistant across instances/processes; the counter guarantees\n        // uniqueness for bursts within a single millisecond in this instance.\n        const timeBits = Date.now() % 0x2000_0000; // 2^29 (~6.2 day wrap)\n        const low = (Math.floor(randomUnit() * 0x8_0000) + this.coiCounter++) % 0x8_0000; // 2^19\n        return (timeBits * 0x8_0000 + low) % LighterConstant.MAX_CLIENT_ORDER_INDEX;\n    }\n\n    /** Reject an order that is below the market's minimum size or notional before it burns a nonce. */\n    private assertOrderMinimums(meta: LighterMarketMeta, baseAmount: bigint, sizeHuman: number, priceHuman?: number): void {\n        if (meta.minBaseAmount > 0) {\n            const minBase = LighterHelper.toBaseAmount(meta.minBaseAmount, meta.sizeDecimals);\n            if (baseAmount < minBase) {\n                throw new Error(\n                    `LighterClient::order size ${sizeHuman} below ${meta.symbol} minimum ${meta.minBaseAmount}`,\n                );\n            }\n        }\n        if (meta.minQuoteAmount > 0 && priceHuman && priceHuman > 0) {\n            const notional = sizeHuman * priceHuman;\n            if (notional < meta.minQuoteAmount) {\n                throw new Error(\n                    `LighterClient::order notional ${notional.toFixed(4)} below ${meta.symbol} minimum ${meta.minQuoteAmount}`,\n                );\n            }\n        }\n    }\n\n    /**\n     * Place a market order (size in tokens). A worst-case price bound is ALWAYS sent — from `slippage`,\n     * else the client's `defaultSlippage` (5%) — computed off a freshly-refreshed last price, so a market\n     * buy can fill and a sell is slippage-protected. Never signs an unbounded (price 0) order.\n     */\n    public async placeMarketOrder(params: PlaceMarketOrderParams, ctx?: LighterSignerContext): Promise<LighterSendTxResponse> {\n        const signer = this.requireSigner(ctx);\n        await this.ensureFreshMarkets(this.marketStalenessMs);\n        const meta = this.market(params.symbol);\n        const baseAmount = LighterHelper.toBaseAmount(params.size, meta.sizeDecimals);\n        const isAsk = params.side === \"short\";\n        if (!(meta.lastTradePrice > 0)) {\n            throw new Error(\n                `LighterClient::placeMarketOrder::no reference price for ${meta.symbol} — cannot set a worst-case bound; use placeLimitOrder with an explicit price`,\n            );\n        }\n        const slippage = params.slippage ?? this.defaultSlippage;\n        const worstHuman = isAsk ? meta.lastTradePrice * (1 - slippage) : meta.lastTradePrice * (1 + slippage);\n        this.assertOrderMinimums(meta, baseAmount, Number(params.size), meta.lastTradePrice);\n        const price = Number(LighterHelper.toPriceInt(worstHuman, meta.priceDecimals));\n        return this.rest.createMarketOrder(signer, {\n            marketIndex: meta.marketId,\n            baseAmount,\n            isAsk,\n            reduceOnly: Boolean(params.reduceOnly),\n            clientOrderIndex: this.nextClientOrderIndex(params.clientOrderIndex),\n            price,\n            applyIntegratorFee: params.applyIntegratorFee,\n        });\n    }\n\n    /** Place a resting/IOC limit order (size in tokens, price in quote units). */\n    public async placeLimitOrder(params: PlaceLimitOrderParams, ctx?: LighterSignerContext): Promise<LighterSendTxResponse> {\n        const signer = this.requireSigner(ctx);\n        await this.loadMarkets();\n        const meta = this.market(params.symbol);\n        const baseAmount = LighterHelper.toBaseAmount(params.size, meta.sizeDecimals);\n        this.assertOrderMinimums(meta, baseAmount, Number(params.size), Number(params.price));\n        return this.rest.createLimitOrder(signer, {\n            marketIndex: meta.marketId,\n            baseAmount,\n            price: Number(LighterHelper.toPriceInt(params.price, meta.priceDecimals)),\n            isAsk: params.side === \"short\",\n            clientOrderIndex: this.nextClientOrderIndex(params.clientOrderIndex),\n            timeInForce: params.timeInForce,\n            postOnly: params.postOnly,\n            reduceOnly: params.reduceOnly,\n            applyIntegratorFee: params.applyIntegratorFee,\n        });\n    }\n\n    /**\n     * Place a bracket order in ONE atomic transaction: a market/limit entry plus a take-profit and/or\n     * stop-loss that close the position automatically. TP+SL = OTOCO; a single TP or SL = OTO. Prices and\n     * size are human units; the TP/SL legs are reduce-only and close whatever the entry fills.\n     */\n    public async placeBracketOrder(params: PlaceBracketOrderParams, ctx?: LighterSignerContext): Promise<LighterSendTxResponse> {\n        const signer = this.requireSigner(ctx);\n        if (params.takeProfit == null && params.stopLoss == null) {\n            throw new LighterValidationError(\n                \"LighterClient::placeBracketOrder requires takeProfit and/or stopLoss; use placeMarketOrder/placeLimitOrder for a plain order\",\n            );\n        }\n        await this.ensureFreshMarkets(this.marketStalenessMs);\n        const meta = this.market(params.symbol);\n        const isAsk = params.side === \"short\";\n        const closeIsAsk = !isAsk; // TP/SL close the position the opposite way\n        const baseAmount = LighterHelper.toBaseAmount(params.size, meta.sizeDecimals);\n        this.assertOrderMinimums(meta, baseAmount, Number(params.size), meta.lastTradePrice || undefined);\n        const slip = this.defaultSlippage;\n        const toPrice = (p: number | string) => Number(LighterHelper.toPriceInt(p, meta.priceDecimals));\n        const boundFor = (triggerHuman: number, closingIsAsk: boolean) => {\n            const worst = closingIsAsk ? triggerHuman * (1 - slip) : triggerHuman * (1 + slip);\n            return Math.max(1, Number(LighterHelper.toPriceInt(worst, meta.priceDecimals)));\n        };\n\n        // Grouped-order legs need a concrete future expiry (unlike single orders' -1 sentinel).\n        const legExpiry = Date.now() + BRACKET_LEG_TTL_MS;\n\n        // Entry (main) leg.\n        const entry = params.entry ?? { type: \"market\" as const };\n        let mainPrice: number;\n        let orderType: number;\n        let timeInForce: number;\n        let orderExpiry: number;\n        if (entry.type === \"limit\") {\n            mainPrice = toPrice(entry.price);\n            orderType = LighterConstant.ORDER_TYPE.LIMIT;\n            timeInForce = LighterConstant.TIME_IN_FORCE.GOOD_TILL_TIME;\n            orderExpiry = legExpiry;\n        } else {\n            if (!(meta.lastTradePrice > 0)) {\n                throw new LighterValidationError(`LighterClient::placeBracketOrder::no reference price for ${meta.symbol}; use a limit entry`);\n            }\n            const s = entry.slippage ?? slip;\n            const worst = isAsk ? meta.lastTradePrice * (1 - s) : meta.lastTradePrice * (1 + s);\n            mainPrice = Number(LighterHelper.toPriceInt(worst, meta.priceDecimals));\n            orderType = LighterConstant.ORDER_TYPE.MARKET;\n            timeInForce = LighterConstant.TIME_IN_FORCE.IMMEDIATE_OR_CANCEL;\n            orderExpiry = 0;\n        }\n\n        const legs: LighterGroupedOrder[] = [\n            { marketIndex: meta.marketId, clientOrderIndex: this.nextClientOrderIndex(), baseAmount, price: mainPrice, isAsk, orderType, timeInForce, reduceOnly: false, orderExpiry },\n        ];\n        if (params.takeProfit != null) {\n            const trig = toPrice(params.takeProfit);\n            legs.push({\n                marketIndex: meta.marketId, clientOrderIndex: this.nextClientOrderIndex(), baseAmount: 0n,\n                price: boundFor(Number(params.takeProfit), closeIsAsk), isAsk: closeIsAsk,\n                orderType: LighterConstant.ORDER_TYPE.TAKE_PROFIT, timeInForce: LighterConstant.TIME_IN_FORCE.IMMEDIATE_OR_CANCEL,\n                reduceOnly: true, triggerPrice: trig, orderExpiry: legExpiry,\n            });\n        }\n        if (params.stopLoss != null) {\n            const trig = toPrice(params.stopLoss);\n            legs.push({\n                marketIndex: meta.marketId, clientOrderIndex: this.nextClientOrderIndex(), baseAmount: 0n,\n                price: boundFor(Number(params.stopLoss), closeIsAsk), isAsk: closeIsAsk,\n                orderType: LighterConstant.ORDER_TYPE.STOP_LOSS, timeInForce: LighterConstant.TIME_IN_FORCE.IMMEDIATE_OR_CANCEL,\n                reduceOnly: true, triggerPrice: trig, orderExpiry: legExpiry,\n            });\n        }\n        const groupingType =\n            params.takeProfit != null && params.stopLoss != null ? LighterConstant.GROUPING_TYPE.OTOCO : LighterConstant.GROUPING_TYPE.OTO;\n        return this.rest.createGroupedOrders(signer, { groupingType, orders: legs, applyIntegratorFee: params.applyIntegratorFee });\n    }\n\n    /** Add or remove isolated margin on a market. `amount` is in human USDC. */\n    public async adjustMargin(\n        params: { symbol: string; amount: number | string; action: \"add\" | \"remove\" },\n        ctx?: LighterSignerContext,\n    ): Promise<LighterSendTxResponse> {\n        const signer = this.requireSigner(ctx);\n        await this.loadMarkets();\n        const meta = this.market(params.symbol);\n        const usdcAmount = LighterHelper.toBaseAmount(params.amount, USDC_DECIMALS);\n        return this.rest.updateMargin(signer, {\n            marketIndex: meta.marketId,\n            usdcAmount,\n            direction: params.action === \"remove\" ? LighterConstant.MARGIN_DIRECTION.REMOVE : LighterConstant.MARGIN_DIRECTION.ADD,\n        });\n    }\n\n    /** Market-close the open position in `symbol` (reduce-only). Returns null if already flat. */\n    public async closePosition(symbol: string, ctx?: LighterSignerContext): Promise<LighterSendTxResponse | null> {\n        const signer = this.requireSigner(ctx);\n        await this.loadMarkets();\n        const meta = this.market(symbol);\n        const positions = await this.rest.getPositions(signer.accountIndex);\n        const pos = positions.find((p) => Number(p.market_id) === meta.marketId);\n        const size = pos ? Math.abs(Number(pos.position)) : 0;\n        if (!pos || !(size > 0)) return null;\n        const closeSide: OrderSide = Number(pos.sign) > 0 ? \"short\" : \"long\"; // long position -> sell to close\n        return this.placeMarketOrder({ symbol, side: closeSide, size, reduceOnly: true }, signer);\n    }\n\n    /** Market-close every open position (reduce-only). Continues past individual failures. */\n    public async closeAllPositions(ctx?: LighterSignerContext): Promise<Array<{ symbol: string; result: LighterSendTxResponse | null; error?: string }>> {\n        const signer = this.requireSigner(ctx);\n        await this.loadMarkets();\n        const positions = await this.rest.getPositions(signer.accountIndex);\n        const out: Array<{ symbol: string; result: LighterSendTxResponse | null; error?: string }> = [];\n        for (const p of positions) {\n            if (!(Math.abs(Number(p.position)) > 0)) continue;\n            const meta = this.marketsById?.get(Number(p.market_id));\n            const symbol = meta?.symbol ?? String(p.symbol ?? p.market_id);\n            try {\n                out.push({ symbol, result: await this.closePosition(symbol, signer) });\n            } catch (err: any) {\n                out.push({ symbol, result: null, error: err?.message });\n            }\n        }\n        return out;\n    }\n\n    /**\n     * Withdraw USDC from the L2 account back to the L1 owner. `amount` is in human USDC. Defaults to the\n     * fast route (the standard route is not available on all networks).\n     *\n     * Note: account transfers to another Lighter account additionally require the account owner's L1\n     * signature (like onboarding). Use the low-level `client.rest.transfer` + your own L1 signing for that.\n     */\n    public async withdraw(params: { amount: number | string; routeType?: number }, ctx?: LighterSignerContext): Promise<LighterSendTxResponse> {\n        const signer = this.requireSigner(ctx);\n        return this.rest.withdraw(signer, {\n            amount: LighterHelper.toBaseAmount(params.amount, USDC_DECIMALS),\n            routeType: params.routeType ?? LighterConstant.ROUTE_TYPE.FAST,\n        });\n    }\n\n    /** Poll a transaction hash until it reaches a terminal state (see {@link LighterRestClient.waitForTransaction}). */\n    public async waitForTransaction(hash: string, opts?: { timeoutMs?: number; intervalMs?: number }): Promise<any> {\n        return this.rest.waitForTransaction(hash, opts);\n    }\n\n    /** Set per-market leverage (clamped to the market's max). */\n    public async setLeverage(\n        params: { symbol: string; leverage: number; marginMode?: number },\n        ctx?: LighterSignerContext,\n    ): Promise<LighterSendTxResponse> {\n        const signer = this.requireSigner(ctx);\n        await this.loadMarkets();\n        const meta = this.market(params.symbol);\n        return this.rest.updateLeverage(signer, {\n            marketIndex: meta.marketId,\n            leverage: params.leverage,\n            marginMode: params.marginMode,\n            minFraction: meta.minInitialMarginFraction,\n        });\n    }\n\n    /** Cancel a specific resting order by its order_index. */\n    public async cancelOrder(symbol: string, orderIndex: number, ctx?: LighterSignerContext): Promise<LighterSendTxResponse> {\n        const signer = this.requireSigner(ctx);\n        const marketIndex = await this.marketId(symbol);\n        return this.rest.cancelOrder(signer, { marketIndex, orderIndex });\n    }\n\n    /**\n     * Atomically cancel every resting order for the account (or all orders in one symbol) in a single tx.\n     * One nonce, one round trip, no window for fills between cancels — unlike a per-order loop.\n     */\n    public async cancelAllOrders(ctx?: LighterSignerContext, symbol?: string): Promise<LighterSendTxResponse> {\n        const signer = this.requireSigner(ctx);\n        const marketIndex = symbol ? await this.marketId(symbol) : LighterConstant.CANCEL_ALL_MARKETS;\n        return this.rest.cancelAllOrders(signer, { marketIndex });\n    }\n\n    // ==================== reads ====================\n\n    public async getAccount(accountIndex?: number): Promise<LighterAccount | null> {\n        const idx = accountIndex ?? this.defaultSigner?.accountIndex;\n        if (idx === undefined) throw new Error(\"LighterClient::getAccount::accountIndex required\");\n        return this.rest.getAccount(idx);\n    }\n\n    public async getPositions(accountIndex?: number): Promise<LighterPosition[]> {\n        const idx = accountIndex ?? this.defaultSigner?.accountIndex;\n        if (idx === undefined) throw new Error(\"LighterClient::getPositions::accountIndex required\");\n        return this.rest.getPositions(idx);\n    }\n\n    public async getOpenOrders(symbol?: string, ctx?: LighterSignerContext): Promise<LighterActiveOrder[]> {\n        const signer = this.requireSigner(ctx);\n        const marketId = symbol ? await this.marketId(symbol) : undefined;\n        return this.rest.getActiveOrders(signer, marketId !== undefined ? { marketId } : {});\n    }\n\n    // ==================== streaming ====================\n\n    /**\n     * WS account-channel auth provider: the explicit `getAuthToken` config, else one minted from the\n     * default signer (so `streamAccount*` works out of the box when a signer is configured).\n     */\n    private resolveAuthProvider(): (() => string | Promise<string>) | undefined {\n        if (this.getAuthToken) return this.getAuthToken;\n        const s = this.defaultSigner;\n        if (!s) return undefined;\n        const { baseUrl, chainId } = LighterConstant.resolveVenue(this.venue, this.isMainnet);\n        return () => createAuthToken({ url: baseUrl, chainId, apiPrivateKey: s.apiPrivateKey, accountIndex: s.accountIndex, apiKeyIndex: s.apiKeyIndex });\n    }\n\n    /** The underlying WebSocket client (lazily created for this venue/network). */\n    public get ws(): LighterWs {\n        if (!this.wsClient) {\n            this.wsClient = new LighterWs({ venue: this.venue, isMainnet: this.isMainnet, getAuthToken: this.resolveAuthProvider() });\n        }\n        return this.wsClient;\n    }\n\n    /** Connect the WebSocket (loads markets too, so symbol-based streams resolve). */\n    public async connect(): Promise<void> {\n        await this.loadMarkets();\n        await this.ws.connect();\n    }\n\n    /** Stream the order book for a symbol (markets must be loaded; call `connect()`/`loadMarkets()` first). */\n    public streamOrderBook(symbol: string, handler: LighterChannelHandler): Unsubscribe {\n        return this.ws.subscribeOrderBook(this.market(symbol).marketId, handler);\n    }\n\n    /** Stream public trades for a symbol. */\n    public streamTrades(symbol: string, handler: LighterChannelHandler): Unsubscribe {\n        return this.ws.subscribeTrades(this.market(symbol).marketId, handler);\n    }\n\n    /** Stream all account updates (balances, positions, orders). */\n    public streamAccount(handler: LighterChannelHandler, accountIndex?: number): Unsubscribe {\n        const idx = accountIndex ?? this.defaultSigner?.accountIndex;\n        if (idx === undefined) throw new Error(\"LighterClient::streamAccount::accountIndex required\");\n        return this.ws.subscribeAccountAll(idx, handler);\n    }\n\n    /** Close the WebSocket if this client owns it. */\n    public close(): void {\n        if (this.wsClient && !this.wsInjected) this.wsClient.close();\n    }\n}\n","import { Logger } from \"./logger\";\nimport LighterConstant from \"./constants\";\nimport LighterRestClient from \"./rest/client\";\nimport { signChangePubKey, generateApiKey } from \"./signer/core\";\nimport { LighterVenue, LighterAccount, LighterSignerContext } from \"./types\";\n\nexport interface LighterOnboardingConfig {\n    /** Perp venue: \"zk\" (default) or \"robinhood\". */\n    venue?: LighterVenue;\n    /** Default true (mainnet). */\n    isMainnet?: boolean;\n    /** Advanced/testing override for the underlying REST client. */\n    restClient?: LighterRestClient;\n}\n\n/**\n * A generated-but-not-yet-registered API key. The caller must (1) have the account owner's EVM wallet\n * personal_sign `messageToSign`, then (2) submit via `submitApiKey`. STORE `apiPrivateKey` securely — it is\n * the credential you sign orders with and cannot be recovered.\n */\nexport interface PendingApiKeyRegistration {\n    accountIndex: number;\n    apiKeyIndex: number;\n    /** The new API key's private key — persist this; it is your trading credential. */\n    apiPrivateKey: string;\n    /** The new API key's public key (being registered on-chain). */\n    publicKey: string;\n    /** tx_type 8 (ChangePubKey). */\n    txType: number;\n    /** L2-signed tx with an empty `L1Sig` placeholder to be filled by the account owner's L1 signature. */\n    txInfo: string;\n    /** The message the account owner's EVM wallet must personal_sign; its signature completes the tx. */\n    messageToSign: string;\n}\n\n/**\n * Onboarding helper: associate a programmatic API key with a Lighter account so the SDK can sign trades.\n *\n * Prerequisite: the account must already exist (create one by depositing via Lighter's L1 bridge). This\n * helper does the API-key association (a ChangePubKey, tx_type 8), which is a two-signature handshake:\n *   1. the SDK generates a fresh API keypair and L2 self-signs the ChangePubKey (proving control of the new key);\n *   2. the account owner's EVM wallet personal_signs the returned `messageToSign` (proving account ownership);\n *   3. that L1 signature is spliced in and the tx submitted.\n *\n * Use {@link registerApiKey} for the full flow with an injected wallet signer, or the two-step\n * {@link prepareApiKey} / {@link submitApiKey} when the wallet signature happens elsewhere (e.g. a frontend).\n */\nexport default class LighterOnboarding {\n    private readonly rest: LighterRestClient;\n    private readonly baseUrl: string;\n    private readonly chainId: number;\n\n    constructor(config: LighterOnboardingConfig = {}) {\n        const venue = config.venue || LighterConstant.VENUE.ZK;\n        const isMainnet = config.isMainnet !== false;\n        const resolved = LighterConstant.resolveVenue(venue, isMainnet);\n        this.baseUrl = resolved.baseUrl;\n        this.chainId = resolved.chainId;\n        this.rest = config.restClient || new LighterRestClient({ venue, isMainnet });\n    }\n\n    /** All Lighter accounts (sub-accounts) owned by an L1 (EVM) wallet address. */\n    public async getAccounts(l1Address: string): Promise<LighterAccount[]> {\n        return this.rest.getAccountsByL1Address(l1Address);\n    }\n\n    /** Resolve the primary account index for an L1 wallet; throws if the wallet has no Lighter account yet. */\n    public async resolveAccountIndex(l1Address: string): Promise<number> {\n        const accounts = await this.getAccounts(l1Address);\n        const acc = accounts[0] as (LighterAccount & { index?: number }) | undefined;\n        const idx = acc?.account_index ?? acc?.index;\n        if (idx == null) {\n            throw new Error(\n                `LighterOnboarding::no Lighter account found for ${l1Address}. Create one first by depositing via the Lighter bridge.`,\n            );\n        }\n        return Number(idx);\n    }\n\n    /** Pick the lowest free programmatic api_key_index (>= 4; slots 0-3 are reserved for desktop/mobile). */\n    public async findFreeApiKeyIndex(accountIndex: number): Promise<number> {\n        const keys = await this.rest.getApiKeys(accountIndex);\n        const used = new Set(keys.map((k) => Number(k.api_key_index)));\n        let apiKeyIndex = LighterConstant.RESERVED_API_KEY_INDEX_MAX + 1;\n        while (used.has(apiKeyIndex) && apiKeyIndex <= LighterConstant.MAX_API_KEY_INDEX) apiKeyIndex++;\n        if (apiKeyIndex > LighterConstant.MAX_API_KEY_INDEX) {\n            throw new Error(\"LighterOnboarding::no free API key slot available on this account\");\n        }\n        return apiKeyIndex;\n    }\n\n    /**\n     * Step 1: generate a fresh API keypair and L2 self-sign a ChangePubKey for `accountIndex`. Returns the\n     * pending registration, including `messageToSign` for the account owner's wallet and `apiPrivateKey`\n     * (STORE IT). A fresh slot has never been used, so the nonce bootstraps at 0 (skipNonce).\n     */\n    public async prepareApiKey(params: { accountIndex: number; apiKeyIndex?: number }): Promise<PendingApiKeyRegistration> {\n        const apiKeyIndex = params.apiKeyIndex ?? (await this.findFreeApiKeyIndex(params.accountIndex));\n        const keyPair = await generateApiKey();\n        const signed = await signChangePubKey(\n            { url: this.baseUrl, chainId: this.chainId, apiPrivateKey: keyPair.privateKey, apiKeyIndex, accountIndex: params.accountIndex },\n            { publicKey: keyPair.publicKey, nonce: 0, skipNonce: true },\n        );\n        if (!signed.txInfo.includes('\"L1Sig\":\"\"')) {\n            throw new Error(\"LighterOnboarding::signed ChangePubKey is missing the L1Sig placeholder (signer mismatch)\");\n        }\n        Logger.debug(`LighterOnboarding::prepareApiKey::account=${params.accountIndex}, apiKeyIndex=${apiKeyIndex}`);\n        return {\n            accountIndex: params.accountIndex,\n            apiKeyIndex,\n            apiPrivateKey: keyPair.privateKey,\n            publicKey: keyPair.publicKey,\n            txType: signed.txType,\n            txInfo: signed.txInfo,\n            messageToSign: signed.messageToSign,\n        };\n    }\n\n    /**\n     * Step 2: splice the account owner's L1 (EVM) `personal_sign` of `pending.messageToSign` into the tx and\n     * submit it (tx_type 8). Returns the ready-to-use signer context on success.\n     */\n    public async submitApiKey(\n        pending: PendingApiKeyRegistration,\n        l1Signature: string,\n    ): Promise<{ txHash?: string; signer: LighterSignerContext }> {\n        if (!l1Signature) throw new Error(\"LighterOnboarding::l1Signature is required to submit the ChangePubKey\");\n        if (!pending.txInfo.includes('\"L1Sig\":\"\"')) {\n            throw new Error(\"LighterOnboarding::pending ChangePubKey is malformed (missing L1Sig placeholder)\");\n        }\n        // Byte-exact splice of the empty placeholder preserves the signed payload the signer produced.\n        const mergedTxInfo = pending.txInfo.replace('\"L1Sig\":\"\"', `\"L1Sig\":${JSON.stringify(l1Signature)}`);\n        const res = await this.rest.sendChangePubKey(pending.txType, mergedTxInfo);\n        return {\n            txHash: res.tx_hash,\n            signer: { apiPrivateKey: pending.apiPrivateKey, accountIndex: pending.accountIndex, apiKeyIndex: pending.apiKeyIndex },\n        };\n    }\n\n    /**\n     * Full onboarding in one call: resolve the account (from `accountIndex` or `l1Address`), generate + L2-sign\n     * the key, obtain the L1 signature via your wallet callback, submit, and return the trading signer.\n     *\n     * @example\n     * const { signer, apiPrivateKey } = await onboarding.registerApiKey({\n     *   l1Address: wallet.address,\n     *   l1Sign: (msg) => wallet.signMessage(msg), // ethers/viem personal_sign\n     * });\n     * const client = new LighterClient({ signer });\n     */\n    public async registerApiKey(params: {\n        accountIndex?: number;\n        l1Address?: string;\n        apiKeyIndex?: number;\n        /** Account owner's EVM wallet personal_sign of the returned message (e.g. ethers `signMessage`). */\n        l1Sign: (message: string) => string | Promise<string>;\n    }): Promise<{ apiPrivateKey: string; accountIndex: number; apiKeyIndex: number; txHash?: string; signer: LighterSignerContext }> {\n        let accountIndex = params.accountIndex;\n        if (accountIndex == null) {\n            if (!params.l1Address) throw new Error(\"LighterOnboarding::registerApiKey requires accountIndex or l1Address\");\n            accountIndex = await this.resolveAccountIndex(params.l1Address);\n        }\n        const pending = await this.prepareApiKey({ accountIndex, apiKeyIndex: params.apiKeyIndex });\n        const l1Signature = await params.l1Sign(pending.messageToSign);\n        const { txHash, signer } = await this.submitApiKey(pending, l1Signature);\n        return { apiPrivateKey: pending.apiPrivateKey, accountIndex: pending.accountIndex, apiKeyIndex: pending.apiKeyIndex, txHash, signer };\n    }\n\n    /** Confirm a signer's API key is bound on-chain: an authed read succeeds only after the ChangePubKey applies. */\n    public async verifyApiKey(signer: LighterSignerContext): Promise<boolean> {\n        try {\n            await this.rest.getActiveOrders(signer);\n            return true;\n        } catch (err: any) {\n            Logger.debug(`LighterOnboarding::verifyApiKey::not yet bound: ${err?.message}`);\n            return false;\n        }\n    }\n}\n"],"mappings":"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","names":["path","path"]}