npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

lynx-client

v0.0.34

Published

Client library for interacting with Lynx publicly available services

Readme

Lynx Client SDK

A TypeScript SDK for interacting with the Lynx trading protocol across multiple EVM-compatible blockchains.

Features

  • 🔒 Type-safe interfaces for all Lynx smart contracts
  • 🌐 Multi-chain support (16+ EVM chains)
  • 📊 Built-in utilities for price, leverage, and fraction conversions
  • 🏗️ Support for both CommonJS and ESM module systems
  • 🔍 Read-only lens contracts for efficient data aggregation
  • 💼 Complete trading lifecycle management

Installation

npm install lynx-client
yarn add lynx-client

Quick Start

import { 
  connectToLatestRegistry,
  LynxSystemAddresses,
  createTradersPortalService,
  buildPositionRequestIdentifier,
  buildPositionRequestParams
} from 'lynx-client';
import { ethers } from 'ethers';

// Initialize provider
const provider = new ethers.JsonRpcProvider('YOUR_RPC_URL');
const signer = await provider.getSigner();

// Get chain-specific addresses
const addresses = LynxSystemAddresses.arbitrum; // or .sonic, .base, etc.

// Connect to contracts
const registry = connectToLatestRegistry(provider, addresses.registryProxyAddress);

// Create a service for trader operations
const tradersPortal = createTradersPortalService(signer, addresses.tradersPortalAddress);

Core Concepts

Supported Chains

Engine Chains

The Lynx protocol is deployed on the following chains:

  • Sonic (146)
  • Boba (288)
  • Flare (14)
  • Fantom (250)

Source Chains

Assets can be bridged from these additional chains:

  • Ethereum Mainnet (1)
  • Optimism (10)
  • BSC (56)
  • Polygon (137)
  • Fuse (122)
  • Goat (2345)
  • Mantle (5000)
  • Base (8453)
  • Mode (34443)
  • Arbitrum (42161)
  • Celo (42220)
  • Linea (59144)
  • Zircuit (48900)
import { LynxSystemAddresses, TSupportedChainIds } from 'lynx-client';

// Get addresses for a specific chain
const sonicAddresses = LynxSystemAddresses.sonic;
const arbitrumAddresses = LynxSystemAddresses.arbitrum;

Contract Services

The SDK provides service wrappers for all Lynx contracts, organized using a consistent grouped interface pattern:

Service Architecture

All services follow a grouped interface pattern for better organization:

// Example: TradingFloor Service Structure
const tradingFloor = createTradingFloorService(signer, address);

// Grouped by functionality
tradingFloor.positionQueries       // Position-related queries
tradingFloor.settlementAndPool     // Settlement and pool operations
tradingFloor.traderTracking        // Trader tracking functions
tradingFloor.tradingParameters     // Trading parameters
tradingFloor.fees                  // Fee information
tradingFloor.deprecated            // Deprecated functions

// Standardized accessors
tradingFloor.pendableAdmin         // Admin functions
tradingFloor.pendableImplementation // Implementation functions
tradingFloor.lynxVersionedContract  // Version information
tradingFloor.contractReferences    // Other contract addresses
tradingFloor.constants             // Protocol constants
// Example: OnBehalfTrading Service Structure
const onBehalfTrading = new OnBehalfTradingService(signer, address);

// Grouped by functionality
onBehalfTrading.permissionQueries     // Permission validation and queries
onBehalfTrading.permissionManagement  // Grant/revoke permissions
onBehalfTrading.configuration         // Contract configuration
onBehalfTrading.adminFunctions        // Admin operations

// Standardized accessors
onBehalfTrading.pendableAdmin         // Admin functions
onBehalfTrading.lynxVersionedContract  // Version information
onBehalfTrading.contractReferences    // Other contract addresses

Trading Operations

import { 
  createTradersPortalService,
  buildPositionRequestIdentifier,
  buildPositionRequestParams,
  TOpenOrderType 
} from 'lynx-client';

const tradersPortal = createTradersPortalService(signer, tradersPortalAddress);

