Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/docs/Contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ source env-local.sh
- OR Run the setup script. Note that it requires `socat` and `jq` to run successfully:

```sh
source entrypoint.sh
source ./scripts/entrypoint.sh
```

Running the Application
Expand Down Expand Up @@ -100,6 +100,7 @@ git push
```sh
git checkout main
git merge Release-yy.mm.n
git push
```
- Create versioned tag:

Expand Down
24 changes: 24 additions & 0 deletions .github/docs/Troubleshooting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Debugging Commando Connection
-----------------------------

#### Configure the environment (if not already done):

```sh
cp env.sh env-local.sh
# Edit env-local.sh with your local configuration
source env-local.sh
```

#### Set up Commando authentication (if not already done):

- You can configure Commando credentials in one of the following ways:
- Manual setup: Update LIGHTNING_PUBKEY and LIGHTNING_RUNE in your LIGHTNING_VARS_FILE.
- Automated setup: Run the setup script (requires socat and jq): `source ./scripts/entrypoint.sh`

#### Verify the Commando connection:

After all environment variables are set, run the following script to verify that Commando environment variables are configured and loaded correctly

```sh
node ./scripts/check-commando-connection.js
```
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,8 @@

- Click [here](./.github/docs/Contributing.md) for instructions on how to run it in development mode.

- Follow the steps outlined in [troubleshooting](./.github/docs/Troubleshooting.md) to verify that your Commando connection is successfully established with your current environment setup.

---

# Acknowledgements
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "Core lightning application",
"private": true,
"license": "MIT",
"type": "module",
"scripts": {
"frontend:dev": "npm run start -w cln-application-frontend",
"frontend:build": "npm run build -w cln-application-frontend",
Expand Down
93 changes: 93 additions & 0 deletions scripts/check-commando-connection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import Lnmessage from 'lnmessage';
import WebSocket from 'ws';
import fs from 'fs';
import crypto from 'crypto';
import { exit } from 'process';

const LIGHTNING_VARS_FILE = process.env.LIGHTNING_VARS_FILE || `${process.cwd()}/.commando`;
const WS_PROTOCOL = process.env.LIGHTNING_WS_PROTOCOL;
const NODE_IP = process.env.LIGHTNING_WS_HOST;
const WS_PORT = process.env.LIGHTNING_WS_PORT;
let NODE_PUBKEY;
let RUNE;

if (!LIGHTNING_VARS_FILE) {
console.error(`[ERROR - ${new Date().toISOString()}]: LIGHTNING_VARS_FILE environment variable not set`);
exit(1);
}

try {
const fileContent = fs.readFileSync(LIGHTNING_VARS_FILE, 'utf8');
const lines = fileContent.split('\n');

for (const line of lines) {
const trimmedLine = line.trim();
if (trimmedLine.startsWith('LIGHTNING_PUBKEY=')) {
NODE_PUBKEY = trimmedLine.split('=')[1].replace(/"/g, '');
} else if (trimmedLine.startsWith('LIGHTNING_RUNE=')) {
RUNE = trimmedLine.split('=')[1].replace(/"/g, '');
}
}
} catch (err) {
console.error(`[ERROR - ${new Date().toISOString()}]: Failed to read file ${LIGHTNING_VARS_FILE}:`, err.message);
exit(1);
}

if (!NODE_PUBKEY) {
console.error(`[ERROR - ${new Date().toISOString()}]: LIGHTNING_PUBKEY not found in file`);
exit(1);
}
if (!RUNE) {
console.error(`[ERROR - ${new Date().toISOString()}]: LIGHTNING_RUNE not found in file`);
exit(1);
}

class SecureWebSocket extends WebSocket {
constructor(url) {
const options = {};
options.rejectUnauthorized = false;
options.cert = fs.readFileSync(process.env.LIGHTNING_WS_CLIENT_CERT_FILE);
options.key = fs.readFileSync(process.env.LIGHTNING_WS_CLIENT_KEY_FILE);
super(url, options);
}
}

if (WS_PROTOCOL === 'wss') { globalThis.WebSocket = SecureWebSocket; }

let lnmessageOptions = {
ip: NODE_IP,
remoteNodePublicKey: NODE_PUBKEY,
privateKey: crypto.randomBytes(32).toString('hex'),
wsProxy: `${WS_PROTOCOL}://${NODE_IP}:${WS_PORT}`,
port: WS_PORT,
logger: { info: console.log, warn: console.log, error: console.error }
}
console.log(`[INFO - ${new Date().toISOString()}]: lnMessage Options `, lnmessageOptions);

const ln = new Lnmessage(lnmessageOptions)
console.log(`[INFO - ${new Date().toISOString()}]: Initialized lnMessage`);

ln.connectionStatus$.subscribe(status => {
if (status === 'failed') {
console.error(`[ERROR - ${new Date().toISOString()}]: Failed to reconnect after maximum attempts`);
exit(1);
}
});

console.log(`[INFO - ${new Date().toISOString()}]: Connecting...`);
try {
await ln.connect();
console.log(`[INFO - ${new Date().toISOString()}]: Connected`);
} catch (err) {
console.error(`[ERROR - ${new Date().toISOString()}]: Connection failed! Error:\n`, err);
exit(1);
}

try {
const getinfoResponse = await ln.commando({reqId: crypto.randomBytes(8).toString('hex'), method: 'getinfo', params: [], rune: RUNE});
console.log(`[INFO - ${new Date().toISOString()}]: Connection successful! Getinfo Response:\n`, getinfoResponse);
exit(0);
} catch (err) {
console.error(`[ERROR - ${new Date().toISOString()}]: Connection failed! Getinfo Error:\n`, err);
exit(1);
}
File renamed without changes.