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

lnlink-server

v1.1.6

Published

This project is an SDK library developed based on the Nostr Asset Protocol, designed to facilitate interactions with Lightning Network Daemon (LND) and RGB nodes, enabling Nostr-based functionalities.

Readme

LNLink

This project is an SDK library developed based on the Nostr Asset Protocol, designed to facilitate interactions with Lightning Network Daemon (LND) and RGB nodes, enabling Nostr-based functionalities.

Prerequisites & Installation

  • Node.js >= 19
  • Yarn >= 1.22

Install project dependencies once at the repository root:

yarn install

Notes:

  • Native deps such as @prisma/client are required at runtime and are not bundled by esbuild.
  • Binaries (litd, rgb-lightning-node, tor) are prepared by scripts/binSetup.js on demand.

Getting Started

There are three ways to start the project. Choose the one that fits your scenario.

1) Quick Start with Local Binaries

This mode runs everything on your host using local binaries. It is the fastest way to try the project.

  • Prerequisites

    • Node.js >= 19
    • The project will download platform-specific binaries automatically on first run.
  • Prepare env file at project root: .env.bin

    • Common variables:
      • LINK_BINARY_PATH=/<Your path>/bin or an absolute path, e.g. /root/data/bin
      • LINK_NAME=...
      • LINK_DATA_PATH=/root/data/<name> or an absolute path
      • LINK_HTTP_PORT=8099
      • LINK_ENABLE_TOR=false (optional)
      • LINK_OWNER: Nostr npub of the owner/operator
      • LINK_NETWORK: Bitcoin network (regtest, testnet, mainnet)
  • Install deps (first time only)

    yarn install
  • Start

    yarn start:bin

    What happens:

    • scripts/binSetup.js runs first to ensure required binaries exist (downloads using binaries.json).
    • The app then starts with variables loaded from .env.bin.

2) Development Mode (Docker Compose)

Use this for local development and debugging with Docker.

  • Prepare env file at project root: .env.dev

  • Environment variables overview (.env.dev):

    • LINK_NAME: Logical name of this node instance. Used to name Docker volumes and service identifiers.
    • LINK_DATA_PATH: Absolute path to persist data (wallet, db, macaroons, etc.). Prefer an absolute path to avoid ambiguity.
    • LINK_OWNER: Nostr npub of the owner/operator.
    • LINK_NETWORK: Bitcoin network. Typical values: regtest, testnet, mainnet.
    • LINK_ENABLE_TOR: Whether to enable Tor support (true/false).
    • LINK_HTTP_PORT: API HTTP port exposed by this wrapper inside Docker to your host.
    • LINK_LND_RPC_PORT: LND gRPC port exposed to the host.
    • LINK_RGB_LISTENING_PORT: RGB service port exposed to the host.
    • LINK_NODE_ENV: Node.js runtime environment, typically development for this mode.
    • LINK_NOSTR_NODE_NPUBKEY: The npub (hex-encoded pubkey) of the Nostr relay/node this instance peers with.
    • LINK_NOSTR_NODE_HOST: The Nostr Lightning node host (pubkey@host:port or host:port) used for peering.
    • LINK_ORACLE_SERVER_HOST: Oracle/bridge service host for price or external queries if applicable.
    • LINK_BITCOIND_RPCHOST: Bitcoind RPC host (host:port) that LND connects to (for regtest/testnet/mainnet as configured).
    • LINK_BITCOIND_RPCUSER: Bitcoind RPC username.
    • LINK_BITCOIND_RPCPASS: Bitcoind RPC password.
    • LINK_BITCOIND_ZMQBLOCK: Bitcoind ZMQ block notifications endpoint.
    • LINK_BITCOIND_ZMQRAWTX: Bitcoind ZMQ raw transaction notifications endpoint.
  • Example .env.dev (regtest):

    LINK_NAME=<Your name>
    LINK_DATA_PATH='/<Your project path>/docker/volumes/${LINK_NAME}'
    LINK_DATABASE_URL=file:/<Your project path>/docker/volumes/${LINK_NAME}/link/lnlink.db
    LINK_OWNER=npub1q7amuklx0fjw76dtulzzhhjmff8du5lyngw377d89hhrmj49w48ssltn7y
    LINK_NETWORK=regtest
    LINK_ENABLE_TOR=false
    LINK_HTTP_PORT=8090
    LINK_LND_RPC_PORT=30009
    LINK_RGB_LISTENING_PORT=5002
    LINK_NODE_ENV=development
    
    LINK_NOSTR_NODE_NPUBKEY=027d2f1be71dc24c60b15070489d4ef274dd6aac236d02c67c76d6935defba56a6
    LINK_NOSTR_NODE_HOST=regtest.lnfi.network:9735
    LINK_ORACLE_SERVER_HOST=grpc-oracle.lnfi.network:443
    LINK_BITCOIND_RPCHOST=regtest.lnfi.network:18443
    LINK_BITCOIND_RPCUSER=lnfi_user
    LINK_BITCOIND_RPCPASS=lnfi_pass12GA
    LINK_BITCOIND_ZMQBLOCK=tcp://regtest.lnfi.network:28334
    LINK_BITCOIND_ZMQRAWTX=tcp://regtest.lnfi.network:28335
  • Start

    yarn start:docker:dev

    This will:

    • Use .env.dev for environment variables.
    • Launch services defined in docker-compose.dev.yml.