// Build position parameters using human-readable values
const identifier = buildPositionRequestIdentifier({
  trader: await signer.getAddress(),
  pairId: 1, // BTC/USD
  settlementAsset: "0x...", // USDC address
});

const params = buildPositionRequestParams({
  isLong: true,
  collateral: 100, // 100 USDC
  leverage: 25, // 25x leverage
  minPrice: 50000, // $50,000
  maxPrice: 50100, // $50,100
  takeProfit: 55000, // $55,000
  stopLoss: 48000 // $48,000
});

// Open a position
await tradersPortal.traderRequests.openNewPosition(
  identifier,
  params,
  TOpenOrderType.MARKET,
  "0x", // referrer domain
  "0x", // referrer code
  true, // run cap tests
  ethers.parseEther("0.01") // native fee
);

Lens Services (Read-Only Data)

import {
  createLexLensService,
  createTradingFloorLensService,
  RateModelLensService
} from 'lynx-client';

// LEX Pool data (accepts both provider and signer)
const lexLens = createLexLensService(signerOrProvider, lexLensAddress);
const poolState = await lexLens.getLexPoolState(lexPoolAddress);
const pairConfigs = await lexLens.getAllPairConfigurationsInLex(lexPoolAddress);

// Trading floor data (accepts both provider and signer)
const tradingFloorLens = createTradingFloorLensService(signerOrProvider, tradingFloorLensAddress);
const position = await tradingFloorLens.getCompletePositionData(tradingFloorAddress, positionId);

// Rate Model data (read-only)
const rateModelLens = new RateModelLensService(provider, rateModelLensAddress);
const rateModels = await rateModelLens.getCompleteRateModelsInfo(lexPools);

📖 For detailed rate model usage, see Rate Model Lens Guide

Utility Functions

Price Conversions

import { floatToPriceBn, priceBnToFloat } from 'lynx-client';

// Convert human-readable price to contract format (8 decimals)
const priceBn = floatToPriceBn(50000.50); // $50,000.50 → BigInt

// Convert contract price to human-readable
const price = priceBnToFloat(priceBn); // BigInt → 50000.50

Leverage Conversions

import { floatUnitsToScaledLeverage, scaledLeverageToUnits } from 'lynx-client';

// Convert human leverage to contract format
const scaledLeverage = floatUnitsToScaledLeverage(25); // 25x → 2500

// Convert contract leverage to human-readable
const leverage = scaledLeverageToUnits(2500); // 2500 → 25x

Collateral Conversions

import { floatToChipsBn, chipsBnToUnits } from 'lynx-client';

// Convert human-readable amount to contract format (18 decimals)
const collateralBn = floatToChipsBn(100.5); // 100.5 tokens → BigInt

// Convert contract amount to human-readable
const collateral = chipsBnToUnits(collateralBn); // BigInt → 100.5

Fraction Conversions

import { floatToFractionBn, fractionBnToFloat } from 'lynx-client';

// Convert percentage to contract format
const fractionBn = floatToFractionBn(0.05); // 5% → 5000

// Convert contract fraction to percentage
const fraction = fractionBnToFloat(5000n); // 5000 → 0.05 (5%)

Advanced Usage

Position Management

// Update position with new TP/SL
await tradersPortal.traderRequests.updatePositionDoubleFieldTpAndSl(
  positionId,
  floatToPriceBn(55000), // New TP: $55,000
  floatToPriceBn(48000), // New SL: $48,000
  ethers.parseEther("0.01") // Fee
);

// Close position at market
await tradersPortal.traderRequests.setExistingPositionToMarketClose(
  positionId,
  floatToPriceBn(49900), // Min acceptable price
  floatToPriceBn(50100), // Max acceptable price
  ethers.parseEther("0.01") // Fee
);

Working with Triggers

import { createTriggersService } from 'lynx-client';

const triggers = createTriggersService(signer, triggersAddress);

// Get trigger configurations
const configs = await triggers.getTriggersConfigurations();
const pairConfigs = await triggers.getPairConfigsInTriggers(1); // Pair ID 1

