diff --git a/main.js b/main.js
index 4d34178..ed541d5 100644
--- a/main.js
+++ b/main.js
@@ -1,68 +1,76 @@
// Modules to control application life and create native browser window
const {app, ipcMain, BrowserWindow} = require('electron');
+const singleInstance = require('single-instance');
const path = require('path');
const fs = require('fs');
-// Keep a global reference of the window object, if you don't, the window will
-// be closed automatically when the JavaScript object is garbage collected.
-let mainWindow
+var locker = new singleInstance('Ether1DesktopWallet');
-function createWindow () {
- // Create the browser window.
- mainWindow = new BrowserWindow({
- width: 1200,
- height: 800,
- minWidth: 1100,
- minHeight: 700,
- backgroundColor: "#000000"
- });
+locker.lock().then(function() {
+ // Keep a global reference of the window object, if you don't, the window will
+ // be closed automatically when the JavaScript object is garbage collected.
+ let mainWindow
- // and load the index.html of the app.
- mainWindow.loadFile('index.html');
- EthoGeth.startGeth();
+ function createWindow () {
+ // Create the browser window.
+ mainWindow = new BrowserWindow({
+ width: 1200,
+ height: 800,
+ minWidth: 1100,
+ minHeight: 700,
+ backgroundColor: "#000000"
+ });
- // Open the DevTools.
- // mainWindow.webContents.openDevTools()
+ // and load the index.html of the app.
+ mainWindow.loadFile('index.html');
+ EthoGeth.startGeth();
- // Emitted when the window is closed.
- mainWindow.on('closed', function () {
- // Dereference the window object, usually you would store windows
- // in an array if your app supports multi windows, this is the time
- // when you should delete the corresponding element.
- mainWindow = null
+ // Open the DevTools.
+ // mainWindow.webContents.openDevTools()
+
+ // Emitted when the window is closed.
+ mainWindow.on('closed', function () {
+ // Dereference the window object, usually you would store windows
+ // in an array if your app supports multi windows, this is the time
+ // when you should delete the corresponding element.
+ mainWindow = null
+ })
+ }
+
+ // This method will be called when Electron has finished
+ // initialization and is ready to create browser windows.
+ // Some APIs can only be used after this event occurs.
+ app.on('ready', createWindow)
+
+ // Quit when all windows are closed.
+ app.on('window-all-closed', function () {
+ // On OS X it is common for applications and their menu bar
+ // to stay active until the user quits explicitly with Cmd + Q
+ if (process.platform !== 'darwin') {
+ EthoGeth.stopGeth();
+ app.quit();
+ }
})
-}
-// This method will be called when Electron has finished
-// initialization and is ready to create browser windows.
-// Some APIs can only be used after this event occurs.
-app.on('ready', createWindow)
+ app.on('activate', function () {
+ // On OS X it's common to re-create a window in the app when the
+ // dock icon is clicked and there are no other windows open.
+ if (mainWindow === null) {
+ createWindow()
+ }
+ })
-// Quit when all windows are closed.
-app.on('window-all-closed', function () {
- // On OS X it is common for applications and their menu bar
- // to stay active until the user quits explicitly with Cmd + Q
- if (process.platform !== 'darwin') {
- EthoGeth.stopGeth();
- app.quit()
- }
+ // In this file you can include the rest of your app's specific main process
+ // code. You can also put them in separate files and require them here.
+ // listen for request to get template
+ ipcMain.on('getTemplateContent', (event, arg) => {
+ event.returnValue = fs.readFileSync(path.join(app.getAppPath(), "assets/templates/") + arg, 'utf8');
+ });
})
-
-app.on('activate', function () {
- // On OS X it's common to re-create a window in the app when the
- // dock icon is clicked and there are no other windows open.
- if (mainWindow === null) {
- createWindow()
- }
+.catch(function(err) {
+ app.quit();
})
-// In this file you can include the rest of your app's specific main process
-// code. You can also put them in separate files and require them here.
-// listen for request to get template
-ipcMain.on('getTemplateContent', (event, arg) => {
- event.returnValue = fs.readFileSync(path.join(app.getAppPath(), "assets/templates/") + arg, 'utf8');
-});
-
require('./modules/geth.js');
require('./modules/accounts.js');
require('./modules/database.js');
\ No newline at end of file
diff --git a/modules/database.js b/modules/database.js
index 1650dac..715e41c 100644
--- a/modules/database.js
+++ b/modules/database.js
@@ -14,7 +14,7 @@ db.ensureIndex({ fieldName: 'block' }, function (err) {
});
ipcMain.on('storeTransaction', (event, arg) => {
- db.update({ block: arg.block, fromaddr: arg.fromaddr, toaddr: arg.toaddr }, arg, { upsert: true }, function (err, numReplaced, upsert) {
+ db.update({ txhash: arg.txhash }, arg, { upsert: true }, function (err, numReplaced, upsert) {
// do nothing for now
});
});
@@ -29,8 +29,7 @@ ipcMain.on('getTransactions', (event, arg) => {
docs[i].timestamp,
docs[i].fromaddr,
docs[i].toaddr,
- docs[i].value,
- docs[i].confirmed || 1
+ docs[i].value
]);
}
diff --git a/modules/geth.js b/modules/geth.js
index e7ec1ca..372642d 100644
--- a/modules/geth.js
+++ b/modules/geth.js
@@ -53,8 +53,8 @@ class Geth {
this.gethProcess.stdout.on('data', function(data) {
EthoGeth._writeLog(data.toString() + '\n');
});
- } catch (e) {
- dialog.showErrorBox("Error starting application", e);
+ } catch (err) {
+ dialog.showErrorBox("Error starting application", err.message);
app.quit();
}
}
diff --git a/package.json b/package.json
index 9b73c28..f02b844 100644
--- a/package.json
+++ b/package.json
@@ -21,18 +21,18 @@
"win": {
"icon": "build/icon.png",
"target": "7z",
- "artifactName": "Windows-${productName}-${version}.${ext}",
+ "artifactName": "Windows-${productName}-${version}.${ext}",
"extraResources": [
"bin/win/*"
]
},
"linux": {
"target": "tar.gz",
- "artifactName": "Linux-${productName}-${version}.${ext}",
+ "artifactName": "Linux-${productName}-${version}.${ext}",
"extraResources": [
"bin/linux/*"
]
- }
+ }
},
"repository": "https://github.com/taeguscromis/Ether1DesktopWallet",
"keywords": [
@@ -47,7 +47,8 @@
"app-root-path": "^2.1.0",
"electron-storage": "^1.0.7",
"handlebars": "^4.0.12",
- "nedb": "^1.8.0"
+ "nedb": "^1.8.0",
+ "single-instance": "0.0.1"
},
"devDependencies": {
"electron": "^3.0.12",
diff --git a/renderer/send.js b/renderer/send.js
index 5c74b4f..cfe7374 100644
--- a/renderer/send.js
+++ b/renderer/send.js
@@ -145,16 +145,14 @@ $(document).on("render_send", function() {
EthoMainGUI.showGeneralError(error);
},
function(transaction) {
- /*
ipcRenderer.send('storeTransaction', {
- block: element.block,
- fromaddr: element.fromaddr,
+ block: element.block.toString(),
+ txhash: element.hash.toLowerCase(),
+ fromaddr: element.fromaddr.toLowerCase(),
timestamp: element.timestamp,
- toaddr: element.toaddr,
- value: element.value,
- confirmed: "1",
+ toaddr: element.toaddr.toLowerCase(),
+ value: element.value
});
- */
}
);
}
diff --git a/renderer/syncing.js b/renderer/syncing.js
index 6052665..ee83e67 100644
--- a/renderer/syncing.js
+++ b/renderer/syncing.js
@@ -28,7 +28,7 @@ SyncProgress = new ProgressBar.Line('#syncProgress',
});
// set initial value for the progress text
-SyncProgress.setText("initializing, please wait...");
+SyncProgress.setText("Waiting for blockchain, please wait...");
var peerCountInterval = setInterval(function()
{
@@ -39,61 +39,67 @@ var peerCountInterval = setInterval(function()
function StartSyncProcess() {
var alreadyCatchedUp = false;
+ var nodeSyncInterval = null;
- function keepTheNodeInSync(interval) {
- var nodeSyncInterval = setInterval(function()
- {
- web3Local.eth.isSyncing(function(error, sync)
- {
- if(!error) {
- if(sync == true) {
- console.log("start the sync");
- } else if(sync) {
- SyncProgress.animate(sync.currentBlock / sync.highestBlock);
- SyncProgress.setText(vsprintf('%d/%d (%d%%)', [sync.currentBlock, sync.highestBlock, Math.round(sync.currentBlock / sync.highestBlock * 100)]));
- } else {
- web3Local.eth.getBlock("latest", function(error, localBlock) {
- if (localBlock.number > 0) {
- web3Remote.eth.getBlock("latest", function(error, remoteBlock) {
- if (!EthoTransactions.getIsSyncing()) {
- SyncProgress.animate(localBlock.number / remoteBlock.number);
- SyncProgress.setText(vsprintf('%d/%d (%d%%)', [localBlock.number, remoteBlock.number, Math.round(localBlock.number / remoteBlock.number * 100)]));
- }
-
- if (remoteBlock.number == localBlock.number) {
- if (alreadyCatchedUp == false)
- {
- // clear the repeat interval and render wallets
- $(document).trigger("onNewAccountTransaction");
- clearInterval(nodeSyncInterval);
- alreadyCatchedUp = true;
-
- // sync all the transactions to the current block
- EthoTransactions.syncTransactionsForAllAddresses(localBlock.number);
- $(document).trigger("onSyncInterval");
-
- // restart with less intensity
- keepTheNodeInSync(10000);
- }
- }
- });
- }
- });
- }
+ var subscription = web3Local.eth.subscribe('syncing', function(error, sync){
+ if (!error) {
+ if (!sync) {
+ if (nodeSyncInterval) {
+ clearInterval(nodeSyncInterval);
}
- });
- }, interval);
- }
- // initial fast syncing
- keepTheNodeInSync(2000);
+ nodeSyncInterval = setInterval(function()
+ {
+ web3Local.eth.getBlock("latest", function(error, localBlock) {
+ if (localBlock.number > 0) {
+ if (!EthoTransactions.getIsSyncing()) {
+ SyncProgress.animate(1);
+ SyncProgress.setText(vsprintf('%d/%d (100%%)', [localBlock.number, localBlock.number]));
+ }
+
+ if (alreadyCatchedUp == false)
+ {
+ // clear the repeat interval and render wallets
+ $(document).trigger("onNewAccountTransaction");
+ alreadyCatchedUp = true;
+
+ // sync all the transactions to the current block
+ EthoTransactions.syncTransactionsForAllAddresses(localBlock.number);
+ $(document).trigger("onSyncInterval");
+ }
+ }
+ });
+ }, 10000);
+ }
+ }
+ }).on("data", function(sync){
+ if ((sync) && (sync.HighestBlock > 0)) {
+ SyncProgress.animate(sync.CurrentBlock / sync.HighestBlock);
+ SyncProgress.setText(vsprintf('%d/%d (%d%%)', [sync.CurrentBlock, sync.HighestBlock, Math.round(sync.CurrentBlock / sync.HighestBlock * 100)]));
+ }
+ }).on("changed", function(isSyncing){
+ if(isSyncing) {
+ nodeSyncInterval = setInterval(function()
+ {
+ web3Local.eth.isSyncing(function(error, sync){
+ if ((!error) && (sync)) {
+ SyncProgress.animate(sync.currentBlock / sync.highestBlock);
+ SyncProgress.setText(vsprintf('%d/%d (%d%%)', [sync.currentBlock, sync.highestBlock, Math.round(sync.currentBlock / sync.highestBlock * 100)]));
+ }
+ });
+ }, 2000);
+ } else {
+ if (nodeSyncInterval) {
+ clearInterval(nodeSyncInterval);
+ }
+ }
+ });
}
var InitWeb3 = setInterval(function()
{
try {
web3Local = new Web3(new Web3.providers.WebsocketProvider('ws://localhost:8546'));
- web3Remote = new Web3(new Web3.providers.HttpProvider("https://rpc.ether1.org"));
web3Local.eth.net.isListening(function(error, success) {
if (!error) {
diff --git a/renderer/transactions.js b/renderer/transactions.js
index 342a2d8..4cb36ec 100644
--- a/renderer/transactions.js
+++ b/renderer/transactions.js
@@ -36,13 +36,12 @@ class Transactions {
$.getJSON("https://richlist.ether1.org/transactions_list.php" + params, function( result ) {
result.data.forEach(element => {
ipcRenderer.send('storeTransaction', {
- block: element.block,
- txhash: element.hash,
- fromaddr: element.fromaddr,
+ block: element.block.toString(),
+ txhash: element.txhash.toLowerCase(),
+ fromaddr: element.fromaddr.toLowerCase(),
timestamp: element.timestamp,
- toaddr: element.toaddr,
- value: element.value,
- confirmed: "1"
+ toaddr: element.toaddr.toLowerCase(),
+ value: element.value
});
});
@@ -149,11 +148,12 @@ class Transactions {
},
{
"targets": 6,
+ "defaultContent": "",
"render": function ( data, type, row ) {
- if (data == 0) {
- return '';
- } else if (data == 1) {
+ if (row[1]) {
return '';
+ } else if (data == 1) {
+ return '';
}
}
}
@@ -196,11 +196,11 @@ $(document).on("onSyncInterval", function() {
if ((EthoWallets.getAddressExists(element.from)) || (EthoWallets.getAddressExists(element.to))) {
var Transaction = {
block: element.blockNumber.toString(),
+ txhash: element.hash.toLowerCase(),
fromaddr: element.from.toLowerCase(),
timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
toaddr: element.to.toLowerCase(),
- value: Number(element.value).toExponential(5).toString().replace('+',''),
- confirmed: "0",
+ value: Number(element.value).toExponential(5).toString().replace('+','')
}
// store transaction and notify about new transactions