Run steps (recommended workflow):

  1. Start dependencies (Docker services) in Terminal A:
    yarn start:docker:dev
  2. Start the application in Terminal B (local Node process using .env.dev):
    yarn start:dev

Stop / cleanup:

  • Stop the application: Ctrl+C in the Terminal B running yarn start:dev.
  • Stop Docker services:
    docker compose --env-file ./.env.dev -f ./docker-compose.dev.yml down

Network prerequisite:

  • The compose file uses an external Docker network named lnfi_network. Create it once if it doesn't exist:

    docker network create lnfi_network

    Tips:

    • Ensure LINK_DATA_PATH exists and is writable by Docker; it will persist LND/RGB data and macaroons.
    • Make sure the specified ports (LINK_HTTP_PORT, LINK_LND_RPC_PORT, LINK_RGB_LISTENING_PORT) are free on your host.
    • For regtest, confirm your BITCOIND_* endpoints are reachable from the Docker network.

3) Docker Compose (Standard, Multi-Network)

Use this when you want to run LN-Link fully inside Docker with a clear separation between environment settings (.env.*) and network profiles (DB settings).

There are three environment files for different networks:

  • .env.regtest
  • .env.testnet
  • .env.mainnet (optional, usually only contains non-sensitive runtime values)

Each file typically contains:

  • LINK_NAME: Logical name of this node instance (used for container/alias/naming).
  • LINK_NETWORK: Bitcoin network (regtest, testnet, mainnet).
  • LINK_DATA_PATH: Data persistence path (relative path supported, e.g. ./docker/volumes/linkdev).
  • LINK_OWNER: Nostr npub of the owner/operator.
  • LINK_ENABLE_TOR: Enable Tor support (true/false).
  • LINK_RGB_LDK_PEER_LISTENING_PORT: RGB LDK peer listening port (e.g. 9750).
  • LINK_RGB_HOST: Host advertised for RGB peers (e.g. host LAN IP in regtest).
  • LINK_REPORT_BASE_URL, LINK_REPORT_ADDRESS: Optional reporting/telemetry endpoints.

Example .env.regtest:

LINK_NAME=linkdev
LINK_NETWORK=regtest
LINK_NODE_ENV=production

LINK_DATA_PATH=./docker/volumes/linkdev
LINK_ENABLE_TOR=false
LINK_OWNER=npub1...

LINK_REPORT_BASE_URL=https://devoffaucet.unift.xyz
LINK_REPORT_ADDRESS=npub1...
LINK_RGB_LDK_PEER_LISTENING_PORT=9750
LINK_RGB_HOST=192.168.0.117

Example .env.testnet is similar but typically uses a different LINK_DATA_PATH and possibly different ports/host IP.

  • Start (regtest)

    yarn start:regtest
  • Start (testnet)

    yarn start:testnet
  • Start (mainnet)

    # Requires a proper .env.mainnet and network settings (see LINK_SETTINGS_PATH below)
    yarn start:mainnet

