Skip to content

Commit 8c0b392

Browse files
Merge branch 'light' into master
2 parents 9e67279 + 46750eb commit 8c0b392

35 files changed

+1293
-935
lines changed

.github/workflows/build.yml

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Build and Release
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
tags:
7+
- 'v*'
8+
pull_request:
9+
branches: [ master ]
10+
workflow_dispatch:
11+
12+
jobs:
13+
build:
14+
runs-on: ${{ matrix.os }}
15+
16+
strategy:
17+
matrix:
18+
os: [ubuntu-latest, windows-latest, macos-latest]
19+
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- name: Setup Node.js
24+
uses: actions/setup-node@v4
25+
with:
26+
node-version: '18.x'
27+
cache: 'npm'
28+
29+
- name: Install dependencies
30+
run: npm ci
31+
32+
- name: Build React app
33+
env:
34+
CI: false
35+
run: npm run build
36+
37+
- name: Build Electron app
38+
if: matrix.os != 'ubuntu-latest'
39+
run: npm run electron-build
40+
env:
41+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42+
43+
- name: Build Electron app (Linux)
44+
if: matrix.os == 'ubuntu-latest'
45+
shell: bash
46+
run: |
47+
npm run electron-build
48+
# Remove chrome-sandbox from both unpacked and packaged versions
49+
rm -f dist/linux-unpacked/chrome-sandbox
50+
cd dist
51+
tar xzf drivechain-launcher-*.tar.gz
52+
rm -f drivechain-launcher-*/chrome-sandbox
53+
tar czf drivechain-launcher-*.tar.gz drivechain-launcher-*/
54+
rm -rf drivechain-launcher-*/
55+
env:
56+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57+
58+
- name: Upload Linux artifacts
59+
if: matrix.os == 'ubuntu-latest'
60+
uses: actions/upload-artifact@v4
61+
with:
62+
name: linux-artifacts
63+
path: |
64+
dist/drivechain-launcher-*.tar.gz
65+
66+
- name: Upload Windows artifacts
67+
if: matrix.os == 'windows-latest'
68+
uses: actions/upload-artifact@v4
69+
with:
70+
name: windows-artifacts
71+
path: dist/Drivechain-Launcher-Setup-*.exe
72+
73+
- name: Upload macOS artifacts
74+
if: matrix.os == 'macos-latest'
75+
uses: actions/upload-artifact@v4
76+
with:
77+
name: macos-artifacts
78+
path: |
79+
dist/Drivechain-Launcher-*-x64.dmg
80+
dist/Drivechain-Launcher-*-arm64.dmg

README.md

-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ Drivechain Launcher is an **Electron-based desktop application** that allows use
88
- 🔄 **Start and stop individual chains**
99
- ♻️ **Reset chain data**
1010
- 📊 **View chain details and settings**
11-
- 🌗 **Dark/Light mode toggle**
1211
- 🖥️ **Cross-platform support (Windows, macOS, Linux)**
1312

1413
## 📚 Table of Contents

package.json

