lnlink-server 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +461 -0
  2. package/dist/app.js +11165 -0
  3. package/dist/binaries.json +20 -0
  4. package/dist/build-info.json +41 -0
  5. package/dist/config.default.js +19 -0
  6. package/dist/index.js +19002 -0
  7. package/dist/index.js.map +7 -0
  8. package/dist/package.json +61 -0
  9. package/dist/prisma/migrations/20250918020814_/migration.sql +188 -0
  10. package/dist/prisma/migrations/20251114105314_auto_update/migration.sql +2 -0
  11. package/dist/prisma/migrations/migration_lock.toml +3 -0
  12. package/dist/prisma/schema.prisma +181 -0
  13. package/dist/proto/chainkit.proto +74 -0
  14. package/dist/proto/lightning.proto +5411 -0
  15. package/dist/proto/lit-status.proto +36 -0
  16. package/dist/proto/looprpc/client.proto +1435 -0
  17. package/dist/proto/price_oracle.proto +243 -0
  18. package/dist/proto/rfqrpc/rfq.proto +436 -0
  19. package/dist/proto/routerrpc/router.proto +1136 -0
  20. package/dist/proto/signrpc/signer.proto +709 -0
  21. package/dist/proto/stateservice.proto +73 -0
  22. package/dist/proto/swapserverrpc/common.proto +37 -0
  23. package/dist/proto/tapchannel.proto +306 -0
  24. package/dist/proto/tapcommon.proto +36 -0
  25. package/dist/proto/taprootassets.proto +1959 -0
  26. package/dist/proto/universe.proto +1063 -0
  27. package/dist/proto/walletkit.proto +1594 -0
  28. package/dist/proto/walletunlocker.proto +338 -0
  29. package/dist/public/css/initOwner.css +553 -0
  30. package/dist/public/favicon.ico +0 -0
  31. package/dist/public/init.html +70 -0
  32. package/dist/public/js/init.js +454 -0
  33. package/dist/setting.mainnet.json +22 -0
  34. package/dist/setting.regtest.json +22 -0
  35. package/dist/setting.testnet.json +22 -0
  36. package/package.json +91 -0
