/** * Injectable logger. The SDK never logs on its own — it routes through whatever the host app installs * via {@link setLogger}. The default is a no-op so the SDK is silent unless a logger is provided. * * This replaces the internal `Logger` dependency the code carried inside loky-backend; the SDK must not * pull in an application logging stack. */ interface LighterLogger { debug(message: string): void; info(message: string): void; warn(message: string): void; error(message: string): void; } /** Install a logger (e.g. console, pino, winston). Pass nothing / a partial to reset to no-op. */ declare function setLogger(logger: Partial | null | undefined): void; /** * Environment-neutral Lighter signing core. * * Lighter uses a ZK-rollup signature scheme (Poseidon hash over the Goldilocks field, Schnorr-style) * with no JavaScript implementation, so signing runs elliottech's official Go signer compiled to * WebAssembly. This module holds the ABI-level sign functions; loading the WASM is delegated to a * pluggable *instantiator* so the same signing code runs under Node (fs) and the browser (fetch). * * The Node aggregate `./signer` registers the fs instantiator on import; browser consumers call * `initLighterSigner` from `./signer/browser`. Both resolve to a {@link LighterWasmExports} of Go globals. */ /** Auth context handed to the Go client (CreateClient) before each signing call. */ interface LighterClientContext { url: string; /** 304 = zk mainnet, 300 = testnet, 466324 = robinhood mainnet. */ chainId: number; apiPrivateKey: string; accountIndex: number; apiKeyIndex: number; } interface LighterCreateOrderInput { marketIndex: number; clientOrderIndex: number; /** Base amount as an integer scaled by the market's size_decimals (uint48; must be 0..2^48-1). */ baseAmount: bigint | number; /** Price as an integer scaled by the market's price_decimals (must fit uint32). 0 = unset. */ price: number; isAsk: boolean; orderType: number; timeInForce: number; reduceOnly: boolean; triggerPrice?: number; /** IOC/market orders must use 0 (NilOrderExpiry); GTT orders pass an epoch-ms expiry. */ orderExpiry: number; /** Integrator (builder) fee routing; omit or 0 = Nil. Fee is a uint32 fraction of 1e6 (500 = 5 bps). */ integratorAccountIndex?: number; integratorTakerFee?: number; integratorMakerFee?: number; nonce: number; } interface LighterCancelOrderInput { marketIndex: number; orderIndex: number; nonce: number; } interface LighterModifyOrderInput { marketIndex: number; /** The order index (id) to modify. */ orderIndex: number; /** New base amount, integer scaled by size_decimals. */ baseAmount: bigint | number; /** New price, integer scaled by price_decimals (uint32). */ price: number; /** New trigger price for stop/tp orders, integer scaled by price_decimals (0 if none). */ triggerPrice?: number; nonce: number; } interface LighterUpdateLeverageInput { marketIndex: number; /** Integer initial-margin fraction (fraction/100 = margin%). */ fraction: number; /** 0 = cross, 1 = isolated. */ marginMode: number; nonce: number; } /** The signed transaction the REST client POSTs to /api/v1/sendTx. */ interface LighterSignedTx { txType: number; txInfo: string; txHash?: string; } declare function signCreateOrder(ctx: LighterClientContext, input: LighterCreateOrderInput): Promise; interface LighterApiKeyPair { privateKey: string; publicKey: string; } /** Generate a fresh Ed25519 API keypair (for code-based provisioning; association still needs ChangePubKey). */ declare function generateApiKey(): Promise; interface LighterChangePubKeyInput { /** New API public key (hex) being registered at (accountIndex, apiKeyIndex). */ publicKey: string; nonce: number; /** Skip nonce handling (for a brand-new api_key_index whose nonce bootstraps at 0). */ skipNonce?: boolean; } interface LighterChangePubKeyResult { txType: number; /** Signed tx JSON: the L2 self-signature (`Sig`) is set; `L1Sig` is empty and filled by the account owner's wallet. */ txInfo: string; txHash?: string; /** The L1 message the account owner's EVM wallet must sign; its signature merges into `txInfo.L1Sig`. */ messageToSign: string; } /** * Produce the L2 self-signed ChangePubKey tx that registers a new API public key. `ctx.apiPrivateKey` MUST * be the NEW key's private key (the self-signature proves control of the new key). The returned `txInfo` * has an empty `L1Sig`; the account owner's wallet signs `messageToSign` and that signature is merged into * `L1Sig` before submitting to /sendTx (tx_type 8). */ declare function signChangePubKey(ctx: LighterClientContext, input: LighterChangePubKeyInput): Promise; interface LighterApproveIntegratorInput { /** The integrator (partner) account_index that may collect fees on this account's orders. */ integratorAccountIndex: number; /** Max perps taker fee the integrator may charge, as a uint32 fraction of 1e6 (500 = 5 bps). */ maxPerpsTakerFee: number; maxPerpsMakerFee: number; /** Max spot fees (set 0 for perps-only integrators). */ maxSpotTakerFee: number; maxSpotMakerFee: number; /** Absolute approval expiry in epoch MILLISECONDS (Lighter reads this field as ms, not seconds). */ approvalExpiryMs: number; nonce: number; } interface LighterApproveIntegratorResult { txType: number; /** Signed tx JSON: the L2 `Sig` is set; `L1Sig` is empty and filled by the account owner's wallet. */ txInfo: string; txHash?: string; /** The L1 message the account owner's EVM wallet must personal_sign; merged into `txInfo.L1Sig`. */ messageToSign: string; } /** * Produce the L2-signed ApproveIntegrator tx (tx_type 45) authorising `integratorAccountIndex` to charge * up to the given max fees on this account's orders until `approvalExpiryMs`. The integrator account is a * different L1 than the user, so Lighter REQUIRES an L1 signature: the returned `txInfo` has an empty * `L1Sig`, and the account owner's wallet personal_signs `messageToSign`; that signature is merged into * `L1Sig` before submitting to /sendTx. `ctx.apiPrivateKey` is the user's custodial (registered) API key. */ declare function signApproveIntegrator(ctx: LighterClientContext, input: LighterApproveIntegratorInput): Promise; declare function signModifyOrder(ctx: LighterClientContext, input: LighterModifyOrderInput): Promise; declare function signUpdateLeverage(ctx: LighterClientContext, input: LighterUpdateLeverageInput): Promise; /** Mint a short-lived auth token for account-scoped GET reads (trades, fundings, …). */ declare function createAuthToken(ctx: LighterClientContext, deadlineUnixSec?: number): Promise; declare function signCancelOrder(ctx: LighterClientContext, input: LighterCancelOrderInput): Promise; interface LighterCancelAllOrdersInput { /** 0 = immediate, 1 = scheduled (at `time`), 2 = abort a scheduled cancel. Default immediate. */ timeInForce?: number; /** Epoch-ms trigger for a scheduled cancel (timeInForce 1); 0/omitted for immediate. */ time?: number; /** Market index to cancel, or 255 for ALL markets (the signer rejects other out-of-range values). */ marketIndex: number; nonce: number; } /** * Sign an atomic CancelAllOrders tx (tx_type 16) — cancels every resting order (marketIndex 255) or all * orders in one market, in a single transaction. Preferred over cancelling order-by-order: one nonce, one * round trip, and no window for fills between per-order cancels. */ declare function signCancelAllOrders(ctx: LighterClientContext, input: LighterCancelAllOrdersInput): Promise; interface LighterUpdateMarginInput { marketIndex: number; /** USDC amount as an integer scaled to USDC decimals. */ usdcAmount: bigint | number; /** 0 = add margin (isolated), 1 = remove margin. */ direction: number; nonce: number; } /** Sign an add/remove isolated-margin tx (tx_type 29) for a market. */ declare function signUpdateMargin(ctx: LighterClientContext, input: LighterUpdateMarginInput): Promise; interface LighterWithdrawInput { /** Asset index (1-based; USDC = 1). Defaults to 1. */ assetIndex?: number; /** 0 = standard, 1 = fast. Defaults to 0. */ routeType?: number; /** Amount as an integer scaled to the asset's decimals (uint64). */ amount: bigint | number; nonce: number; } /** Sign a withdrawal tx (tx_type 13) moving funds out of the L2 account to the L1 owner. */ declare function signWithdraw(ctx: LighterClientContext, input: LighterWithdrawInput): Promise; interface LighterTransferInput { toAccountIndex: number; /** Asset index (1-based; USDC = 1). Defaults to 1. */ assetIndex?: number; fromRouteType?: number; toRouteType?: number; /** Amount as an integer scaled to the asset's decimals. */ amount: bigint | number; /** USDC fee (scaled). Defaults to 0. */ usdcFee?: bigint | number; /** 32-byte memo as hex (64 hex chars, or 66 with `0x`). Defaults to a zero memo. */ memo?: string; nonce: number; } /** Sign a transfer tx (tx_type 12) moving funds to another Lighter account. */ declare function signTransfer(ctx: LighterClientContext, input: LighterTransferInput): Promise; /** One leg of a grouped order. Trigger/child legs (TP/SL) use baseAmount 0 (they close the main fill). */ interface LighterGroupedOrder { marketIndex: number; clientOrderIndex: number; /** Integer scaled by size_decimals (uint48). 0 for TP/SL legs in an OTOCO bracket. */ baseAmount: bigint | number; /** Integer scaled by price_decimals (uint32). Worst-case bound for market/trigger legs. */ price: number; isAsk: boolean; orderType: number; timeInForce: number; reduceOnly: boolean; triggerPrice?: number; orderExpiry: number; } interface LighterCreateGroupedOrdersInput { /** LighterConstant.GROUPING_TYPE: OTO (1), OCO (2), or OTOCO (3, a bracket). */ groupingType: number; orders: LighterGroupedOrder[]; integratorAccountIndex?: number; integratorTakerFee?: number; integratorMakerFee?: number; nonce: number; } /** * Sign a grouped-orders tx (tx_type 28) — OTO/OCO/OTOCO. The OTOCO form is a bracket: a main entry order * plus reduce-only take-profit and stop-loss legs (their baseAmount is 0; they close whatever the main fills). */ declare function signCreateGroupedOrders(ctx: LighterClientContext, input: LighterCreateGroupedOrdersInput): Promise; /** * Typed error hierarchy so callers can branch on failure kind instead of string-matching messages. * All SDK errors extend {@link LighterError}. */ declare class LighterError extends Error { constructor(message: string); } /** A REST/API call failed: non-2xx HTTP, a non-200 `code`, or an unparseable body. */ declare class LighterApiError extends LighterError { /** The Lighter response `code`, if present. */ readonly code?: number | undefined; /** The HTTP status, if available. */ readonly status?: number | undefined; /** The failing method label (e.g. "createLimitOrder"). */ readonly method?: string | undefined; constructor(message: string, /** The Lighter response `code`, if present. */ code?: number | undefined, /** The HTTP status, if available. */ status?: number | undefined, /** The failing method label (e.g. "createLimitOrder"). */ method?: string | undefined); } /** The WASM signer rejected a request (bad params, out-of-range value, or an internal signer error). */ declare class LighterSignerError extends LighterError { readonly method?: string | undefined; constructor(message: string, method?: string | undefined); } /** Client-side validation failed before hitting the network (bad size, unknown symbol, missing config). */ declare class LighterValidationError extends LighterError { } /** * Integrator (builder) fee routing. Supply this to a {@link LighterRestClientConfig} to attach a partner * fee to orders placed with `applyIntegratorFee: true`. The account must have approved this integrator * on-chain (see the client's approve-integrator flow), else Lighter rejects the fee-bearing order. */ interface LighterIntegratorConfig { /** The integrator (partner) account_index that collects the fee. Instance-local (differs per venue/network). */ accountIndex: number; /** Taker fee as a uint32 fraction of 1e6 (500 = 5 bps). Lighter caps perps at 10 bps (1000). */ takerFee: number; /** Maker fee as a uint32 fraction of 1e6. */ makerFee: number; } /** Supported perp venues: the zk-Lighter L2 (USDC) or the Robinhood-Chain Lighter deployment (USDG). */ type LighterVenue = "zk" | "robinhood"; interface LighterRestClientConfig { /** Default true (mainnet). */ isMainnet?: boolean; /** Override the resolved host (rare); the signer chainId always comes from venue + network. */ baseUrl?: string; /** Perp venue: "zk" (default) or "robinhood". Picks host + signer chainId. */ venue?: LighterVenue; /** Optional builder-fee routing; omit to never attach an integrator fee. */ integrator?: LighterIntegratorConfig | null; } /** One OHLCV candle from /candles or /markPriceCandles. `t` is the open time in epoch ms. */ interface LighterCandle { /** Open time, epoch milliseconds. */ t: number; o: number; h: number; l: number; c: number; /** Base-asset volume. */ v: number; /** Quote-asset (USD) volume. */ V: number; /** Internal candle index/id. */ i?: number; } interface LighterCandlesResponse { code?: number; /** The resolution echoed back by the server. */ r?: string | number; /** Candles, oldest first. */ c: LighterCandle[]; } /** Auth context for signed (write) transactions. */ interface LighterSignerContext { apiPrivateKey: string; accountIndex: number; apiKeyIndex: number; } /** Per-market precision/limits from /api/v1/orderBookDetails. */ interface LighterOrderBookDetail { market_id: number; symbol: string; price_decimals: number; size_decimals: number; supported_price_decimals?: number; supported_size_decimals?: number; min_base_amount: string; min_quote_amount: string; order_quote_limit?: string; taker_fee?: string; maker_fee?: string; last_trade_price?: number; /** Integer initial-margin fractions (fraction/100 = margin%); `min` = max allowed leverage. */ default_initial_margin_fraction?: number; min_initial_margin_fraction?: number; } interface LighterOrderBookDetailsResponse { code?: number; message?: string; order_book_details: LighterOrderBookDetail[]; spot_order_book_details?: LighterOrderBookDetail[]; } interface LighterFundingRate { market_id?: number; /** The /funding-rates endpoint aggregates several venues (binance, bybit, hyperliquid, lighter). */ exchange?: string; symbol: string; rate: number; funding_rate?: number; } interface LighterFundingRatesResponse { code?: number; funding_rates: LighterFundingRate[]; } interface LighterPosition { market_id: number; symbol: string; /** Direction: 1 = long, -1 = short. Size is the unsigned `position`. */ sign: number; /** Unsigned position size as a string. */ position: string; avg_entry_price?: string; position_value?: string; unrealized_pnl?: string; realized_pnl?: string; total_funding_paid_out?: string; liquidation_price?: string; allocated_margin?: string; initial_margin_fraction?: string; margin_mode?: number; } interface LighterAccount { account_index: number; l1_address?: string; collateral?: string; available_balance?: string; total_asset_value?: string; positions?: LighterPosition[]; } interface LighterAccountResponse { code?: number; accounts?: LighterAccount[]; account?: LighterAccount; } interface LighterNextNonceResponse { code?: number; nonce: number; } interface LighterSendTxResponse { code: number; message?: string; tx_hash?: string; predicted_execution_time_ms?: number; volume_quota_remaining?: number; } /** * A fill from GET /api/v1/trades. A trade has two sides; determine which side is *your* account by * matching `ask_account_id` / `bid_account_id` against your account index. */ interface LighterTrade { trade_id?: number | string; tx_hash?: string; type?: string; market_id: number; size: string; price: string; usd_amount?: string; timestamp?: number; ask_account_id?: number; bid_account_id?: number; /** true = the ask (sell) side was the maker; the other side was the taker. */ is_maker_ask?: boolean; taker_fee?: string; maker_fee?: string; ask_account_pnl?: string; bid_account_pnl?: string; } /** Your side of a trade, normalized for accounting. */ interface LighterAccountFill { trade: LighterTrade; /** true = you sold (ask side). */ isAsk: boolean; price: number; size: number; fee: number; /** Realized pnl attributed to your side of this fill. */ pnl: number; timestamp: number; } /** An account's realized funding payment for a position, from GET /api/v1/positionFunding. */ interface LighterPositionFunding { timestamp: number; market_id: number; funding_id?: number; /** Funding amount: negative = paid, positive = received. */ change: string; rate?: string; position_size?: string; position_side?: string; } /** An entry from GET /api/v1/tokenlist (public, no auth). */ interface LighterTokenListItem { symbol: string; name?: string; /** "PERPS" for perp-tradeable tokens. */ market?: string; /** "CRYPTO" | "RWA". */ asset_type?: string; categories?: string[]; is_allowed_mainnet?: boolean; is_asset_allowed_mainnet?: boolean; } interface LighterCreateMarketOrderParams { marketIndex: number; /** Base amount as an integer scaled by the market's size_decimals. */ baseAmount: bigint; isAsk: boolean; reduceOnly: boolean; clientOrderIndex: number; /** Optional worst-case price (integer scaled by price_decimals, uint32) for slippage protection. */ price?: number; /** Attach the configured integrator (builder) fee — only for accounts that have approved it. */ applyIntegratorFee?: boolean; } /** An entry from the account's registered API keys (apikeys endpoint) — used to pick a free api_key_index. */ interface LighterApiKeyEntry { api_key_index?: number; public_key?: string; [key: string]: unknown; } interface LighterCreateLimitOrderParams { marketIndex: number; /** Base amount as an integer scaled by the market's size_decimals. */ baseAmount: bigint; /** Limit price as an integer scaled by the market's price_decimals (uint32). */ price: number; isAsk: boolean; clientOrderIndex: number; /** 'gtc' (good-till-time, 28d max), 'ioc' (immediate-or-cancel), 'alo' (add-liquidity-only / post-only). */ timeInForce?: "gtc" | "ioc" | "alo"; /** Force post-only (rejected if it would take). Overrides timeInForce to post-only. */ postOnly?: boolean; reduceOnly?: boolean; applyIntegratorFee?: boolean; } /** * A resting order from accountActiveOrders. Field names follow Lighter's order conventions; typed * loosely (index signature) so parsing survives shape variance. `order_index` is the id needed to * cancel/modify. */ interface LighterActiveOrder { order_index?: number; client_order_index?: number; market_index?: number; market_id?: number; is_ask?: boolean; price?: string | number; remaining_base_amount?: string | number; initial_base_amount?: string | number; status?: string; type?: number | string; trigger_price?: string | number; reduce_only?: boolean; order_expiry?: number; [key: string]: unknown; } /** * REST client for a single Lighter venue (zk or robinhood) + network. Covers the public read endpoints, * account-scoped authed reads, and the signed write path (/sendTx). Signing is delegated to the WASM * signer; the caller passes a {@link LighterSignerContext} (decrypted API key + account/key indices) per * write call, so the client holds no secrets. */ declare class LighterRestClient { private readonly baseUrl; private readonly chainId; private readonly venue; private readonly isMainnet; private readonly integrator; /** Cached auth tokens per account+key; refreshed before expiry. */ private authTokenCache; private static readonly AUTH_TOKEN_TTL_MS; /** Serializes signed writes per account+key and sequences their nonces (see NonceManager). */ private readonly nonces; constructor(config?: LighterRestClientConfig); private clientContext; private authToken; getOrderBookDetails(): Promise; /** Full token list incl. asset_type (CRYPTO/RWA) and categories. Public, no auth. */ getTokenList(): Promise; /** * Funding rates. The `/funding-rates` endpoint AGGREGATES several venues (binance, bybit, hyperliquid, * lighter), so this defaults to Lighter's own rows only — otherwise a naive `find(symbol)` can return * another exchange's rate. Pass `{ exchange: null }` for the raw aggregated set, or another venue name. */ getFundingRates(options?: { exchange?: string | null; }): Promise; /** Raw aggregated funding rates across ALL venues (binance/bybit/hyperliquid/lighter). */ getAllFundingRates(): Promise; getAccount(accountIndex: number): Promise; getAccountsByL1Address(l1Address: string): Promise; /** * The account's registered API keys. `api_key_index=255` returns all slots. Used to pick a free * programmatic slot (>= 4). Public read (returns public keys, no secrets). */ getApiKeys(accountIndex: number): Promise; getPositions(accountIndex: number): Promise; /** Account-scoped fills. Requires auth (minted per account+key and cached). */ getAccountTrades(ctx: LighterSignerContext, params?: { marketId?: number; limit?: number; orderIndex?: number; }): Promise; /** * Resting (active) orders for an account. Requires auth. `marketId` defaults to all markets. * Used to resolve a user-facing order id -> `order_index` (+ market) for cancel/modify, and to * enumerate orders for a cancel-all. */ getActiveOrders(ctx: LighterSignerContext, params?: { marketId?: number; }): Promise; /** * VERIFY ON-CHAIN that the account has approved the configured integrator. Lighter exposes NO read API * for integrator approvals (not in accountLimits/account, no dedicated endpoint), so we PROBE: attempt a * tiny far-from-market resting limit carrying the integrator fee. Lighter rejects it with "integrator is * not approved" for an unapproved / insufficient-max-fee / expired account, and accepts it otherwise * (Lighter itself checks the approved account, max fee and expiry). On acceptance we immediately cancel * the canary and return true. Non-integrator errors are rethrown (indeterminate). */ probeIntegratorApproved(ctx: LighterSignerContext): Promise; /** An account's realized funding payments per position. Requires auth. */ getPositionFunding(ctx: LighterSignerContext, params?: { marketId?: number; limit?: number; startTimestamp?: number; endTimestamp?: number; }): Promise; /** * OHLCV candles. All of market_id, resolution, start/end_timestamp (ms) and count_back are * required by the API. Response: { code, r, c: [{ t,o,h,l,c,v,V,i }] } (max 500 per call). */ getCandles(params: { market_id: number; resolution: string; start_timestamp: number; end_timestamp: number; count_back: number; set_timestamp_to_end?: boolean; }): Promise; /** * Mark-price OHLCV candles. Mark price (not last trade) drives margin and liquidation, so use these for * risk math. Same required params as {@link getCandles}. */ getMarkPriceCandles(params: { market_id: number; resolution: string; start_timestamp: number; end_timestamp: number; count_back: number; set_timestamp_to_end?: boolean; }): Promise; /** Full order books (levels) for all markets, or one market when `marketId` is given. */ getOrderBooks(marketId?: number): Promise; /** Public recent trades for a market (no auth). */ getRecentTrades(marketId: number, limit?: number): Promise; /** Account tier + trading limits (rate/volume/size caps). Requires auth (account-scoped). */ getAccountLimits(ctx: LighterSignerContext): Promise; /** * Closed / historical (inactive) orders for an account — needed for reconciliation. Requires auth. * `marketId` defaults to all markets. */ getInactiveOrders(ctx: LighterSignerContext, params?: { marketId?: number; limit?: number; }): Promise; getNextNonce(accountIndex: number, apiKeyIndex: number): Promise; /** Look up a transaction by hash. Response shape is passthrough (includes a `status`). */ getTransaction(hash: string): Promise; /** * Poll a transaction by hash until it reaches a terminal state (executed/committed or failed/rejected) * or `timeoutMs` elapses. Returns the final transaction object. Statuses are matched case-insensitively. */ waitForTransaction(hash: string, opts?: { timeoutMs?: number; intervalMs?: number; }): Promise; /** * Integrator (builder) fee params for the signer. Only attached when the caller opts in * (`applyIntegratorFee`) AND an integrator is configured on this client. */ private integratorInput; createMarketOrder(ctx: LighterSignerContext, params: LighterCreateMarketOrderParams): Promise; /** * Place a resting LIMIT order. `timeInForce`/`postOnly` map to Lighter's TIF: * ioc -> IMMEDIATE_OR_CANCEL (expiry 0), alo/postOnly -> POST_ONLY, gtc (default) -> GOOD_TILL_TIME. * GTT orders require a non-nil expiry; -1 lets the signer set 28 days (Lighter's max resting life). */ createLimitOrder(ctx: LighterSignerContext, params: LighterCreateLimitOrderParams): Promise; /** * Place a reduce-only TAKE_PROFIT or STOP_LOSS trigger order (native TP/SL for a single-leg position). * Lighter requires: perps market, IOC, a non-nil trigger price and a non-nil expiry (we pass -1 → 28d), * and price >= 1 (worst-case execution bound). */ createTriggerOrder(ctx: LighterSignerContext, params: { marketIndex: number; baseAmount: bigint | number; isAsk: boolean; /** ORDER_TYPE.TAKE_PROFIT or ORDER_TYPE.STOP_LOSS. */ orderType: number; /** Trigger price, integer scaled by price_decimals (uint32). */ triggerPrice: number; /** Worst-case execution price bound, integer scaled by price_decimals (uint32, >= 1). */ price: number; clientOrderIndex: number; /** Attach the configured integrator (builder) fee — only for accounts that have approved. */ applyIntegratorFee?: boolean; }): Promise; /** Set per-market leverage. `leverage` is converted to Lighter's margin fraction (clamped by min). */ updateLeverage(ctx: LighterSignerContext, params: { marketIndex: number; leverage: number; marginMode?: number; minFraction?: number; }): Promise; cancelOrder(ctx: LighterSignerContext, params: { marketIndex: number; orderIndex: number; }): Promise; /** * Atomically cancel every resting order (marketIndex 255 = all markets, the default) or all orders in a * single market, in ONE tx (tx_type 16). Preferred over cancelling order-by-order — one nonce, one round * trip, no window for fills between per-order cancels. */ cancelAllOrders(ctx: LighterSignerContext, params?: { marketIndex?: number; timeInForce?: number; time?: number; }): Promise; /** Modify a resting order's size/price/trigger. */ modifyOrder(ctx: LighterSignerContext, params: { marketIndex: number; orderIndex: number; baseAmount: bigint | number; price: number; triggerPrice?: number; }): Promise; /** Add or remove isolated margin on a market (tx 29). `usdcAmount` is scaled to USDC decimals. */ updateMargin(ctx: LighterSignerContext, params: { marketIndex: number; usdcAmount: bigint | number; direction: number; }): Promise; /** Withdraw funds from the L2 account back to the L1 owner (tx 13). `amount` scaled to asset decimals. */ withdraw(ctx: LighterSignerContext, params: { amount: bigint | number; assetIndex?: number; routeType?: number; }): Promise; /** * Transfer funds to another Lighter account (tx 12). `amount` scaled to asset decimals. * * ADVANCED: a transfer additionally requires the account owner's L1 (EVM) signature merged into the tx's * `L1Sig` field — the L2 signature alone is rejected ("fail to l1 signature"). This method signs only the * L2 part; the caller is responsible for constructing + merging the L1 signature per Lighter's transfer * message spec before it will be accepted. Withdrawals do NOT need this. */ transfer(ctx: LighterSignerContext, params: { toAccountIndex: number; amount: bigint | number; assetIndex?: number; usdcFee?: bigint | number; memo?: string; }): Promise; /** * Submit a grouped order (tx 28): OTO / OCO / OTOCO (bracket). Orders are pre-scaled legs; use the * high-level client's `placeBracketOrder` for a human-unit API. */ createGroupedOrders(ctx: LighterSignerContext, params: { groupingType: number; orders: LighterGroupedOrder[]; applyIntegratorFee?: boolean; }): Promise; /** * Submit a fully-signed ChangePubKey tx (tx_type 8) whose txInfo already has both the L2 self-signature * and the merged-in L1 signature. Used to bind a new API key on-chain. */ sendChangePubKey(txType: number, txInfo: string): Promise; /** * L2-sign an ApproveIntegrator (tx_type 45) authorising this client's configured integrator account to * charge up to its fee on the account's orders, until now+TTL (ms). The returned `txInfo` has an empty * `L1Sig`; the account owner's wallet personal_signs `messageToSign` and that signature is spliced into * `L1Sig` before `sendApproveIntegrator`. `nonce` is returned so the caller can persist it (the signed * nonce is part of the L1 message, so it cannot be changed after the user signs). */ buildApproveIntegrator(ctx: LighterSignerContext, approvalExpiryMs: number): Promise<{ txType: number; txInfo: string; messageToSign: string; nonce: number; integratorAccountIndex: number; }>; /** Submit the ApproveIntegrator tx (L1Sig already merged in) to /sendTx. */ sendApproveIntegrator(txType: number, txInfo: string): Promise; private sendTx; private getJsonAuthed; private getJson; } /** A parsed inbound WebSocket message. Lighter tags every frame with a `type` like `update/order_book` * or `subscribed/account_all_trades`, and (for channel streams) echoes the `channel` it belongs to. */ interface LighterWsMessage { /** e.g. "connected", "subscribed/order_book", "update/order_book", "ping", "pong". */ type: string; /** The channel this frame belongs to, when applicable (e.g. "order_book/1"). */ channel?: string; [key: string]: unknown; } /** Minimal structural type for a WebSocket constructor (browser `WebSocket` or the Node `ws` package). */ interface WebSocketLike { readonly readyState: number; send(data: string): void; close(code?: number, reason?: string): void; onopen: ((ev: any) => void) | null; onclose: ((ev: any) => void) | null; onerror: ((ev: any) => void) | null; onmessage: ((ev: any) => void) | null; } type WebSocketCtor = new (url: string) => WebSocketLike; interface LighterWsConfig { /** Perp venue: "zk" (default) or "robinhood". Picks the stream host. */ venue?: "zk" | "robinhood"; /** Default true (mainnet). */ isMainnet?: boolean; /** Full override of the wss URL (rare); otherwise derived from venue + network. */ url?: string; /** Connect read-only (appends ?readonly=true). */ readonly?: boolean; /** * WebSocket implementation. Defaults to the global `WebSocket` (browser / Node >= 22); on older Node, * the SDK dynamically imports the optional `ws` package. Pass this to force a specific implementation. */ WebSocketImpl?: WebSocketCtor; /** * Provider for the account-channel auth token. Required to subscribe to authenticated channels * (`account_*`, `user_stats`, `pool_*`, `notification`, `rfq`) — those subscribe frames carry an * `auth` field. Re-invoked on each (re)subscribe so an expiring token (~7h) is refreshed on reconnect. */ getAuthToken?: () => string | Promise; /** Keepalive frame interval (ms). Must be < 120000 (server closes idle connections at 2 min). Default 30000. */ keepAliveMs?: number; /** Auto-reconnect on unexpected close. Default true. */ autoReconnect?: boolean; /** Initial reconnect backoff (ms). Default 1000. */ reconnectBaseMs?: number; /** Max reconnect backoff (ms). Default 30000. */ reconnectMaxMs?: number; } type LighterWsEvent = "open" | "close" | "error" | "message" | "reconnect"; type LighterWsHandler = (payload: any) => void; type LighterChannelHandler = (message: LighterWsMessage) => void; /** Call to remove a subscription/listener. */ type Unsubscribe = () => void; /** * WebSocket client for Lighter's streaming API. Handles connection lifecycle, keepalive (server closes * idle sockets after 2 minutes), automatic reconnect with exponential backoff, and re-subscription of all * active channels after a reconnect. Works in the browser (global `WebSocket`) and Node (the `ws` package * or global `WebSocket` on Node >= 22). * * Dispatch: every inbound frame goes to `on("message", …)` listeners; channel frames additionally go to the * handlers registered for their channel. Channel matching normalizes `:`/`/` separators so it is robust to * the server echoing `order_book:1` vs `order_book/1`. */ declare class LighterWs { private readonly url; private readonly keepAliveMs; private readonly autoReconnect; private readonly reconnectBaseMs; private readonly reconnectMaxMs; private readonly wsCtorInject?; private readonly getAuthToken?; private ws; private wsCtor; private closedByUser; /** True once a socket has opened at least once — gates auto-reconnect so a failed initial connect stays dead. */ private everConnected; private reconnectAttempts; private keepAliveTimer; private reconnectTimer; /** Channels the caller wants subscribed; resent on every (re)connect. */ private desiredChannels; /** Per-channel handlers, keyed by normalized channel string. */ private channelHandlers; /** Lifecycle/message listeners. */ private listeners; constructor(config?: LighterWsConfig); /** Account-scoped channels whose subscribe frame must carry an `auth` token. */ private static needsAuth; /** Open the socket. Resolves once connected (or rejects if the first connect fails). */ connect(): Promise; private openSocket; /** Close the socket and cancel reconnection/keepalive. */ close(): void; private scheduleReconnect; private startKeepAlive; private stopKeepAlive; private handleMessage; private sendSubscribe; private sendUnsubscribe; private sendFrame; private static normalizeChannel; /** * Subscribe to a raw channel string (e.g. "order_book/1", "account_all/7"). Returns an unsubscribe * handle. Safe to call before `connect()`: the subscription is (re)sent on every connect. */ subscribe(channel: string, handler: LighterChannelHandler): Unsubscribe; /** Order book snapshot + batched deltas for a market. */ subscribeOrderBook(marketIndex: number, handler: LighterChannelHandler): Unsubscribe; /** Public trade prints for a market. */ subscribeTrades(marketIndex: number, handler: LighterChannelHandler): Unsubscribe; /** Best bid/offer ticker for a market. */ subscribeTicker(marketIndex: number, handler: LighterChannelHandler): Unsubscribe; /** Rolling market stats for one market, or all markets with "all". */ subscribeMarketStats(marketIndexOrAll: number | "all", handler: LighterChannelHandler): Unsubscribe; /** All account state (balances, positions, orders) for an account. */ subscribeAccountAll(accountIndex: number, handler: LighterChannelHandler): Unsubscribe; /** All open/closed orders for an account. */ subscribeAccountOrders(accountIndex: number, handler: LighterChannelHandler): Unsubscribe; /** All positions for an account. */ subscribeAccountPositions(accountIndex: number, handler: LighterChannelHandler): Unsubscribe; /** All fills for an account. */ subscribeAccountTrades(accountIndex: number, handler: LighterChannelHandler): Unsubscribe; /** Register a lifecycle/message listener. Returns an unsubscribe handle. */ on(event: LighterWsEvent, handler: LighterWsHandler): Unsubscribe; private emit; /** True when the socket is open. */ get isConnected(): boolean; } /** Long = buy (is_ask false); short = sell (is_ask true). */ type OrderSide = "long" | "short"; /** Resolved, cached per-market metadata used to scale human values to the API's integers. */ interface LighterMarketMeta { marketId: number; symbol: string; priceDecimals: number; sizeDecimals: number; /** Minimum order size in human token units. */ minBaseAmount: number; /** Minimum order notional in human quote units. */ minQuoteAmount: number; /** Max leverage the market allows (= SCALE / min_initial_margin_fraction); 0 when the market omits it. */ maxLeverage: number; minInitialMarginFraction: number; lastTradePrice: number; } interface LighterClientConfig extends LighterRestClientConfig { /** Default signer context for write calls, so per-call ctx is optional. */ signer?: LighterSignerContext; /** Default market-order slippage bound (fraction) when a call omits `slippage`. Default 0.05 (5%). */ defaultSlippage?: number; /** Refresh market data before a market order if older than this (ms). Default 15000. */ marketStalenessMs?: number; /** Provider for the WS account-channel auth token; wired into the internal WS client. */ getAuthToken?: () => string | Promise; /** Advanced/testing override for the underlying REST client. */ restClient?: LighterRestClient; /** Advanced/testing override for the underlying WS client. */ wsClient?: LighterWs; } interface PlaceMarketOrderParams { symbol: string; side: OrderSide; /** Order size in human token units (scaled to size_decimals internally). */ size: number | string; reduceOnly?: boolean; /** Optional slippage bound (fraction, e.g. 0.02 = 2%) applied to last price for a worst-case price. */ slippage?: number; applyIntegratorFee?: boolean; clientOrderIndex?: number; } interface PlaceLimitOrderParams { symbol: string; side: OrderSide; /** Size in human token units. */ size: number | string; /** Limit price in human quote units (scaled to price_decimals internally). */ price: number | string; timeInForce?: "gtc" | "ioc" | "alo"; postOnly?: boolean; reduceOnly?: boolean; applyIntegratorFee?: boolean; clientOrderIndex?: number; } interface PlaceBracketOrderParams { symbol: string; /** Entry side. Take-profit/stop-loss close the opposite way automatically. */ side: OrderSide; /** Entry size in human token units. */ size: number | string; /** Entry as a market order (default) or a resting limit at `price`. */ entry?: { type: "market"; slippage?: number; } | { type: "limit"; price: number | string; }; /** Take-profit trigger price (human quote units). Provide TP and/or SL — at least one is required. */ takeProfit?: number | string; /** Stop-loss trigger price (human quote units). */ stopLoss?: number | string; applyIntegratorFee?: boolean; } /** * High-level, venue-aware convenience client over {@link LighterRestClient} and {@link LighterWs}. It * resolves markets by symbol, scales human sizes/prices to Lighter's integer encoding using each market's * decimals, maps long/short to is_ask, and streams by symbol. It is pure sugar — every low-level path is * still reachable through `.rest` and `.ws`. */ declare class LighterClient { readonly rest: LighterRestClient; private readonly venue; private readonly isMainnet; private readonly defaultSigner?; private readonly defaultSlippage; private readonly marketStalenessMs; private readonly getAuthToken?; private wsClient; private readonly wsInjected; private marketsBySymbol; private marketsById; private marketsLoadedAt; private coiCounter; constructor(config?: LighterClientConfig); /** Fetch + cache market metadata (idempotent unless `force`). Auto-called by symbol-based methods. */ loadMarkets(force?: boolean): Promise; /** Reload market data if the cache is older than `maxAgeMs` (keeps the market-order price bound fresh). */ private ensureFreshMarkets; private static toMeta; /** All cached markets (loads on first call). */ markets(): Promise; /** Resolve a market by symbol from cache; throws if not loaded/unknown. Call `loadMarkets()` first. */ market(symbol: string): LighterMarketMeta; /** Market index for a symbol (loads markets if needed). */ marketId(symbol: string): Promise; private requireSigner; private nextClientOrderIndex; /** Reject an order that is below the market's minimum size or notional before it burns a nonce. */ private assertOrderMinimums; /** * Place a market order (size in tokens). A worst-case price bound is ALWAYS sent — from `slippage`, * else the client's `defaultSlippage` (5%) — computed off a freshly-refreshed last price, so a market * buy can fill and a sell is slippage-protected. Never signs an unbounded (price 0) order. */ placeMarketOrder(params: PlaceMarketOrderParams, ctx?: LighterSignerContext): Promise; /** Place a resting/IOC limit order (size in tokens, price in quote units). */ placeLimitOrder(params: PlaceLimitOrderParams, ctx?: LighterSignerContext): Promise; /** * Place a bracket order in ONE atomic transaction: a market/limit entry plus a take-profit and/or * stop-loss that close the position automatically. TP+SL = OTOCO; a single TP or SL = OTO. Prices and * size are human units; the TP/SL legs are reduce-only and close whatever the entry fills. */ placeBracketOrder(params: PlaceBracketOrderParams, ctx?: LighterSignerContext): Promise; /** Add or remove isolated margin on a market. `amount` is in human USDC. */ adjustMargin(params: { symbol: string; amount: number | string; action: "add" | "remove"; }, ctx?: LighterSignerContext): Promise; /** Market-close the open position in `symbol` (reduce-only). Returns null if already flat. */ closePosition(symbol: string, ctx?: LighterSignerContext): Promise; /** Market-close every open position (reduce-only). Continues past individual failures. */ closeAllPositions(ctx?: LighterSignerContext): Promise>; /** * Withdraw USDC from the L2 account back to the L1 owner. `amount` is in human USDC. Defaults to the * fast route (the standard route is not available on all networks). * * Note: account transfers to another Lighter account additionally require the account owner's L1 * signature (like onboarding). Use the low-level `client.rest.transfer` + your own L1 signing for that. */ withdraw(params: { amount: number | string; routeType?: number; }, ctx?: LighterSignerContext): Promise; /** Poll a transaction hash until it reaches a terminal state (see {@link LighterRestClient.waitForTransaction}). */ waitForTransaction(hash: string, opts?: { timeoutMs?: number; intervalMs?: number; }): Promise; /** Set per-market leverage (clamped to the market's max). */ setLeverage(params: { symbol: string; leverage: number; marginMode?: number; }, ctx?: LighterSignerContext): Promise; /** Cancel a specific resting order by its order_index. */ cancelOrder(symbol: string, orderIndex: number, ctx?: LighterSignerContext): Promise; /** * Atomically cancel every resting order for the account (or all orders in one symbol) in a single tx. * One nonce, one round trip, no window for fills between cancels — unlike a per-order loop. */ cancelAllOrders(ctx?: LighterSignerContext, symbol?: string): Promise; getAccount(accountIndex?: number): Promise; getPositions(accountIndex?: number): Promise; getOpenOrders(symbol?: string, ctx?: LighterSignerContext): Promise; /** * WS account-channel auth provider: the explicit `getAuthToken` config, else one minted from the * default signer (so `streamAccount*` works out of the box when a signer is configured). */ private resolveAuthProvider; /** The underlying WebSocket client (lazily created for this venue/network). */ get ws(): LighterWs; /** Connect the WebSocket (loads markets too, so symbol-based streams resolve). */ connect(): Promise; /** Stream the order book for a symbol (markets must be loaded; call `connect()`/`loadMarkets()` first). */ streamOrderBook(symbol: string, handler: LighterChannelHandler): Unsubscribe; /** Stream public trades for a symbol. */ streamTrades(symbol: string, handler: LighterChannelHandler): Unsubscribe; /** Stream all account updates (balances, positions, orders). */ streamAccount(handler: LighterChannelHandler, accountIndex?: number): Unsubscribe; /** Close the WebSocket if this client owns it. */ close(): void; } interface LighterOnboardingConfig { /** Perp venue: "zk" (default) or "robinhood". */ venue?: LighterVenue; /** Default true (mainnet). */ isMainnet?: boolean; /** Advanced/testing override for the underlying REST client. */ restClient?: LighterRestClient; } /** * A generated-but-not-yet-registered API key. The caller must (1) have the account owner's EVM wallet * personal_sign `messageToSign`, then (2) submit via `submitApiKey`. STORE `apiPrivateKey` securely — it is * the credential you sign orders with and cannot be recovered. */ interface PendingApiKeyRegistration { accountIndex: number; apiKeyIndex: number; /** The new API key's private key — persist this; it is your trading credential. */ apiPrivateKey: string; /** The new API key's public key (being registered on-chain). */ publicKey: string; /** tx_type 8 (ChangePubKey). */ txType: number; /** L2-signed tx with an empty `L1Sig` placeholder to be filled by the account owner's L1 signature. */ txInfo: string; /** The message the account owner's EVM wallet must personal_sign; its signature completes the tx. */ messageToSign: string; } /** * Onboarding helper: associate a programmatic API key with a Lighter account so the SDK can sign trades. * * Prerequisite: the account must already exist (create one by depositing via Lighter's L1 bridge). This * helper does the API-key association (a ChangePubKey, tx_type 8), which is a two-signature handshake: * 1. the SDK generates a fresh API keypair and L2 self-signs the ChangePubKey (proving control of the new key); * 2. the account owner's EVM wallet personal_signs the returned `messageToSign` (proving account ownership); * 3. that L1 signature is spliced in and the tx submitted. * * Use {@link registerApiKey} for the full flow with an injected wallet signer, or the two-step * {@link prepareApiKey} / {@link submitApiKey} when the wallet signature happens elsewhere (e.g. a frontend). */ declare class LighterOnboarding { private readonly rest; private readonly baseUrl; private readonly chainId; constructor(config?: LighterOnboardingConfig); /** All Lighter accounts (sub-accounts) owned by an L1 (EVM) wallet address. */ getAccounts(l1Address: string): Promise; /** Resolve the primary account index for an L1 wallet; throws if the wallet has no Lighter account yet. */ resolveAccountIndex(l1Address: string): Promise; /** Pick the lowest free programmatic api_key_index (>= 4; slots 0-3 are reserved for desktop/mobile). */ findFreeApiKeyIndex(accountIndex: number): Promise; /** * Step 1: generate a fresh API keypair and L2 self-sign a ChangePubKey for `accountIndex`. Returns the * pending registration, including `messageToSign` for the account owner's wallet and `apiPrivateKey` * (STORE IT). A fresh slot has never been used, so the nonce bootstraps at 0 (skipNonce). */ prepareApiKey(params: { accountIndex: number; apiKeyIndex?: number; }): Promise; /** * Step 2: splice the account owner's L1 (EVM) `personal_sign` of `pending.messageToSign` into the tx and * submit it (tx_type 8). Returns the ready-to-use signer context on success. */ submitApiKey(pending: PendingApiKeyRegistration, l1Signature: string): Promise<{ txHash?: string; signer: LighterSignerContext; }>; /** * Full onboarding in one call: resolve the account (from `accountIndex` or `l1Address`), generate + L2-sign * the key, obtain the L1 signature via your wallet callback, submit, and return the trading signer. * * @example * const { signer, apiPrivateKey } = await onboarding.registerApiKey({ * l1Address: wallet.address, * l1Sign: (msg) => wallet.signMessage(msg), // ethers/viem personal_sign * }); * const client = new LighterClient({ signer }); */ registerApiKey(params: { accountIndex?: number; l1Address?: string; apiKeyIndex?: number; /** Account owner's EVM wallet personal_sign of the returned message (e.g. ethers `signMessage`). */ l1Sign: (message: string) => string | Promise; }): Promise<{ apiPrivateKey: string; accountIndex: number; apiKeyIndex: number; txHash?: string; signer: LighterSignerContext; }>; /** Confirm a signer's API key is bound on-chain: an authed read succeeds only after the ChangePubKey applies. */ verifyApiKey(signer: LighterSignerContext): Promise; } /** * Static Lighter protocol constants: venues, hosts, signer chain ids, endpoint paths, and the * enum codes used across the order/leverage/tx APIs. Product-neutral — no integrator/partner accounts * are baked in; a builder (integrator) fee is supplied per-client by the caller (see LighterRestClient). */ declare class LighterConstant { static readonly NETWORK = "lighter"; /** Chain ids passed to the Go signer's CreateClient. */ static readonly CHAIN_ID_MAINNET = 304; static readonly CHAIN_ID_TESTNET = 300; /** * Perp venues. The zk-Lighter L2 (USDC) and the Robinhood-Chain Lighter instance (USDG) are separate * Lighter deployments: same signing scheme and REST shapes, but a different host, signer chainId, and * account namespace (a user's account_index on one is unrelated to the other). */ static readonly VENUE: { readonly ZK: "zk"; readonly ROBINHOOD: "robinhood"; }; /** * Host + signer chainId per venue. Robinhood-Chain Lighter mainnet signs with chainId 466324 * (NOT 4663 — that is Robinhood Chain's Ethereum L2 id, a different number). */ static readonly VENUE_CONFIG: { readonly zk: { readonly mainnetBaseUrl: "https://mainnet.zklighter.elliot.ai"; readonly testnetBaseUrl: "https://testnet.zklighter.elliot.ai"; readonly chainIdMainnet: 304; readonly chainIdTestnet: 300; }; readonly robinhood: { readonly mainnetBaseUrl: "https://api.rh.lighter.xyz"; readonly testnetBaseUrl: "https://api.rh-testnet.lighter.xyz"; readonly chainIdMainnet: 466324; readonly chainIdTestnet: 300; }; }; /** Resolve base URL + signer chainId for a venue and network. */ static resolveVenue(venue: string, isMainnet: boolean): { baseUrl: string; chainId: number; }; /** API-key indexes {0,1,2,3} are reserved by Lighter for desktop/mobile; programmatic keys start at 4. */ static readonly RESERVED_API_KEY_INDEX_MAX = 3; /** api_key_index is a uint8 in the signer ABI, so the usable programmatic range is 4..255. */ static readonly MAX_API_KEY_INDEX = 255; static readonly ENDPOINTS: { readonly status: "/api/v1/status"; readonly tokenlist: "/api/v1/tokenlist"; readonly orderBooks: "/api/v1/orderBooks"; readonly orderBookDetails: "/api/v1/orderBookDetails"; readonly account: "/api/v1/account"; readonly accountsByL1Address: "/api/v1/accountsByL1Address"; readonly apikeys: "/api/v1/apikeys"; readonly accountLimits: "/api/v1/accountLimits"; readonly accountActiveOrders: "/api/v1/accountActiveOrders"; readonly accountInactiveOrders: "/api/v1/accountInactiveOrders"; readonly positionFunding: "/api/v1/positionFunding"; readonly pnl: "/api/v1/pnl"; readonly trades: "/api/v1/trades"; readonly recentTrades: "/api/v1/recentTrades"; readonly fundings: "/api/v1/fundings"; readonly fundingRates: "/api/v1/funding-rates"; readonly candles: "/api/v1/candles"; readonly markPriceCandles: "/api/v1/markPriceCandles"; readonly nextNonce: "/api/v1/nextNonce"; readonly transaction: "/api/v1/transaction"; readonly sendTx: "/api/v1/sendTx"; readonly sendTxBatch: "/api/v1/sendTxBatch"; }; /** * uint8 transaction-type codes for POST /sendTx. The WASM signer returns the txType alongside * the signed txInfo, so these are informational/fallback — confirm exact values against * `github.com/elliottech/lighter-go` constants before relying on them directly. */ static readonly TX_TYPE: { readonly changePubKey: 8; readonly transfer: 12; readonly withdraw: 13; readonly createOrder: 14; readonly cancelOrder: 15; readonly cancelAllOrders: 16; readonly modifyOrder: 17; readonly updateLeverage: 20; readonly createGroupedOrders: 28; readonly updateMargin: 29; readonly approveIntegrator: 45; }; /** Grouped-order strategies for SignCreateGroupedOrders (verified against the signer). */ static readonly GROUPING_TYPE: { /** One-Triggers-Other: a main order that, once filled, activates a second (2 orders). */ readonly OTO: 1; /** One-Cancels-Other: two equal-size orders; filling one cancels the other (2 orders). */ readonly OCO: 2; /** One-Triggers-A-One-Cancels-Other (bracket): main entry + TP + SL (3 orders). */ readonly OTOCO: 3; }; /** SignUpdateMargin direction. */ static readonly MARGIN_DIRECTION: { readonly ADD: 0; readonly REMOVE: 1; }; /** Withdraw/transfer route types (0 = standard/slow, 1 = fast). */ static readonly ROUTE_TYPE: { readonly STANDARD: 0; readonly FAST: 1; }; /** USDC asset index (asset indices are 1-based; the signer rejects 0). */ static readonly ASSET_INDEX_USDC = 1; /** A zero 32-byte transfer memo (the signer requires a 32-byte hex memo). */ static readonly ZERO_MEMO: string; /** A reasonable default ApproveIntegrator validity window (epoch MS). The user re-approves after this. */ static readonly INTEGRATOR_APPROVAL_TTL_MS: number; /** Lighter order-type codes (verified against elliottech/lighter-python SignerClient). */ static readonly ORDER_TYPE: { readonly LIMIT: 0; readonly MARKET: 1; readonly STOP_LOSS: 2; readonly STOP_LOSS_LIMIT: 3; readonly TAKE_PROFIT: 4; readonly TAKE_PROFIT_LIMIT: 5; readonly TWAP: 6; }; /** Lighter time-in-force codes (verified against elliottech/lighter-python SignerClient). */ static readonly TIME_IN_FORCE: { readonly IMMEDIATE_OR_CANCEL: 0; readonly GOOD_TILL_TIME: 1; readonly POST_ONLY: 2; }; /** Lighter uses `is_ask`: true = sell/short leg, false = buy/long leg. */ static readonly IS_ASK: { readonly SHORT: true; readonly LONG: false; }; /** Margin modes for SignUpdateLeverage. */ static readonly MARGIN_MODE: { readonly CROSS: 0; readonly ISOLATED: 1; }; /** client_order_index is a uint48 in the order tx; must stay below 2^48. */ static readonly MAX_CLIENT_ORDER_INDEX = 281474976710655; /** base_amount is a uint48 in the order tx (the WASM signer rejects larger values). 2^48 - 1. */ static readonly MAX_BASE_AMOUNT = 281474976710655; /** SignCancelAllOrders market index sentinel: 255 = cancel across all markets (verified against the signer). */ static readonly CANCEL_ALL_MARKETS = 255; /** SignCancelAllOrders time-in-force: 0 = immediate, 1 = scheduled (at `time`), 2 = abort a scheduled cancel. */ static readonly CANCEL_ALL_TIME_IN_FORCE: { readonly IMMEDIATE: 0; readonly SCHEDULED: 1; readonly ABORT: 2; }; /** * Initial-margin-fraction scale: an integer `fraction` maps to margin% = fraction/100, so * leverage = 10000 / fraction (e.g. 500 → 5.00% → 20x). 1x = 10000 (the upper bound). */ static readonly MARGIN_FRACTION_SCALE = 10000; /** Funding is paid hourly on Lighter perps. */ static readonly FUNDING_INTERVAL_SECONDS = 3600; /** Integrator (builder) fee is a uint32 fraction of this tick: 500 = 5 bps. Lighter caps perps at 10 bps. */ static readonly INTEGRATOR_FEE_TICK = 1000000; } /** * Pure, dependency-free helpers for Lighter's fixed-point encoding and URL building. Lighter encodes * base amounts with a market's `size_decimals` and prices with its `price_decimals`; these convert * between human decimals and the scaled integers the signer/API expect. */ declare class LighterHelper { static toQueryString(params: Record): string; static buildUrl(baseUrl: string, endpoint: string, query?: Record): string; /** * Scale a decimal value to Lighter's integer representation (floor extra precision). * Lighter base amounts use `size_decimals` and prices use `price_decimals`. */ static scaleToInt(value: number | string, decimals: number): bigint; static toBaseAmount(size: number | string, sizeDecimals: number): bigint; static toPriceInt(price: number | string, priceDecimals: number): bigint; /** Floor `value` to the nearest multiple of `step` (both integers already scaled to the same decimals). */ static floorToStep(value: bigint, step: bigint): bigint; /** Convert a scaled integer back to a human-readable decimal string. */ static fromScaledInt(value: bigint, decimals: number): string; /** * Convert a target leverage to Lighter's integer initial-margin fraction. * leverage = SCALE / fraction, so fraction = round(SCALE / leverage). Clamped to * [minFraction, SCALE] — `minFraction` (the market's min_initial_margin_fraction) caps leverage, * SCALE (=10000) is 1x. */ static leverageToMarginFraction(leverage: number, minFraction?: number): number; } export { type LighterWithdrawInput as $, type LighterGroupedOrder as A, LighterHelper as B, type LighterIntegratorConfig as C, type LighterLogger as D, type LighterMarketMeta as E, type LighterModifyOrderInput as F, type LighterNextNonceResponse as G, LighterOnboarding as H, type LighterOnboardingConfig as I, type LighterOrderBookDetail as J, type LighterOrderBookDetailsResponse as K, type LighterAccount as L, type LighterPosition as M, type LighterPositionFunding as N, LighterRestClient as O, type LighterRestClientConfig as P, type LighterSendTxResponse as Q, type LighterSignedTx as R, type LighterSignerContext as S, LighterSignerError as T, type LighterTokenListItem as U, type LighterTrade as V, type LighterTransferInput as W, type LighterUpdateLeverageInput as X, type LighterUpdateMarginInput as Y, LighterValidationError as Z, type LighterVenue as _, type LighterAccountFill as a, LighterWs as a0, type LighterWsConfig as a1, type LighterWsEvent as a2, type LighterWsHandler as a3, type LighterWsMessage as a4, type OrderSide as a5, type PendingApiKeyRegistration as a6, type PlaceBracketOrderParams as a7, type PlaceLimitOrderParams as a8, type PlaceMarketOrderParams as a9, type Unsubscribe as aa, type WebSocketCtor as ab, type WebSocketLike as ac, createAuthToken as ad, generateApiKey as ae, setLogger as af, signApproveIntegrator as ag, signCancelAllOrders as ah, signCancelOrder as ai, signChangePubKey as aj, signCreateGroupedOrders as ak, signCreateOrder as al, signModifyOrder as am, signTransfer as an, signUpdateLeverage as ao, signUpdateMargin as ap, signWithdraw as aq, type LighterAccountResponse as b, type LighterActiveOrder as c, LighterApiError as d, type LighterApiKeyEntry as e, type LighterApiKeyPair as f, type LighterApproveIntegratorInput as g, type LighterApproveIntegratorResult as h, type LighterCancelAllOrdersInput as i, type LighterCancelOrderInput as j, type LighterCandle as k, type LighterCandlesResponse as l, type LighterChangePubKeyInput as m, type LighterChangePubKeyResult as n, type LighterChannelHandler as o, LighterClient as p, type LighterClientConfig as q, type LighterClientContext as r, LighterConstant as s, type LighterCreateGroupedOrdersInput as t, type LighterCreateLimitOrderParams as u, type LighterCreateMarketOrderParams as v, type LighterCreateOrderInput as w, LighterError as x, type LighterFundingRate as y, type LighterFundingRatesResponse as z };