+41-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
"name": "drivechain-launcher",
33
"version": "0.1.0",
44
"private": true,
5+
"description": "Drivechain Launcher Application",
6+
"author": {
7+
"name": "Drivechain",
8+
"email": "support@drivechain.info"
9+
},
510
"main": "public/electron.js",
611
"homepage": "./",
712
"dependencies": {
@@ -20,8 +25,6 @@
2025
"bitcoinjs-lib": "^6.1.7",
2126
"concurrently": "^8.2.2",
2227
"cross-env": "^7.0.3",
23-
"electron": "^28.1.0",
24-
"electron-builder": "^24.9.1",
2528
"electron-dl": "^4.0.0",
2629
"electron-is-dev": "^2.0.0",
2730
"electron-store": "^10.0.0",
@@ -74,7 +77,43 @@
7477
"last 1 safari version"
7578
]
7679
},
80+
"build": {
81+
"appId": "com.drivechain.launcher",
82+
"productName": "Drivechain Launcher",
83+
"files": [
84+
"build/**/*",
85+
"public/**/*"
86+
],
87+
"directories": {
88+
"buildResources": "public"
89+
},
90+
"linux": {
91+
"target": ["deb", "tar.gz"],
92+
"category": "Development",
93+
"maintainer": "Drivechain <support@drivechain.info>",
94+
"asarUnpack": ["**/chrome-sandbox"],
95+
"executableName": "drivechain-launcher",
96+
"executableArgs": ["--no-sandbox"],
97+
"artifactName": "Drivechain-Launcher-${version}-${arch}.${ext}"
98+
},
99+
"win": {
100+
"target": "nsis",
101+
"artifactName": "Drivechain-Launcher-Setup-${version}.${ext}"
102+
},
103+
"mac": {
104+
"target": [
105+
{
106+
"target": "dmg",
107+
"arch": ["x64", "arm64"]
108+
}
109+
],
110+
"category": "public.app-category.developer-tools",
111+
"artifactName": "Drivechain-Launcher-${version}-${arch}.${ext}"
112+
}
113+
},
77114
"devDependencies": {
115+
"electron": "^28.1.0",
116+
"electron-builder": "^24.9.1",
78117
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
79118
"@babel/plugin-transform-modules-commonjs": "^7.26.3",
80119
"@babel/preset-env": "^7.26.0",

public/chain_config.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@
8787
}
8888
},
8989
"binary": {
90-
"linux": "bip300301-enforcer-latest-x86_64-unknown-linux-gnu/bip300301_enforcer-0.3.1-x86_64-unknown-linux-gnu",
91-
"darwin": "bip300301-enforcer-latest-x86_64-apple-darwin/bip300301_enforcer-0.3.1-x86_64-apple-darwin",
92-
"win32": "bip300301-enforcer-latest-x86_64-pc-windows-gnu/bip300301_enforcer-0.3.1-x86_64-pc-windows-gnu.exe"
90+
"linux": "bip300301-enforcer-latest-x86_64-unknown-linux-gnu/bip300301-enforcer-latest-x86_64-unknown-linux-gnu",
91+
"darwin": "bip300301-enforcer-latest-x86_64-apple-darwin/bip300301-enforcer-latest-x86_64-apple-darwin",
92+
"win32": "bip300301-enforcer-latest-x86_64-pc-windows-gnu/bip300301-enforcer-latest-x86_64-pc-windows-gnu.exe"
9393
},
9494
"network": {
9595
"port": 0

public/electron.js

+146-22
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
const { app, BrowserWindow, ipcMain, shell } = require("electron");
2+
3+
// Disable sandbox for Linux
4+
if (process.platform === 'linux') {
5+
app.commandLine.appendSwitch('no-sandbox');
6+
app.commandLine.appendSwitch('disable-setuid-sandbox');
7+
process.env.ELECTRON_DISABLE_SANDBOX = '1';
8+
}
29
const path = require("path");
310
const fs = require("fs-extra");
411
const isDev = require("electron-is-dev");
@@ -42,6 +49,7 @@ function createWindow() {
4249
contextIsolation: true,
4350
nodeIntegration: false,
4451
preload: path.join(__dirname, "preload.js"),
52+
sandbox: false
4553
},
4654
});
4755
mainWindow.loadURL(
@@ -304,6 +312,40 @@ function setupIPCHandlers() {
304312
}
305313
});
306314