package/README.md ADDED
@@ -0,0 +1,461 @@
1
+ # LNLink
2
+
3
+ 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.
4
+
5
+ ## Prerequisites & Installation
6
+
7
+ - Node.js >= 19
8
+ - Yarn >= 1.22
9
+
10
+ Install project dependencies once at the repository root:
11
+
12
+ ```bash
13
+ yarn install
14
+ ```
15
+
16
+ Notes:
17
+ - Native deps such as `@prisma/client` are required at runtime and are not bundled by esbuild.
18
+ - Binaries (`litd`, `rgb-lightning-node`, `tor`) are prepared by `scripts/binSetup.js` on demand.
19
+
20
+ ## Getting Started
21
+
22
+ There are three ways to start the project. Choose the one that fits your scenario.
23
+
24
+ ### 1) Quick Start with Local Binaries
25
+
26
+ This mode runs everything on your host using local binaries. It is the fastest way to try the project.
27
+
28
+ - Prerequisites
29
+ - Node.js >= 19
30
+ - The project will download platform-specific binaries automatically on first run.
31
+
32
+ - Prepare env file at project root: `.env.bin`
33
+ - Common variables:
34
+ - `LINK_BINARY_PATH=/<Your path>/bin` or an absolute path, e.g. `/root/data/bin`
35
+ - `LINK_NAME=...`
36
+ - `LINK_DATA_PATH=/root/data/<name>` or an absolute path
37
+ - `LINK_HTTP_PORT=8099`
38
+ - `LINK_ENABLE_TOR=false` (optional)
39
+ - `LINK_OWNER`: Nostr npub of the owner/operator
40
+ - `LINK_NETWORK`: Bitcoin network (`regtest`, `testnet`, `mainnet`)
41
+
42
+ - Install deps (first time only)
43
+ ```bash
44
+ yarn install
45
+ ```
46
+
47
+ - Start
48
+ ```bash
49
+ yarn start:bin
50
+ ```
51
+ What happens:
52
+ - `scripts/binSetup.js` runs first to ensure required binaries exist (downloads using `binaries.json`).
53
+ - The app then starts with variables loaded from `.env.bin`.
54
+
55
+ ### 2) Development Mode (Docker Compose)
56
+
57
+ Use this for local development and debugging with Docker.
58
+
59
+ - Prepare env file at project root: `.env.dev`
60
+ - Environment variables overview (`.env.dev`):
61
+ - `LINK_NAME`: Logical name of this node instance. Used to name Docker volumes and service identifiers.
62
+ - `LINK_DATA_PATH`: Absolute path to persist data (wallet, db, macaroons, etc.). Prefer an absolute path to avoid ambiguity.
63
+ - `LINK_OWNER`: Nostr npub of the owner/operator.
64
+ - `LINK_NETWORK`: Bitcoin network. Typical values: `regtest`, `testnet`, `mainnet`.
65
+ - `LINK_ENABLE_TOR`: Whether to enable Tor support (`true`/`false`).
66
+ - `LINK_HTTP_PORT`: API HTTP port exposed by this wrapper inside Docker to your host.
67
+ - `LINK_LND_RPC_PORT`: LND gRPC port exposed to the host.
68
+ - `LINK_RGB_LISTENING_PORT`: RGB service port exposed to the host.
69
+ - `LINK_NODE_ENV`: Node.js runtime environment, typically `development` for this mode.
70
+ - `LINK_NOSTR_NODE_NPUBKEY`: The npub (hex-encoded pubkey) of the Nostr relay/node this instance peers with.
71
+ - `LINK_NOSTR_NODE_HOST`: The Nostr Lightning node host (pubkey@host:port or host:port) used for peering.
72
+ - `LINK_ORACLE_SERVER_HOST`: Oracle/bridge service host for price or external queries if applicable.
73
+ - `LINK_BITCOIND_RPCHOST`: Bitcoind RPC host (host:port) that LND connects to (for regtest/testnet/mainnet as configured).
74
+ - `LINK_BITCOIND_RPCUSER`: Bitcoind RPC username.
75
+ - `LINK_BITCOIND_RPCPASS`: Bitcoind RPC password.
76
+ - `LINK_BITCOIND_ZMQBLOCK`: Bitcoind ZMQ block notifications endpoint.
77
+ - `LINK_BITCOIND_ZMQRAWTX`: Bitcoind ZMQ raw transaction notifications endpoint.
78
+
79
+ - Example `.env.dev` (regtest):
80
+ ```env
81
+ LINK_NAME=<Your name>
82
+ LINK_DATA_PATH='/<Your project path>/docker/volumes/${LINK_NAME}'
83
+ LINK_DATABASE_URL=file:/<Your project path>/docker/volumes/${LINK_NAME}/link/lnlink.db
84
+ LINK_OWNER=npub1q7amuklx0fjw76dtulzzhhjmff8du5lyngw377d89hhrmj49w48ssltn7y
85
+ LINK_NETWORK=regtest
86
+ LINK_ENABLE_TOR=false
87
+ LINK_HTTP_PORT=8090
88
+ LINK_LND_RPC_PORT=30009
89
+ LINK_RGB_LISTENING_PORT=5002
90
+ LINK_NODE_ENV=development
91
+
92
+ LINK_NOSTR_NODE_NPUBKEY=027d2f1be71dc24c60b15070489d4ef274dd6aac236d02c67c76d6935defba56a6
93
+ LINK_NOSTR_NODE_HOST=regtest.lnfi.network:9735
94
+ LINK_ORACLE_SERVER_HOST=grpc-oracle.lnfi.network:443
95
+ LINK_BITCOIND_RPCHOST=regtest.lnfi.network:18443
96
+ LINK_BITCOIND_RPCUSER=lnfi_user
97
+ LINK_BITCOIND_RPCPASS=lnfi_pass12GA
98
+ LINK_BITCOIND_ZMQBLOCK=tcp://regtest.lnfi.network:28334
99
+ LINK_BITCOIND_ZMQRAWTX=tcp://regtest.lnfi.network:28335
100
+ ```
101
+
102
+ - Start
103
+ ```bash
104
+ yarn start:docker:dev
105
+ ```
106
+ This will:
107
+ - Use `.env.dev` for environment variables.
108
+ - Launch services defined in `docker-compose.dev.yml`.
109
+
110
+ Run steps (recommended workflow):
111
+
112
+ 1) Start dependencies (Docker services) in Terminal A:
113
+ ```bash
114
+ yarn start:docker:dev
115
+ ```
116
+ 2) Start the application in Terminal B (local Node process using `.env.dev`):
117
+ ```bash
118
+ yarn start:dev
119
+ ```
120
+
121
+ Stop / cleanup:
122
+ - Stop the application: Ctrl+C in the Terminal B running `yarn start:dev`.
123
+ - Stop Docker services:
124
+ ```bash
125
+ docker compose --env-file ./.env.dev -f ./docker-compose.dev.yml down
126
+ ```
127
+
128
+ Network prerequisite:
129
+ - The compose file uses an external Docker network named `lnfi_network`. Create it once if it doesn't exist:
130
+ ```bash
131
+ docker network create lnfi_network
132
+ ```
133
+
134
+ Tips:
135
+ - Ensure `LINK_DATA_PATH` exists and is writable by Docker; it will persist LND/RGB data and macaroons.
136
+ - Make sure the specified ports (`LINK_HTTP_PORT`, `LINK_LND_RPC_PORT`, `LINK_RGB_LISTENING_PORT`) are free on your host.
137
+ - For `regtest`, confirm your `BITCOIND_*` endpoints are reachable from the Docker network.
138
+
139
+ ### 3) Docker Compose (Standard, Multi-Network)
140
+
141
+ Use this when you want to run LN-Link fully inside Docker with a clear separation between
142
+ environment settings (`.env.*`) and network profiles (DB `settings`).
143
+
144
+ There are three environment files for different networks:
145
+
146
+ - `.env.regtest`
147
+ - `.env.testnet`
148
+ - `.env.mainnet` (optional, usually only contains non-sensitive runtime values)
149
+
150
+ Each file typically contains:
151
+
152
+ - `LINK_NAME`: Logical name of this node instance (used for container/alias/naming).
153
+ - `LINK_NETWORK`: Bitcoin network (`regtest`, `testnet`, `mainnet`).
154
+ - `LINK_DATA_PATH`: Data persistence path (relative path supported, e.g. `./docker/volumes/linkdev`).
155
+ - `LINK_OWNER`: Nostr npub of the owner/operator.
156
+ - `LINK_ENABLE_TOR`: Enable Tor support (`true`/`false`).
157
+ - `LINK_RGB_LDK_PEER_LISTENING_PORT`: RGB LDK peer listening port (e.g. `9750`).
158
+ - `LINK_RGB_HOST`: Host advertised for RGB peers (e.g. host LAN IP in regtest).
159
+ - `LINK_REPORT_BASE_URL`, `LINK_REPORT_ADDRESS`: Optional reporting/telemetry endpoints.
160
+
161
+ Example `.env.regtest`:
162
+
163
+ ```env
164
+ LINK_NAME=linkdev
165
+ LINK_NETWORK=regtest
166
+ LINK_NODE_ENV=production
167
+
168
+ LINK_DATA_PATH=./docker/volumes/linkdev
169
+ LINK_ENABLE_TOR=false
170
+ LINK_OWNER=npub1...
171
+
172
+ LINK_REPORT_BASE_URL=https://devoffaucet.unift.xyz
173
+ LINK_REPORT_ADDRESS=npub1...
174
+ LINK_RGB_LDK_PEER_LISTENING_PORT=9750
175
+ LINK_RGB_HOST=192.168.0.117
176
+ ```
177
+
178
+ Example `.env.testnet` is similar but typically uses a different `LINK_DATA_PATH` and
179
+ possibly different ports/host IP.
180
+
181
+ - Start (regtest)
182
+ ```bash
183
+ yarn start:regtest
184
+ ```
185
+
186
+ - Start (testnet)
187
+ ```bash
188
+ yarn start:testnet
189
+ ```
190
+
191
+ - Start (mainnet)
192
+ ```bash
193
+ # Requires a proper .env.mainnet and network settings (see LINK_SETTINGS_PATH below)
194
+ yarn start:mainnet
195
+ ```
196
+
197
+ Each command will:
198
+
199
+ - Use the corresponding `.env.<network>` file via `docker-compose-lnlink.yml`.
200
+ - Launch the `lit` service (LN-Link + litd + RGB) inside Docker on the
201
+ external network `lnfi_network`.
202
+
203
+ ### 4) Run from dist (bundled output)
204
+
205
+ Build first:
206
+
207
+ ```bash
208
+ yarn build
209
+ ```
210
+
211
+ Run using local binaries and env `.env.bin` (requires `bin/` and root `node_modules/`):
212
+
213
+ ```bash
214
+ yarn start:bin:dist
215
+ ```
216
+
217
+
218
+ Notes about `dist/` runtime:
219
+ - `dist/index.js` still requires runtime dependencies from the repository root `node_modules/` (e.g., `@grpc/grpc-js`, `@prisma/client`).
220
+ - The `proto/` folder is copied to `dist/proto/` during build; code resolves proto paths via `process.cwd()`.
221
+ - 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`.
222
+
223
+ ## Using as NPM Package
224
+
225
+ After building with `yarn build`, the `dist/` directory contains a complete NPM package that can be published and used in other projects.
226
+
227
+ ### Installation
228
+
229
+ ```bash
230
+ npm install @lnfi-network/ln-link
231
+ ```
232
+
233
+ **Note**: Database initialization (Prisma client generation and migrations) is handled at runtime to avoid requiring environment variables during package installation.
234
+
235
+ ### Usage in Node.js Applications
236
+
237
+ ```javascript
238
+ // Import the main application entry point
239
+ require('@lnfi-network/ln-link');
240
+
241
+ // The application will start automatically when imported
242
+ // Configuration is handled via environment variables or config files
243
+ ```
244
+
245
+ For programmatic control in Node.js:
246
+
247
+ ```javascript
248
+ const path = require('path');
249
+
250
+ // Set environment variables before importing
251
+ process.env.LINK_DATA_PATH = path.join(__dirname, 'ln-link-data');
252
+ process.env.LINK_NETWORK = 'testnet';
253
+ process.env.LINK_HTTP_PORT = '8099';
254
+ process.env.LINK_OWNER = 'npub1...'; // Your Nostr public key
255
+ process.env.LINK_DATABASE_URL = 'file:' + path.join(__dirname, 'ln-link-data', 'lnlink.db');
256
+
257
+ // You may need to run Prisma setup manually for Node.js applications:
258
+ // npx prisma generate
259
+ // npx prisma migrate deploy
260
+
261
+ // Import and start the application
262
+ require('@lnfi-network/ln-link');
263
+ ```
264
+
265
+ ### Usage in Electron Applications
266
+
267
+ The package provides a dedicated Electron entry point for desktop applications:
268
+
269
+ ```javascript
270
+ // In your Electron main process
271
+ const { app, BrowserWindow } = require('electron');
272
+ const path = require('path');
273
+
274
+ // Import the Electron-specific entry point
275
+ const LnLinkElectron = require('@lnfi-network/ln-link/electron');
276
+
277
+ // Global LN-Link instance
278
+ let lnLink = null;
279
+
280
+ app.whenReady().then(async () => {
281
+ // Create your Electron window
282
+ const mainWindow = new BrowserWindow({
283
+ width: 1200,
284
+ height: 800,
285
+ webPreferences: {
286
+ nodeIntegration: true,
287
+ contextIsolation: false
288
+ }
289
+ });
290
+
291
+ // Create LN-Link instance
292
+ lnLink = new LnLinkElectron({
293
+ dataPath: path.join(app.getPath('userData'), 'ln-link'),
294
+ network: 'testnet', // or 'mainnet', 'regtest'
295
+ httpPort: 8099,
296
+ name: 'my-electron-app',
297
+ enableTor: false,
298
+ owner: 'npub1...', // Your Nostr public key
299
+ debug: true,
300
+ // binaryPath: '/path/to/binaries', // Optional: for local binary mode
301
+ // Database setup is handled automatically in Electron applications
302
+ });
303
+
304
+ await lnLink.start();
305
+
306
+ // Load your application UI
307
+ mainWindow.loadFile('index.html');
308
+ });
309
+
310
+ app.on('window-all-closed', async () => {
311
+ // Gracefully shutdown LN-Link
312
+ if (lnLink) {
313
+ await lnLink.stop();
314
+ }
315
+
316
+ if (process.platform !== 'darwin') {
317
+ app.quit();
318
+ }
319
+ });
320
+ ```
321
+
322
+ ### Configuration Options
323
+
324
+ When using the package in other applications, you can configure it programmatically:
325
+
326
+ ```javascript
327
+ const config = {
328
+ // Data storage path
329
+ dataPath: '/path/to/data',
330
+
331
+ // Network configuration
332
+ network: 'testnet', // 'mainnet', 'testnet', 'regtest'
333
+
334
+ // Application name
335
+ name: 'my-app',
336
+
337
+ // Service ports
338
+ httpPort: 8099,
339
+ lndRpcPort: 10009,
340
+ rgbPort: 5002,
341
+
342
+ // Nostr configuration
343
+ owner: 'npub1...', // Your Nostr public key
344
+
345
+ // Optional features
346
+ enableTor: false,
347
+ debug: false,
348
+
349
+ // Binary paths (for local binary mode)
350
+ binaryPath: '/path/to/binaries',
351
+
352
+ // Database configuration (optional - defaults to dataPath/lnlink.db)
353
+ databaseUrl: 'file:/path/to/custom/database.db',
354
+ };
355
+
356
+ ## Configuration Overview
357
+
358
+ ### DB-backed network settings (LnlinkConfig.settings)
359
+
360
+ LN-Link stores the **network profile** (bitcoind, RGB, Nostr, oracle, etc.) in the
361
+ `LnlinkConfig.settings` field in the database. At runtime, `getConfig()` merges:
362
+
363
+ - `config.default.js` (built-in defaults)
364
+ - Process env (`.env.*` / programmatic options)
365
+ - `LnlinkConfig.settings` (network profile)
366
+
367
+ For Docker/standalone modes (**`LINK_NODE_ENV !== "app"`**):
368
+
369
+ - On first start, if the DB has no `settings`, LN-Link will initialize them by:
370
+ 1. If `LINK_SETTINGS_PATH` is set and points to a valid JSON file, load that JSON
371
+ and write it to `LnlinkConfig.settings`.
372
+ 2. Otherwise, fall back to network templates:
373
+ - `setting.regtest.json` for `LINK_NETWORK=regtest`
374
+ - `setting.testnet.json` for `LINK_NETWORK=testnet`
375
+ - `setting.mainnet.json` for `LINK_NETWORK=mainnet` (template only, no secrets).
376
+
377
+ For security-sensitive environments (especially **mainnet**):
378
+
379
+ - Keep `setting.mainnet.json` as a **template only** (with placeholder values).
380
+ - Put the real mainnet JSON under a secure path on the server, e.g.:
381
+ - `/data/config/lnlink-mainnet-settings.json`
382
+ - Set:
383
+ ```env
384
+ LINK_NETWORK=mainnet
385
+ LINK_SETTINGS_PATH=/data/config/lnlink-mainnet-settings.json
386
+ ```
387
+ so that first start reads this file and writes it into `LnlinkConfig.settings`.
388
+
389
+ ### Node name (LINK_NAME) and database node_name
390
+
391
+ The human-readable node name comes from `LnlinkConfig.node_name` and is exposed as
392
+ `LINK_NAME` by `getConfig()` with the following precedence:
393
+
394
+ - DB `node_name` > env `LINK_NAME` > `config.default.js`.
395
+
396
+ On first initialization in Docker/standalone mode:
397
+
398
+ - LN-Link uses the current `LINK_NAME` to populate `LnlinkConfig.node_name`.
399
+ - If `settings` already exist but `node_name` is empty, it will backfill
400
+ `node_name` once from the current `LINK_NAME`.
401
+
402
+ To change the node name later without touching env:
403
+
404
+ - Use the HTTP API:
405
+ ```http
406
+ POST /api/lnd/update-name
407
+ { "nodeName": "my-new-node-name" }
408
+ ```
409
+ This updates `LnlinkConfig.node_name` and triggers `reloadConfig()`, so
410
+ subsequent `getConfig()` calls see the new `LINK_NAME` immediately.
411
+
412
+ Notes:
413
+
414
+ - LND (litd) reads the alias/TLS extra domains only at process start
415
+ (via `buildLitdArgs`). Changing the name via API does **not** automatically
416
+ restart litd; restart is only needed if you want the alias/TLS SANs to match
417
+ the new name.
418
+ - RGB uses `LINK_NAME` as `announce_alias` during `unlockNode`. After changing
419
+ the name, the next unlock call will use the new alias; no process restart
420
+ is required for RGB.
421
+
422
+ ### Electron mode (LINK_NODE_ENV = "app")
423
+
424
+ When running via the Electron entry point (`lnlink.js` / `LnLinkElectron`):
425
+
426
+ - `LINK_NODE_ENV` is effectively `"app"`.
427
+ - `initLinkConfig()` **does not** auto-initialize DB from `setting.*.json` or
428
+ `LINK_SETTINGS_PATH`.
429
+ - You are expected to initialize and update `LnlinkConfig.settings` and
430
+ `node_name` via the HTTP APIs:
431
+ - `POST /api/lnd/init` with `{ owner, settings, nodeName }`.
432
+ - `POST /api/lnd/update-name` with `{ nodeName }`.
433
+ ```
434
+
435
+ ### Platform-Specific Notes
436
+
437
+ - **Prisma**: Database client generation and migrations are handled at runtime. For Node.js applications, you may need to run manually:
438
+ ```bash
439
+ npx prisma generate # Generate client code
440
+ npx prisma migrate deploy # Apply database migrations
441
+ ```
442
+
443
+ For Electron applications, database setup is handled automatically.
444
+
445
+ - **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.
446
+
447
+ ## Notes
448
+
449
+ - Local binary workflow
450
+ - The binary download/prepare workflow is implemented in `scripts/binSetup.js` (calls `scripts/binManage.js`).
451
+ - Download sources are configured in `binaries.json` per-platform (`darwin-arm64`, `darwin-x64`, `linux-x64`).
452
+ - Binaries are stored under `./bin` by default; you can override via `LINK_BINARY_PATH`.
453
+ - Job system
454
+ - The system initializes with state-driven tasks; no manual `startJobs` events are needed.
455
+ - Error handling
456
+ - Improved error typing in `business/job/core/StateManager.js` for better diagnostics.
457
+
458
+ ## Key Features
459
+ * SDK Library based on Nostr Asset Protocol.
460
+ * Integration with LND and RGB nodes.
461
+ * Enables Nostr-based functionalities for Lightning and RGB assets.