Each command will:

  • Use the corresponding .env.<network> file via docker-compose-lnlink.yml.
  • Launch the lit service (LN-Link + litd + RGB) inside Docker on the external network lnfi_network.

4) Run from dist (bundled output)

Build first:

yarn build

Run using local binaries and env .env.bin (requires bin/ and root node_modules/):

yarn start:bin:dist

Notes about dist/ runtime:

  • dist/index.js still requires runtime dependencies from the repository root node_modules/ (e.g., @grpc/grpc-js, @prisma/client).
  • The proto/ folder is copied to dist/proto/ during build; code resolves proto paths via process.cwd().
  • The bin/ folder (with litd, rgb-lightning-node, tor) is required when running with local binaries; prepare it using yarn start:bin once, or run node ./scripts/binSetup.js.

Using as NPM Package

After building with yarn build, the dist/ directory contains a complete NPM package that can be published and used in other projects.

Installation

npm install @lnfi-network/ln-link

Note: Database initialization (Prisma client generation and migrations) is handled at runtime to avoid requiring environment variables during package installation.

Usage in Node.js Applications

// Import the main application entry point
require('@lnfi-network/ln-link');

// The application will start automatically when imported
// Configuration is handled via environment variables or config files

For programmatic control in Node.js:

const path = require('path');

// Set environment variables before importing
process.env.LINK_DATA_PATH = path.join(__dirname, 'ln-link-data');
process.env.LINK_NETWORK = 'testnet';
process.env.LINK_HTTP_PORT = '8099';
process.env.LINK_OWNER = 'npub1...'; // Your Nostr public key
process.env.LINK_DATABASE_URL = 'file:' + path.join(__dirname, 'ln-link-data', 'lnlink.db');

// You may need to run Prisma setup manually for Node.js applications:
// npx prisma generate
// npx prisma migrate deploy

// Import and start the application
require('@lnfi-network/ln-link');

Usage in Electron Applications

The package provides a dedicated Electron entry point for desktop applications:

// In your Electron main process
const { app, BrowserWindow } = require('electron');
const path = require('path');

// Import the Electron-specific entry point
const LnLinkElectron = require('@lnfi-network/ln-link/electron');

// Global LN-Link instance
let lnLink = null;

app.whenReady().then(async () => {
  // Create your Electron window
  const mainWindow = new BrowserWindow({
    width: 1200,
    height: 800,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  });

  // Create LN-Link instance
  lnLink = new LnLinkElectron({
    dataPath: path.join(app.getPath('userData'), 'ln-link'),
    network: 'testnet', // or 'mainnet', 'regtest'
    httpPort: 8099,
    name: 'my-electron-app',
    enableTor: false,
    owner: 'npub1...', // Your Nostr public key
    debug: true,
    // binaryPath: '/path/to/binaries', // Optional: for local binary mode
    // Database setup is handled automatically in Electron applications
  });

  await lnLink.start();

  // Load your application UI
  mainWindow.loadFile('index.html');
});