Delegated Trading with OnBehalfTrading

The OnBehalfTrading service enables users to grant trading permissions to other addresses with specific limits and durations:

import { OnBehalfTradingService } from 'lynx-client';

const onBehalfTrading = new OnBehalfTradingService(signer, onBehalfTradingAddress);

// Grant permission to a trader
await onBehalfTrading.permissionManagement.grantPermission(
  traderAddress,
  tokenAddress,
  ethers.parseUnits("1000", 18), // 1000 token limit
  86400n // 24 hours duration
);

// Check if permission is valid
const isValid = await onBehalfTrading.permissionQueries.isPermissionValid(
  ownerAddress,
  traderAddress,
  tokenAddress
);

// Get remaining amount
const remaining = await onBehalfTrading.permissionQueries.getRemainingAmount(
  ownerAddress,
  traderAddress,
  tokenAddress
);

// Revoke permissions
await onBehalfTrading.permissionManagement.revokePermission(
  traderAddress,
  tokenAddress
);

// Get all active permissions for an owner
const allPermissions = await onBehalfTrading.permissionQueries.getAllActivePermissions(
  ownerAddress
);

LEX Pool Operations

// Get complete LEX pool state
const completeState = await lexLens.getCompleteStateForLex(lexPoolAddress);

// Get supplier state
const supplierState = await lexLens.getLexPoolSupplierState(
  lexPoolAddress,
  supplierAddress
);

// Get all fee configurations
const feeConfigs = await lexLens.getAllFeeConfigurationsInLex(lexPoolAddress);

Standardized Contract Interfaces

The SDK provides standardized interfaces for common contract patterns, ensuring consistent access across all services:

Common Interfaces

ILynxVersionedContract

All Lynx contracts implement versioning for transparency and upgradeability tracking:

import { createTradingFloorService } from 'lynx-client';

const tradingFloor = createTradingFloorService(signer, tradingFloorAddress);

// Access version information through standardized property
const name = await tradingFloor.lynxVersionedContract.getContractName();
const version = await tradingFloor.lynxVersionedContract.getContractVersion();
const contractName = await tradingFloor.lynxVersionedContract.CONTRACT_NAME();
const contractVersion = await tradingFloor.lynxVersionedContract.CONTRACT_VERSION();

IPendableAdmin

Contracts with two-step admin transfer for enhanced security:

// All services with admin functionality use the same accessor
const currentAdmin = await tradingFloor.pendableAdmin.admin();
const pendingAdmin = await tradingFloor.pendableAdmin.pendingAdmin();

// Same pattern works across all services
const triggersAdmin = await triggers.pendableAdmin.admin();
const pnlrAdmin = await pnlr.pendableAdmin.admin();

IPendableImplementation

Upgradeable contracts with two-step implementation updates:

// Access implementation details through standardized property
const implementation = await tradingFloor.pendableImplementation.implementation();
const pendingImpl = await tradingFloor.pendableImplementation.pendingImplementation();

// OrderBook also uses the same pattern
const orderBookImpl = await orderBook.pendableImplementation.implementation();

Standardized Accessor Patterns

All services follow consistent naming conventions for common functionality:

| Property | Interface | Description | |----------|-----------|-------------| | lynxVersionedContract | ILynxVersionedContract | Contract version information | | pendableAdmin | IPendableAdmin | Admin transfer functionality | | pendableImplementation | IPendableImplementation | Implementation upgrade functionality | | contractReferences | Service-specific | References to other contracts | | constants | Service-specific | Protocol constants and scales |

Example with multiple services:

// TradingFloor Service
const tf = createTradingFloorService(signer, address);
await tf.pendableAdmin.admin(); // Admin functionality
await tf.pendableImplementation.implementation(); // Implementation info
await tf.lynxVersionedContract.getContractVersion(); // Version info
await tf.contractReferences.registry(); // Other contract addresses

// PNLR Service (no implementation pattern)
const pnlr = createPNLRService(signer, address);
await pnlr.pendableAdmin.admin(); // Admin functionality
await pnlr.lynxVersionedContract.getContractVersion(); // Version info