315+
// Get wallet starter data
316+
ipcMain.handle("get-wallet-starter", async (event, type) => {
317+
try {
318+
const walletDir = path.join(app.getPath('userData'), 'wallet_starters');
319+
let filePath;
320+
321+
switch (type) {
322+
case 'master':
323+
filePath = path.join(walletDir, 'master_starter.json');
324+
break;
325+
case 'layer1':
326+
filePath = path.join(walletDir, 'l1_starter.json');
327+
break;
328+
case 'thunder':
329+
filePath = path.join(walletDir, 'sidechain_9_starter.json');
330+
break;
331+
case 'bitnames':
332+
filePath = path.join(walletDir, 'sidechain_2_starter.json');
333+
break;
334+
default:
335+
throw new Error('Invalid wallet type');
336+
}
337+
338+
if (await fs.pathExists(filePath)) {
339+
const data = await fs.readJson(filePath);
340+
return { success: true, data: data.mnemonic };
341+
}
342+
return { success: false, error: 'Wallet starter not found' };
343+
} catch (error) {
344+
console.error('Error reading wallet starter:', error);
345+
return { success: false, error: error.message };
346+
}
347+
});
348+
307349
// Advanced wallet handlers
308350
ipcMain.handle("preview-wallet", async (event, options) => {
309351
try {
@@ -347,6 +389,47 @@ function setupIPCHandlers() {
347389
return await updateManager.checkForUpdates();
348390
});
349391

392+
ipcMain.handle("apply-updates", async (event, chainIds) => {
393+
try {
394+
// First stop any running chains
395+
for (const chainId of chainIds) {
396+
const status = await chainManager.getChainStatus(chainId);
397+
if (status === 'running' || status === 'ready') {
398+
await chainManager.stopChain(chainId);
399+
}
400+
}
401+
402+
// Delete existing binaries and download updates
403+
for (const chainId of chainIds) {
404+
const chain = config.chains.find(c => c.id === chainId);
405+
if (!chain) continue;
406+
407+
// Get extract path
408+
const platform = process.platform;
409+
const extractDir = chain.extract_dir?.[platform];
410+
if (!extractDir) continue;
411+
412+
const downloadsDir = app.getPath("downloads");
413+
const extractPath = path.join(downloadsDir, extractDir);
414+
415+
// Delete existing binary directory
416+
await fs.remove(extractPath);
417+
418+
// Download and extract new binary
419+
const url = chain.download.urls[platform];
420+
if (!url) continue;
421+
422+
await fs.ensureDir(extractPath);
423+
downloadManager.startDownload(chainId, url, extractPath);
424+
}
425+
426+
return { success: true };
427+
} catch (error) {
428+
console.error('Failed to apply updates:', error);
429+
return { success: false, error: error.message };
430+
}
431+
});
432+
350433
ipcMain.handle("get-balance-btc", async (event, options) => {
351434
try {
352435
return await fastWithdrawalManager.getBalanceBTC();
@@ -384,33 +467,74 @@ function setupIPCHandlers() {
384467
}
385468
});
386469

470+
// Wallet directory handlers
471+
ipcMain.handle("delete-wallet-starters-dir", async () => {
472+
try {
473+
const walletDir = path.join(app.getPath('userData'), 'wallet_starters');
474+
if (await fs.pathExists(walletDir)) {
475+
await fs.remove(walletDir);
476+
}
477+
return { success: true };
478+
} catch (error) {
479+
console.error('Failed to delete wallet starters directory:', error);
480+
return { success: false, error: error.message };
481+
}
482+
});
483+
484+
ipcMain.handle("init-wallet-dirs", async () => {
485+
try {
486+
const walletDir = path.join(app.getPath('userData'), 'wallet_starters');
487+
const mnemonicsDir = path.join(walletDir, 'mnemonics');
488+
await fs.ensureDir(walletDir);
489+
await fs.ensureDir(mnemonicsDir);
490+
return { success: true };
491+
} catch (error) {
492+
console.error('Failed to initialize wallet directories:', error);
493+
return { success: false, error: error.message };
494+
}
495+
});
496+
387497
ipcMain.handle('force-kill', () => {
388498
forceKillAllProcesses();
389499
});
390500
}
391501

392-
app.whenReady().then(async () => {
393-
await loadConfig();
394-
395-
// Initialize managers
396-
directoryManager = new DirectoryManager(config);
397-
await directoryManager.setupChainDirectories();
398-
399-
const configManager = new ConfigManager(configPath);
400-
await configManager.loadConfig();
401-
await configManager.setupExtractDirectories();
402-
403-
createWindow();
404-
405-
chainManager = new ChainManager(mainWindow, config);
406-
walletManager = new WalletManager(config);
407-
fastWithdrawalManager = new FastWithdrawalManager();
408-
apiManager = new ApiManager();
409-
updateManager = new UpdateManager(config, chainManager);
410-
downloadManager = new DownloadManager(mainWindow, config);
411-
412-
setupIPCHandlers();
413-
});
502+
async function initialize() {
503+
try {
504+
await loadConfig();
505+
506+
// Initialize managers that don't depend on mainWindow
507+
directoryManager = new DirectoryManager(config);
508+
await directoryManager.setupChainDirectories();
509+
510+
const configManager = new ConfigManager(configPath);
511+
await configManager.loadConfig();
512+
await configManager.setupExtractDirectories();
513+
514+
walletManager = new WalletManager(config);
515+
fastWithdrawalManager = new FastWithdrawalManager();
516+
apiManager = new ApiManager();
517+
518+
// Create window first
519+
createWindow();
520+
521+
// Then initialize managers that need mainWindow
522+
chainManager = new ChainManager(mainWindow, config);
523+
updateManager = new UpdateManager(config, chainManager);
524+
downloadManager = new DownloadManager(mainWindow, config);
525+
526+
// Finally setup IPC handlers after everything is initialized
527+
setupIPCHandlers();
528+
} catch (error) {
529+
console.error('Initialization error:', error);
530+
app.quit();
531+
}
532+
}
533+
534+
// Disable sandbox
535+
app.commandLine.appendSwitch('no-sandbox');
536+
537+
app.whenReady().then(initialize);
414538

415539
let isShuttingDown = false;
416540
let forceKillTimeout;

0 commit comments

Comments
 (0)