app.on('window-all-closed', async () => {
  // Gracefully shutdown LN-Link
  if (lnLink) {
    await lnLink.stop();
  }
  
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

Configuration Options

When using the package in other applications, you can configure it programmatically:

const config = {
  // Data storage path
  dataPath: '/path/to/data',
  
  // Network configuration
  network: 'testnet', // 'mainnet', 'testnet', 'regtest'
  
  // Application name
  name: 'my-app',
  
  // Service ports
  httpPort: 8099,
  lndRpcPort: 10009,
  rgbPort: 5002,
  
  // Nostr configuration
  owner: 'npub1...', // Your Nostr public key
  
  // Optional features
  enableTor: false,
  debug: false,
  
  // Binary paths (for local binary mode)
  binaryPath: '/path/to/binaries',

  // Database configuration (optional - defaults to dataPath/lnlink.db)
  databaseUrl: 'file:/path/to/custom/database.db',
};

## Configuration Overview

### DB-backed network settings (LnlinkConfig.settings)

LN-Link stores the **network profile** (bitcoind, RGB, Nostr, oracle, etc.) in the
`LnlinkConfig.settings` field in the database. At runtime, `getConfig()` merges:

- `config.default.js` (built-in defaults)
- Process env (`.env.*` / programmatic options)
- `LnlinkConfig.settings` (network profile)

For Docker/standalone modes (**`LINK_NODE_ENV !== "app"`**):

- On first start, if the DB has no `settings`, LN-Link will initialize them by:
  1. If `LINK_SETTINGS_PATH` is set and points to a valid JSON file, load that JSON
     and write it to `LnlinkConfig.settings`.
  2. Otherwise, fall back to network templates:
     - `setting.regtest.json` for `LINK_NETWORK=regtest`
     - `setting.testnet.json` for `LINK_NETWORK=testnet`
     - `setting.mainnet.json` for `LINK_NETWORK=mainnet` (template only, no secrets).

For security-sensitive environments (especially **mainnet**):

- Keep `setting.mainnet.json` as a **template only** (with placeholder values).
- Put the real mainnet JSON under a secure path on the server, e.g.:
  - `/data/config/lnlink-mainnet-settings.json`
- Set:
  ```env
  LINK_NETWORK=mainnet
  LINK_SETTINGS_PATH=/data/config/lnlink-mainnet-settings.json

so that first start reads this file and writes it into LnlinkConfig.settings.

Node name (LINK_NAME) and database node_name

The human-readable node name comes from LnlinkConfig.node_name and is exposed as LINK_NAME by getConfig() with the following precedence:

  • DB node_name > env LINK_NAME > config.default.js.

On first initialization in Docker/standalone mode:

  • LN-Link uses the current LINK_NAME to populate LnlinkConfig.node_name.
  • If settings already exist but node_name is empty, it will backfill node_name once from the current LINK_NAME.

To change the node name later without touching env:

  • Use the HTTP API:
    POST /api/lnd/update-name
    { "nodeName": "my-new-node-name" }
    This updates LnlinkConfig.node_name and triggers reloadConfig(), so subsequent getConfig() calls see the new LINK_NAME immediately.

Notes:

  • LND (litd) reads the alias/TLS extra domains only at process start (via buildLitdArgs). Changing the name via API does not automatically restart litd; restart is only needed if you want the alias/TLS SANs to match the new name.
  • RGB uses LINK_NAME as announce_alias during unlockNode. After changing the name, the next unlock call will use the new alias; no process restart is required for RGB.

Electron mode (LINK_NODE_ENV = "app")

When running via the Electron entry point (lnlink.js / LnLinkElectron):

  • LINK_NODE_ENV is effectively "app".
  • initLinkConfig() does not auto-initialize DB from setting.*.json or LINK_SETTINGS_PATH.
  • You are expected to initialize and update LnlinkConfig.settings and node_name via the HTTP APIs:
    • POST /api/lnd/init with { owner, settings, nodeName }.
    • POST /api/lnd/update-name with { nodeName }.

### Platform-Specific Notes

- **Prisma**: Database client generation and migrations are handled at runtime. For Node.js applications, you may need to run manually:
  ```bash
  npx prisma generate        # Generate client code
  npx prisma migrate deploy  # Apply database migrations

For Electron applications, database setup is handled automatically.

  • Binary Dependencies: When using local binaries (LND, RGB node, Tor), ensure they are available for your target platform. The package includes platform detection and automatic binary management.

Notes

  • Local binary workflow
    • The binary download/prepare workflow is implemented in scripts/binSetup.js (calls scripts/binManage.js).
    • Download sources are configured in binaries.json per-platform (darwin-arm64, darwin-x64, linux-x64).
    • Binaries are stored under ./bin by default; you can override via LINK_BINARY_PATH.
  • Job system
    • The system initializes with state-driven tasks; no manual startJobs events are needed.
  • Error handling
    • Improved error typing in business/job/core/StateManager.js for better diagnostics.

Key Features

  • SDK Library based on Nostr Asset Protocol.
  • Integration with LND and RGB nodes.
  • Enables Nostr-based functionalities for Lightning and RGB assets.