// Triggers Service (no implementation pattern)
const triggers = createTriggersService(signer, address);
await triggers.pendableAdmin.admin(); // Admin functionality
await triggers.contractReferences.orderBook(); // Other contract addresses

Type Safety

The SDK provides comprehensive TypeScript types for all contract interactions:

import { 
  TPositionRequestIdentifierStruct,
  TPositionRequestParamsStruct,
  TSinglePositionStruct,
  TPairConfigsInTriggersStruct,
  ILynxVersionedContract,
  IPendableAdmin,
  IPendableImplementation
} from 'lynx-client';

// All contract structs are properly typed
const position = await tradingFloorLens.getCompletePositionData(tradingFloorAddress, id);
console.log(position.trader); // string
console.log(position.collateral); // bigint
console.log(position.leverage); // bigint

// Common interfaces ensure type safety
const service: { pendableAdmin: IPendableAdmin } = tradingFloor;
const admin = await service.pendableAdmin.admin(); // Type-safe access

Error Handling

The SDK validates inputs to prevent common errors:

try {
  // This will throw an error - can't use both price and fraction TP
  const params = buildPositionRequestParams({
    isLong: true,
    collateral: 100,
    leverage: 25,
    minPrice: 50000,
    maxPrice: 50100,
    takeProfit: 55000, // Price-based TP
    takeProfitByFraction: 0.1 // Fraction-based TP - ERROR!
  });
} catch (error) {
  console.error("Cannot specify both takeProfit and takeProfitByFraction");
}

Type Safety

The SDK provides strong type safety with clear distinctions between different numeric types:

Return Type Conventions

  • bigint: Used for asset amounts, collateral, and values requiring high precision
  • number: Used for IDs, timestamps, prices, leverage, and human-readable values
  • string: Used for addresses and text values
  • boolean: Used for flags and states

Lens Service Types

All Lens services return properly typed data structures:

// Example: TradingFloorLens returns typed position data
const position = await lensService.getCompletePositionData(tradingFloor, positionId);
// position.pairId: number (not bigint)
// position.collateral: bigint (asset amount)
// position.leverage: number (human-readable)
// position.openPrice: number (human-readable price)

Constants and Enums

import { 
  TOpenOrderType,
  TOrderCloseType,
  TPositionField,
  TPairIds,
  CHIP_DECIMALS,
  PRICES_SCALE,
  LEVERAGE_MULTIPLIER_SCALE
} from 'lynx-client';

// Order types
const marketOrder = TOpenOrderType.MARKET;
const limitOrder = TOpenOrderType.LIMIT;

// Pair IDs
const btcUsd = TPairIds.BTC_USD;
const ethUsd = TPairIds.ETH_USD;

Best Practices

  1. Always use builder functions for creating position requests:

    // ✅ Good
    const params = buildPositionRequestParams({ ... });
       
    // ❌ Avoid manual construction
    const params = { long: true, collateral: 100n, ... };
  2. Use utility functions for conversions:

    // ✅ Good
    const priceBn = floatToPriceBn(50000);
       
    // ❌ Avoid manual calculations
    const priceBn = BigInt(50000 * 10**8);
  3. Handle contract errors appropriately:

    try {
      await tradersPortal.traderRequests.openNewPosition(...);
    } catch (error) {
      if (error.reason === "Insufficient collateral") {
        // Handle specific error
      }
    }

Migration Guide

From Previous Versions

If you're upgrading from an earlier version, note these changes to standardized accessors:

// Old pattern (mixed grouping)
const admin = await tradingFloor.administration.admin();
const version = await tradingFloor.contractInfo.getContractVersion();

// New pattern (standardized accessors)
const admin = await tradingFloor.pendableAdmin.admin();
const version = await tradingFloor.lynxVersionedContract.getContractVersion();

Key changes:

  • administration → Split into pendableAdmin and contractReferences
  • contractInfo → Split into lynxVersionedContract and contractReferences
  • Consistent naming across all services

Development

Building

npm run build

Testing

npm test

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

ISC

Support