+ beautifier

* version info
This commit is contained in:
Taegus
2019-03-03 10:37:19 +01:00
parent de73afd5cd
commit b0cd7d517a
19 changed files with 1648 additions and 1697 deletions

7
.unibeautifyrc.json Normal file
View File

@@ -0,0 +1,7 @@
{
"LANGUAGE_NAME": {
"beautifiers": [
"JS-Beautify"
]
}
}

View File

@@ -1,5 +1,6 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Ether-1 Desktop Wallet</title>
@@ -17,7 +18,12 @@
<link rel="stylesheet" href="./assets/styles/style.css">
<link rel="stylesheet" href="./assets/styles/forms.css">
<!-- Insert this line above script imports -->
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
<script>
if (typeof module === 'object') {
window.module = module;
module = undefined;
}
</script>
<!-- normal script imports etc -->
<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js@1.0.0-beta.36/dist/web3.min.js" integrity="sha256-nWBTbvxhJgjslRyuAKJHK+XcZPlCnmIAAMixz6EefVk=" crossorigin="anonymous"></script>
@@ -39,15 +45,15 @@
<script src="./assets/scripts/Chart.js"></script>
<!-- Insert this line after script imports -->
<script>if (window.module) module = window.module;</script>
<script>
if (window.module)
module = window.module;
</script>
</head>
<body>
<script>
var loading_screen = pleaseWait({
logo: "assets/images/logo.png",
backgroundColor: '#000000',
loadingHtml: "<div class='spinner'><div class='bounce bounce1'></div><div class='bounce bounce2'></div><div class='bounce bounce3'></div></div><div class='loadingText'>Starting the node and loading app, please wait...</div>"
});
var loading_screen = pleaseWait({logo: "assets/images/logo.png", backgroundColor: '#000000', loadingHtml: "<div class='spinner'><div class='bounce bounce1'></div><div class='bounce bounce2'></div><div class='bounce bounce3'></div></div><div class='loadingText'>Starting the node and loading app, please wait...</div>"});
$(document).on("onGethReady", function () {
loading_screen.finish();
@@ -61,22 +67,34 @@
<!-- The sidebar -->
<div class="sidebar">
<div class="sidebarIconWrapper iconSelected" id="mainNavBtnWalletsWrapper" data-tippy="Wallets" data-tippy-delay="500">
<a class="sidebarIcon" id="mainNavBtnWallets" href="#"><i class="fas fa-wallet fa-2x"></i></a>
<a class="sidebarIcon" id="mainNavBtnWallets" href="#">
<i class="fas fa-wallet fa-2x"></i>
</a>
</div>
<div class="sidebarIconWrapper iconSelected" id="mainNavBtnAddressBoookWrapper" data-tippy="Address Book" data-tippy-delay="500">
<a class="sidebarIcon" id="mainNavBtnAddressBoook" href="#"><i class="far fa-address-book fa-2x"></i></a>
<a class="sidebarIcon" id="mainNavBtnAddressBoook" href="#">
<i class="far fa-address-book fa-2x"></i>
</a>
</div>
<div class="sidebarIconWrapper" id="mainNavBtnSendWrapper" data-tippy="Send Funds" data-tippy-delay="500">
<a class="sidebarIcon" id="mainNavBtnSend" href="#"><i class="fas fas fa-share-square fa-2x"></i></a>
<a class="sidebarIcon" id="mainNavBtnSend" href="#">
<i class="fas fas fa-share-square fa-2x"></i>
</a>
</div>
<div class="sidebarIconWrapper" id="mainNavBtnTransactionsWrapper" data-tippy="Transactions" data-tippy-delay="500">
<a class="sidebarIcon" id="mainNavBtnTransactions" href="#"><i class="fas fa-exchange-alt fa-2x"></i></a>
<a class="sidebarIcon" id="mainNavBtnTransactions" href="#">
<i class="fas fa-exchange-alt fa-2x"></i>
</a>
</div>
<div class="sidebarIconWrapper" id="mainNavBtnMarketsWrapper" data-tippy="Markets" data-tippy-delay="500">
<a class="sidebarIcon" id="mainNavBtnMarkets" href="#"><i class="fas fa-poll fa-2x"></i></a>
<a class="sidebarIcon" id="mainNavBtnMarkets" href="#">
<i class="fas fa-poll fa-2x"></i>
</a>
</div>
<div class="sidebarIconWrapper" id="mainNavBtnSettingsWrapper" data-tippy="Settings" data-tippy-delay="500">
<a class="sidebarIcon" id="mainNavBtnSettings" href="#"><i class="fas fa-cog fa-2x"></i></a>
<a class="sidebarIcon" id="mainNavBtnSettings" href="#">
<i class="fas fa-cog fa-2x"></i>
</a>
</div>
<div id="peerCount">
Peer Count: 0
@@ -102,7 +120,7 @@
</div>
<!-- The modal for general error -->
<div id="dlgGeneralError" class="modalDialog" data-iziModal-title="Application Error" data-iziModal-subtitle="Something went wrong, don't kill the fish..." data-iziModal-icon="icon-home">
<div id="dlgGeneralError" class="modalDialog" data-izimodal-title="Application Error" data-izimodal-subtitle="Something went wrong, don't kill the fish..." data-izimodal-icon="icon-home">
<div class="modalBody">
<div class="form-group">
<span id="txtGeneralError"></span>
@@ -112,7 +130,7 @@
</div>
<!-- The modal for general confirmation -->
<div id="dlgGeneralConfirm" class="modalDialog" data-iziModal-title="Confirmation" data-iziModal-subtitle="" data-iziModal-icon="icon-home">
<div id="dlgGeneralConfirm" class="modalDialog" data-izimodal-title="Confirmation" data-izimodal-subtitle="" data-izimodal-icon="icon-home">
<div class="modalBody">
<div class="form-group">
<span id="txtGeneralConfirm"></span>
@@ -123,16 +141,22 @@
</div>
<!-- The modal for about info -->
<div id="dlgAboutInfo" class="modalDialog" data-iziModal-title="About Ether1 Wallet" data-iziModal-icon="icon-home">
<div id="dlgAboutInfo" class="modalDialog" data-izimodal-title="About Ether1 Wallet" data-izimodal-icon="icon-home">
<div class="modalBody">
<div class="aboutInfo">
<div class="infoText" id="aboutInfoWallet">Ether1 Wallet</div>
<div class="infoText" id="aboutInfoGitHub">GitHub: <a id="urlOpenGitHub" href="https://github.com/taeguscromis/Ether1DesktopWallet">https://github.com/taeguscromis/Ether1DesktopWallet</a></div>
<div class="infoText" id="aboutInfoLicence">Made under <a id="urlOpenLicence" href="https://choosealicense.com/licenses/gpl-3.0">GPL v3.0</a> licence</div>
<div class="infoText" id="aboutInfoVersion">Version: <span id="versionNumber"></span></div>
<div class="infoText" id="aboutInfoGitHub">GitHub:
<a id="urlOpenGitHub" href="https://github.com/taeguscromis/Ether1DesktopWallet">https://github.com/taeguscromis/Ether1DesktopWallet</a>
</div>
<div class="infoText" id="aboutInfoLicence">Made under
<a id="urlOpenLicence" href="https://choosealicense.com/licenses/gpl-3.0">GPL v3.0</a>
licence</div>
<div class="infoText" id="aboutInfoVersion">Version:
<span id="versionNumber"></span></div>
</div>
<button type="button" class="btn btn-etho btn-dialog-confirm" id="btnAboutInfoClose">Close</button>
</div>
</div>
</body>
</html>

54
main.js
View File

@@ -1,10 +1,10 @@
// Modules to control application life and create native browser window
const {app, Menu, ipcMain, BrowserWindow} = require('electron');
const singleInstance = require('single-instance');
const path = require('path');
const fs = require('fs');
const {app, Menu, ipcMain, BrowserWindow} = require("electron");
const singleInstance = require("single-instance");
const path = require("path");
const fs = require("fs");
var locker = new singleInstance('Ether1DesktopWallet');
var locker = new singleInstance("Ether1DesktopWallet");
locker.lock().then(function () {
// Keep a global reference of the window object, if you don't, the window will
@@ -19,69 +19,67 @@ locker.lock().then(function() {
minWidth: 1100,
minHeight: 700,
backgroundColor: "#000000",
icon: 'assets/images/icon.png'
icon: "assets/images/icon.png"
});
// and load the index.html of the app.
mainWindow.loadFile('index.html');
mainWindow.loadFile("index.html");
EthoGeth.startGeth();
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
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
mainWindow = null;
});
require('./modules/menu.js');
require("./modules/menu.js");
}
// 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("ready", createWindow);
// Quit when all windows are closed.
app.on('window-all-closed', function () {
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') {
if (process.platform !== "darwin") {
EthoGeth.stopGeth();
app.quit();
}
})
});
app.on('activate', function () {
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()
createWindow();
}
})
});
// 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
// get the template content from file
ipcMain.on('getTemplateContent', (event, arg) => {
event.returnValue = fs.readFileSync(path.join(app.getAppPath(), "assets/templates/") + arg, 'utf8');
ipcMain.on("getTemplateContent", (event, arg) => {
event.returnValue = fs.readFileSync(path.join(app.getAppPath(), "assets/templates/") + arg, "utf8");
});
// quit the app on coomand
ipcMain.on('appQuit', (event, arg) => {
ipcMain.on("appQuit", (event, arg) => {
app.quit();
});
}).catch(function (err) {
app.quit();
});
})
.catch(function(err) {
app.quit();
})
require('./modules/geth.js');
require('./modules/accounts.js');
require('./modules/database.js');
require("./modules/geth.js");
require("./modules/accounts.js");
require("./modules/database.js");

View File

@@ -1,26 +1,25 @@
const {app, dialog, ipcMain} = require('electron');
const admZip = require('adm-zip');
const path = require('path');
const fs = require('fs-extra');
const os = require('os');
const {app, dialog, ipcMain} = require("electron");
const admZip = require("adm-zip");
const path = require("path");
const fs = require("fs-extra");
const os = require("os");
class Accounts {
constructor() {
}
constructor() {}
getKeyStoreLocation() {
switch (os.type()) {
case "Darwin":
return path.join(os.homedir(), 'Library', 'Ether1', 'keystore');
return path.join(os.homedir(), "Library", "Ether1", "keystore");
break;
default:
return path.join(process.env.APPDATA, 'Ether1', 'keystore');
return path.join(process.env.APPDATA, "Ether1", "keystore");
}
}
exportAccounts() {
var savePath = dialog.showSaveDialog({
defaultPath: path.join(app.getPath('documents'), 'accounts.zip')
defaultPath: path.join(app.getPath("documents"), "accounts.zip")
});
if (savePath) {
@@ -43,7 +42,7 @@ class Accounts {
var extName = path.extname(accountsFile).toUpperCase();
const accPath = EthoAccounts.getKeyStoreLocation();
if (extName == '.ZIP') {
if (extName == ".ZIP") {
var zip = new admZip(accountsFile);
zip.extractAllTo(accPath, true);
return {success: true, text: "Accounts ware successfully imported."};
@@ -58,32 +57,29 @@ class Accounts {
}
saveAccount(account) {
fs.writeFile(path.join(tEthoAccountshis.getKeyStoreLocation(), '0x' + account.address), JSON.stringify(account), 'utf8', function() {
fs.writeFile(path.join(tEthoAccountshis.getKeyStoreLocation(), "0x" + account.address), JSON.stringify(account), "utf8", function () {
// file was written
});
}
}
ipcMain.on('exportAccounts', (event, arg) => {
ipcMain.on("exportAccounts", (event, arg) => {
EthoAccounts.exportAccounts();
});
ipcMain.on('importAccounts', (event, arg) => {
ipcMain.on("importAccounts", (event, arg) => {
var openPath = dialog.showOpenDialog({
defaultPath: app.getPath('documents'),
"filters":
[
defaultPath: app.getPath("documents"),
filters: [
{
"name": "archive",
"extensions": ["zip"]
},
{
"name": "json",
"extensions": ["json"]
},
{
"name": "All",
"extensions": ["*.*"]
name: "archive",
extensions: ["zip"]
}, {
name: "json",
extensions: ["json"]
}, {
name: "All",
extensions: ["*.*"]
}
]
});
@@ -95,7 +91,7 @@ ipcMain.on('importAccounts', (event, arg) => {
}
});
ipcMain.on('saveAccount', (event, arg) => {
ipcMain.on("saveAccount", (event, arg) => {
EthoAccounts.saveAccount(arg);
event.returnValue = true;
});

View File

@@ -1,45 +1,54 @@
const {app, dialog, ipcMain} = require('electron');
const storage = require('electron-storage');
const datastore = require('nedb');
const moment = require('moment');
const path = require('path');
const fs = require('fs');
const os = require('os');
const {app, dialog, ipcMain} = require("electron");
const storage = require("electron-storage");
const datastore = require("nedb");
const moment = require("moment");
const path = require("path");
const fs = require("fs");
const os = require("os");
const dbPath = path.join(app.getPath('userData'), 'storage.db');
const dbPath = path.join(app.getPath("userData"), "storage.db");
const db = new datastore({filename: dbPath});
db.loadDatabase(function (err) {
// Now commands will be executed
});
// index the block field
db.ensureIndex({ fieldName: 'block' }, function (err) {
db.ensureIndex({
fieldName: "block"
}, function (err) {
// If there was an error, err is not null
});
// index the txhash field
db.ensureIndex({ fieldName: 'txhash', unique: true }, function (err) {
db.ensureIndex({
fieldName: "txhash",
unique: true
}, function (err) {
// If there was an error, err is not null
});
ipcMain.on('storeTransaction', (event, arg) => {
db.update({ txhash: arg.txhash }, arg, { upsert: true }, function (err, numReplaced, upsert) {
ipcMain.on("storeTransaction", (event, arg) => {
db.update({
txhash: arg.txhash
}, arg, {
upsert: true
}, function (err, numReplaced, upsert) {
// do nothing for now
});
});
ipcMain.on('getTransactions', (event, arg) => {
ipcMain.on("getTransactions", (event, arg) => {
db.find({}).exec(function (err, docs) {
ResultData = [];
// sort the data
docs.sort((a, b) => {
if ((!b.block) && (a.block)) {
if (!b.block && a.block) {
return 1;
} else if ((b.block) && (!a.block)) {
} else if (b.block && !a.block) {
return -1;
} else if ((!b.block) && (!a.block)) {
return moment(b.timestamp, "YYYY-MM-DD HH:mm:ss").toDate() - moment(a.timestamp, "YYYY-MM-DD HH:mm:ss").toDate();
} else if (!b.block && !a.block) {
return (moment(b.timestamp, "YYYY-MM-DD HH:mm:ss").toDate() - moment(a.timestamp, "YYYY-MM-DD HH:mm:ss").toDate());
} else {
return b.block - a.block;
}
@@ -60,7 +69,7 @@ ipcMain.on('getTransactions', (event, arg) => {
});
});
ipcMain.on('getJSONFile', (event, arg) => {
ipcMain.on("getJSONFile", (event, arg) => {
storage.get(arg, (err, data) => {
if (err) {
event.returnValue = null;
@@ -70,44 +79,64 @@ ipcMain.on('getJSONFile', (event, arg) => {
});
});
ipcMain.on('setJSONFile', (event, arg) => {
storage.set(arg.file, arg.data, (err) => {
ipcMain.on("setJSONFile", (event, arg) => {
storage.set(arg.file, arg.data, err => {
if (err) {
event.returnValue = { success: false, error: err };
event.returnValue = {
success: false,
error: err
};
} else {
event.returnValue = { success: true, error: null };
event.returnValue = {
success: true,
error: null
};
}
});
});
ipcMain.on('deleteTransactions', (event, arg) => {
fs.unlink(dbPath, (err) => {
ipcMain.on("deleteTransactions", (event, arg) => {
fs.unlink(dbPath, err => {
if (err) {
event.returnValue = { success: false, error: err };
event.returnValue = {
success: false,
error: err
};
} else {
event.returnValue = { success: true, error: null };
event.returnValue = {
success: true,
error: null
};
}
});
});
ipcMain.on('deleteWalletData', (event, arg) => {
fs.unlink(path.join(app.getPath('userData'), 'wallets.json'), (err) => {
ipcMain.on("deleteWalletData", (event, arg) => {
fs.unlink(path.join(app.getPath("userData"), "wallets.json"), err => {
if (err) {
event.returnValue = { success: false, error: err };
event.returnValue = {
success: false,
error: err
};
} else {
event.returnValue = { success: true, error: null };
event.returnValue = {
success: true,
error: null
};
}
});
});
ipcMain.on('deleteBlockchainData', (event, arg) => {
ipcMain.on("deleteBlockchainData", (event, arg) => {
var deleteFolderRecursive = function (path) {
if (fs.existsSync(path)) {
fs.readdirSync(path).forEach(function (file, index) {
var curPath = path + "/" + file;
if(fs.lstatSync(curPath).isDirectory()) { // recurse
if (fs.lstatSync(curPath).isDirectory()) {
// recurse
deleteFolderRecursive(curPath);
} else { // delete file
} else {
// delete file
fs.unlinkSync(curPath);
}
});
@@ -118,10 +147,10 @@ ipcMain.on('deleteBlockchainData', (event, arg) => {
function getBlockchainDataLocation() {
switch (os.type()) {
case "Darwin":
return path.join(os.homedir(), 'Library', 'Ether1', 'geth');
return path.join(os.homedir(), "Library", "Ether1", "geth");
break;
default:
return path.join(process.env.APPDATA, 'Ether1', 'geth');
return path.join(process.env.APPDATA, "Ether1", "geth");
}
}

View File

@@ -1,25 +1,24 @@
const {app, dialog, ipcMain} = require('electron');
const child_process = require('child_process');
const appRoot = require('app-root-path');
const path = require('path');
const fs = require('fs');
const os = require('os');
const {app, dialog, ipcMain} = require("electron");
const child_process = require("child_process");
const appRoot = require("app-root-path");
const path = require("path");
const fs = require("fs");
const os = require("os");
class Geth {
constructor() {
this.gethProcess = null;
this.logGethEvents = false;
// create the user data dir (needed for MacOS)
if (!fs.existsSync(app.getPath('userData'))) {
fs.mkdirSync(app.getPath('userData'));
if (!fs.existsSync(app.getPath("userData"))) {
fs.mkdirSync(app.getPath("userData"));
}
if (this.logGethEvents) {
this.logStream = fs.createWriteStream(path.join(app.getPath('userData'), 'gethlog.txt'), { flags: 'a' });
this.logStream = fs.createWriteStream(path.join(app.getPath("userData"), "gethlog.txt"), {flags: "a"});
}
if (appRoot.path.indexOf('app.asar') > -1) {
if (appRoot.path.indexOf("app.asar") > -1) {
this.rootPath = path.dirname(appRoot.path);
} else {
this.rootPath = appRoot.path;
@@ -27,19 +26,17 @@ class Geth {
switch (os.type()) {
case "Linux":
this.binaries = path.join(this.rootPath, 'bin', 'linux');
this.binaries = path.join(this.rootPath, "bin", "linux");
break;
case "Darwin":
this.binaries = path.join(this.rootPath, 'bin', 'macos');
this.binaries = path.join(this.rootPath, "bin", "macos");
break;
case "Windows_NT":
this.binaries = path.join(this.rootPath, 'bin', 'win');
this.binaries = path.join(this.rootPath, "bin", "win");
break;
default:
this.binaries = path.join(this.rootPath, 'bin', 'win');
this.binaries = path.join(this.rootPath, "bin", "win");
}
}
_writeLog(text) {
@@ -51,22 +48,32 @@ class Geth {
startGeth() {
// get the path of get and execute the child process
try {
const gethPath = path.join(this.binaries, 'geth');
this.gethProcess = child_process.spawn(gethPath, ['--ws', '--wsorigins', '*', '--wsaddr', '127.0.0.1', '--wsport', '8546', '--wsapi', 'admin,db,eth,net,miner,personal,web3']);
const gethPath = path.join(this.binaries, "geth");
this.gethProcess = child_process.spawn(gethPath, [
"--ws",
"--wsorigins",
"*",
"--wsaddr",
"127.0.0.1",
"--wsport",
"8546",
"--wsapi",
"admin,db,eth,net,miner,personal,web3"
]);
if (!this.gethProcess) {
dialog.showErrorBox("Error starting application", "Geth failed to start!");
app.quit();
} else {
this.gethProcess.on('error', function(err) {
this.gethProcess.on("error", function (err) {
dialog.showErrorBox("Error starting application", "Geth failed to start!");
app.quit();
});
this.gethProcess.stderr.on('data', function(data) {
EthoGeth._writeLog(data.toString() + '\n');
this.gethProcess.stderr.on("data", function (data) {
EthoGeth._writeLog(data.toString() + "\n");
});
this.gethProcess.stdout.on('data', function(data) {
EthoGeth._writeLog(data.toString() + '\n');
this.gethProcess.stdout.on("data", function (data) {
EthoGeth._writeLog(data.toString() + "\n");
});
}
} catch (err) {
@@ -77,15 +84,15 @@ class Geth {
stopGeth() {
if (os.type() == "Windows_NT") {
const gethWrapePath = path.join(this.binaries, 'WrapGeth.exe');
const gethWrapePath = path.join(this.binaries, "WrapGeth.exe");
child_process.spawnSync(gethWrapePath, [this.gethProcess.pid]);
} else {
this.gethProcess.kill('SIGTERM');
this.gethProcess.kill("SIGTERM");
}
}
}
ipcMain.on('stopGeth', (event, arg) => {
ipcMain.on("stopGeth", (event, arg) => {
EthoGeth.stopGeth();
});

View File

@@ -1,202 +1,170 @@
const {app, Menu, ipcMain} = require('electron');
const {app, Menu, ipcMain} = require("electron");
const open = require("open");
const template = [
{
label: 'File',
label: "File",
submenu: [
{
label:'Exit',
label: "Exit",
click() {
app.quit()
} }
]
},
{
label: 'Edit',
submenu: [
{
role: 'undo'
},
{
role: 'redo'
},
{
type: 'separator'
},
{
role: 'cut'
},
{
role: 'copy'
},
{
role: 'paste'
},
{
role: 'delete'
},
{
role: 'selectall'
app.quit();
}
}
]
},
{
label: 'View',
}, {
label: "Edit",
submenu: [
{
label: 'Reload',
accelerator: 'CmdOrCtrl+R',
role: "undo"
}, {
role: "redo"
}, {
type: "separator"
}, {
role: "cut"
}, {
role: "copy"
}, {
role: "paste"
}, {
role: "delete"
}, {
role: "selectall"
}
]
}, {
label: "View",
submenu: [
{
label: "Reload",
accelerator: "CmdOrCtrl+R",
click(item, focusedWindow) {
if (focusedWindow) focusedWindow.reload()
if (focusedWindow)
focusedWindow.reload();
}
},
{
label: 'Toggle Developer Tools',
accelerator: process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
}, {
label: "Toggle Developer Tools",
accelerator: process.platform === "darwin"
? "Alt+Command+I"
: "Ctrl+Shift+I",
click(item, focusedWindow) {
if (focusedWindow) focusedWindow.webContents.toggleDevTools()
if (focusedWindow)
focusedWindow.webContents.toggleDevTools();
}
},
{
type: 'separator'
},
{
role: 'resetzoom'
},
{
role: 'zoomin'
},
{
role: 'zoomout'
},
{
type: 'separator'
},
{
role: 'togglefullscreen'
}, {
type: "separator"
}, {
role: "resetzoom"
}, {
role: "zoomin"
}, {
role: "zoomout"
}, {
type: "separator"
}, {
role: "togglefullscreen"
}
]
},
{
role: 'window',
}, {
role: "window",
submenu: [
{
role: 'minimize'
},
{
role: 'close'
role: "minimize"
}, {
role: "close"
}
]
},
{
role: 'help',
}, {
role: "help",
submenu: [
{
label: 'About Ether1 wallet',
label: "About Ether1 wallet",
click() {
var infoData = {};
infoData.version = app.getVersion();
mainWindow.webContents.send('showAboutDialog', infoData);
mainWindow.webContents.send("showAboutDialog", infoData);
}
},
{
label: 'Ether1 documentation',
}, {
label: "Ether1 documentation",
click() {
open("https://docs.ether1.org");
}
},
{
label: 'Report issue on GitHub',
}, {
label: "Report issue on GitHub",
click() {
open("https://github.com/taeguscromis/Ether1DesktopWallet/issues");
}
}
]
}
]
];
if (process.platform === 'darwin') {
const name = app.getName()
if (process.platform === "darwin") {
const name = app.getName();
template.unshift({
label: name,
submenu: [
{
role: 'about'
},
{
type: 'separator'
},
{
role: 'services',
role: "about"
}, {
type: "separator"
}, {
role: "services",
submenu: []
},
{
type: 'separator'
},
{
role: 'hide'
},
{
role: 'hideothers'
},
{
role: 'unhide'
},
{
type: 'separator'
},
{
role: 'quit'
}, {
type: "separator"
}, {
role: "hide"
}, {
role: "hideothers"
}, {
role: "unhide"
}, {
type: "separator"
}, {
role: "quit"
}
]
})
});
// Edit menu.
template[1].submenu.push(
{
type: 'separator'
},
{
label: 'Speech',
template[1].submenu.push({
type: "separator"
}, {
label: "Speech",
submenu: [
{
role: 'startspeaking'
},
{
role: 'stopspeaking'
role: "startspeaking"
}, {
role: "stopspeaking"
}
]
}
)
});
// Window menu.
template[3].submenu = [
{
label: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close'
},
{
label: 'Minimize',
accelerator: 'CmdOrCtrl+M',
role: 'minimize'
},
{
label: 'Zoom',
role: 'zoom'
},
{
type: 'separator'
},
{
label: 'Bring All to Front',
role: 'front'
label: "Close",
accelerator: "CmdOrCtrl+W",
role: "close"
}, {
label: "Minimize",
accelerator: "CmdOrCtrl+M",
role: "minimize"
}, {
label: "Zoom",
role: "zoom"
}, {
type: "separator"
}, {
label: "Bring All to Front",
role: "front"
}
]
];
}
ipcMain.on('openURL', (event, arg) => {
ipcMain.on("openURL", (event, arg) => {
open(arg);
});
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);

View File

@@ -1,6 +1,6 @@
{
"name": "Ether1Wallet",
"version": "0.2.6",
"version": "0.2.7",
"description": "Desktop wallet for Ether1 currency",
"main": "main.js",
"scripts": {
@@ -22,41 +22,34 @@
"target": "7z",
"icon": "build/icon.png",
"artifactName": "Windows-${productName}-${version}.${ext}",
"extraResources": [
"bin/win/*"
]
"extraResources": ["bin/win/*"]
},
"linux": {
"target": "tar.gz",
"icon": "build/icon.icns",
"artifactName": "Linux-${productName}-${version}.${ext}",
"extraResources": [
"bin/linux/*"
]
"extraResources": ["bin/linux/*"]
},
"mac": {
"target": "pkg",
"icon": "build/icon.icns",
"artifactName": "MacOS-${productName}-${version}.${ext}",
"extraResources": [
"bin/macos/*"
]
"extraResources": ["bin/macos/*"]
}
},
"repository": "https://github.com/taeguscromis/Ether1DesktopWallet",
"keywords": [
"Ether1",
"Desktop",
"Wallet"
"Ether1", "Desktop", "Wallet"
],
"author": "Ether1",
"license": "CC0-1.0",
"dependencies": {
"@unibeautify/beautifier-js-beautify": "^0.4.0",
"adm-zip": "^0.4.13",
"app-root-path": "^2.1.0",
"electron-storage": "^1.0.7",
"fs-extra": "^7.0.1",
"handlebars": "^4.0.12",
"handlebars": "^4.1.0",
"moment": "^2.23.0",
"nedb": "^1.8.0",
"open": "0.0.5",
@@ -64,6 +57,9 @@
},
"devDependencies": {
"electron": "^3.0.12",
"electron-builder": "^20.38.3"
"electron-builder": "^20.38.3",
"js-beautify": "^1.9.0",
"unibeautify": "^0.17.0",
"unibeautify-cli": "^0.2.1"
}
}

View File

@@ -1,5 +1,5 @@
// In renderer process (web page).
const {ipcRenderer} = require('electron');
const {ipcRenderer} = require("electron");
class Blockchain {
constructor() {
@@ -76,9 +76,8 @@ class Blockchain {
web3Local.eth.personal.unlockAccount(fromAddress, password, function (error, result) {
if (error) {
clbError("Wrong password for the selected address!");
} else
{
web3Local.eth.getTransactionCount(fromAddress, 'pending', function( error, result ) {
} else {
web3Local.eth.getTransactionCount(fromAddress, "pending", function (error, result) {
if (error) {
clbError(error);
} else {
@@ -160,11 +159,10 @@ class Blockchain {
}
});
function updateBalance(index)
{
function updateBalance(index) {
web3Local.eth.getBalance(rendererData.addressData[index].address, function (error, balance) {
rendererData.addressData[index].balance = parseFloat(web3Local.utils.fromWei(balance, 'ether')).toFixed(2);
rendererData.sumBalance = rendererData.sumBalance + parseFloat(web3Local.utils.fromWei(balance, 'ether'));
rendererData.addressData[index].balance = parseFloat(web3Local.utils.fromWei(balance, "ether")).toFixed(2);
rendererData.sumBalance = rendererData.sumBalance + parseFloat(web3Local.utils.fromWei(balance, "ether"));
if (counter < rendererData.addressData.length - 1) {
counter++;
@@ -218,11 +216,11 @@ class Blockchain {
importFromPrivateKey(privateKey, password) {
web3Local.eth.accounts.wallet.clear();
web3Local.eth.accounts.wallet.add(privateKey);
return web3Local.eth.accounts.wallet.encrypt('123456789');
return web3Local.eth.accounts.wallet.encrypt("123456789");
}
subsribePendingTransactions(clbError, clbSuccess, clbData) {
this.txSubscribe = web3Local.eth.subscribe('pendingTransactions', function(error, result){
this.txSubscribe = web3Local.eth.subscribe("pendingTransactions", function (error, result) {
if (error) {
clbError(error);
} else {
@@ -248,7 +246,7 @@ class Blockchain {
}
subsribeNewBlockHeaders(clbError, clbSuccess, clbData) {
this.bhSubscribe = web3Local.eth.subscribe('newBlockHeaders', function(error, result){
this.bhSubscribe = web3Local.eth.subscribe("newBlockHeaders", function (error, result) {
if (error) {
clbError(error);
} else {

View File

@@ -1,11 +1,11 @@
// In renderer process (web page).
const {ipcRenderer} = require('electron');
const {ipcRenderer} = require("electron");
class Datatabse {
constructor() {}
getCounters() {
var counters = ipcRenderer.sendSync('getJSONFile', 'counters.json');
var counters = ipcRenderer.sendSync("getJSONFile", "counters.json");
if (counters == null) {
counters = {};
@@ -15,45 +15,46 @@ class Datatabse {
}
setCounters(counters) {
ipcRenderer.sendSync('setJSONFile',
{
file: 'counters.json',
ipcRenderer.sendSync("setJSONFile", {
file: "counters.json",
data: counters
});
}
getWallets() {
var wallets = ipcRenderer.sendSync('getJSONFile', 'wallets.json');
var wallets = ipcRenderer.sendSync("getJSONFile", "wallets.json");
if (!wallets) {
wallets = { names: {} };
wallets = {
names: {}
};
}
return wallets;
}
setWallets(wallets) {
ipcRenderer.sendSync('setJSONFile',
{
file: 'wallets.json',
ipcRenderer.sendSync("setJSONFile", {
file: "wallets.json",
data: wallets
});
}
getAddresses() {
var addressBook = ipcRenderer.sendSync('getJSONFile', 'addresses.json');
var addressBook = ipcRenderer.sendSync("getJSONFile", "addresses.json");
if (!addressBook) {
addressBook = { names: {} };
addressBook = {
names: {}
};
}
return addressBook;
}
setAddresses(addresses) {
ipcRenderer.sendSync('setJSONFile',
{
file: 'addresses.json',
ipcRenderer.sendSync("setJSONFile", {
file: "addresses.json",
data: addresses
});
}

View File

@@ -1,5 +1,5 @@
// In renderer process (web page).
const {ipcRenderer} = require('electron');
const {ipcRenderer} = require("electron");
class MainGUI {
constructor() {
@@ -42,10 +42,10 @@ class MainGUI {
// create and open the dialog
$("#dlgGeneralError").iziModal();
$('#dlgGeneralError').iziModal('open');
$("#dlgGeneralError").iziModal("open");
$("#btnGeneralErrorOK").click(function () {
$('#dlgGeneralError').iziModal('close');
$("#dlgGeneralError").iziModal("close");
});
}
@@ -54,15 +54,15 @@ class MainGUI {
// create and open the dialog
$("#dlgGeneralConfirm").iziModal();
$('#dlgGeneralConfirm').iziModal('open');
$("#dlgGeneralConfirm").iziModal("open");
$("#btnGeneralConfirmYes").click(function () {
$('#dlgGeneralConfirm').iziModal('close');
$("#dlgGeneralConfirm").iziModal("close");
callback(true);
});
$("#btnGeneralConfirmNo").click(function () {
$('#dlgGeneralConfirm').iziModal('close');
$("#dlgGeneralConfirm").iziModal("close");
callback(false);
});
}
@@ -72,23 +72,23 @@ class MainGUI {
// create and open the dialog
$("#dlgAboutInfo").iziModal();
$('#dlgAboutInfo').iziModal('open');
$("#dlgAboutInfo").iziModal("open");
$("#urlOpenLicence, #urlOpenGitHub").off("click").on("click", function (even) {
event.preventDefault();
ipcRenderer.send('openURL', $(this).attr("href"));
ipcRenderer.send("openURL", $(this).attr("href"));
});
$("#btnAboutInfoClose").off("click").on("click", function (even) {
$('#dlgAboutInfo').iziModal('close');
$("#dlgAboutInfo").iziModal("close");
});
}
renderTemplate(template, data, container) {
var template = Handlebars.compile(ipcRenderer.sendSync('getTemplateContent', template));
var template = Handlebars.compile(ipcRenderer.sendSync("getTemplateContent", template));
if (!container) {
container = $("#mainContent")
container = $("#mainContent");
}
container.empty();
@@ -104,7 +104,7 @@ class MainGUI {
}
}
ipcRenderer.on('showAboutDialog', function(event, message) {
ipcRenderer.on("showAboutDialog", function (event, message) {
EthoMainGUI.showAboutDialog(message);
});

View File

@@ -1,4 +1,4 @@
const {ipcRenderer} = require('electron');
const {ipcRenderer} = require("electron");
class Markets {
constructor() {}
@@ -18,18 +18,20 @@ class Markets {
$("#changeMarketcap").html("high 24h: " + data.market_data.high_24h.usd.toFixed(5) + " $");
$("#changeVolume").html("all time high: " + data.market_data.ath.usd.toFixed(5) + " $");
new Chart(document.getElementById('chartMarketPriceCanvas'), {
type: 'line',
new Chart(document.getElementById("chartMarketPriceCanvas"), {
type: "line",
data: {
labels: data.market_data.sparkline_7d.price,
datasets: [{
datasets: [
{
data: data.market_data.sparkline_7d.price,
backgroundColor: 'rgb(122,19,54,0.1)',
backgroundColor: "rgb(122,19,54,0.1)",
fill: true,
borderWidth: 3,
pointRadius: 0,
borderColor: '#7A1336'
}]
borderColor: "#7A1336"
}
]
},
options: {
animation: false,
@@ -42,22 +44,26 @@ class Markets {
}
},
scales: {
yAxes: [{
yAxes: [
{
ticks: {
maxTicksLimit: 5,
beginAtZero: true,
fontSize: 10,
callback: function (value, index, values) {
return value.toFixed(2) + ' $';
return value.toFixed(2) + " $";
}
},
gridLines: {
color: 'rgba(255,255,255,.08)'
color: "rgba(255,255,255,.08)"
}
}],
xAxes: [{
}
],
xAxes: [
{
display: false
}]
}
]
}
}
});

View File

@@ -1,20 +1,16 @@
// In renderer process (web page).
const {ipcRenderer} = require('electron');
const {ipcRenderer} = require("electron");
class SendTransaction {
constructor() {}
renderSendState() {
EthoBlockchain.getAccountsData(
function(error) {
EthoBlockchain.getAccountsData(function (error) {
EthoMainGUI.showGeneralError(error);
},
function(data) {
}, function (data) {
EthoMainGUI.renderTemplate("send.html", data);
$(document).trigger("render_send");
}
);
});
}
validateSendForm() {
@@ -60,26 +56,26 @@ class SendTransaction {
}
$(document).on("render_send", function () {
$('select').formSelect( {classes: "fromAddressSelect"});
$("select").formSelect({classes: "fromAddressSelect"});
$("#sendFromAddress").on("change", function () {
var optionText = $(this).find("option:selected").text();
var addrName = optionText.substr(0, optionText.indexOf('-'));
var addrName = optionText.substr(0, optionText.indexOf("-"));
var addrValue = optionText.substr(optionText.indexOf("-") + 1);
$(".fromAddressSelect input").val(addrValue.trim());
$("#sendFromAddressName").html(addrName.trim());
web3Local.eth.getBalance(this.value, function (error, balance) {
$("#sendMaxAmmount").html(parseFloat(web3Local.utils.fromWei(balance, 'ether')));
$("#sendMaxAmmount").html(parseFloat(web3Local.utils.fromWei(balance, "ether")));
});
});
$("#btnSendAll").off('click').on('click', function() {
$("#btnSendAll").off("click").on("click", function () {
$("#sendAmmount").focus();
$("#sendAmmount").val($("#sendMaxAmmount").html());
});
$("#sendToAddress").off('input').on('input', function() {
$("#sendToAddress").off("input").on("input", function () {
var addressName = null;
$("#sendToAddressName").html("");
addressName = EthoAddressBook.getAddressName($("#sendToAddress").val());
@@ -91,18 +87,16 @@ $(document).on("render_send", function() {
$("#sendToAddressName").html(addressName);
});
$("#btnLookForToAddress").off('click').on('click', function() {
EthoBlockchain.getAddressListData(
function(error) {
$("#btnLookForToAddress").off("click").on("click", function () {
EthoBlockchain.getAddressListData(function (error) {
EthoMainGUI.showGeneralError(error);
},
function(addressList) {
}, function (addressList) {
var addressBook = EthoAddressBook.getAddressList();
for (var key in addressBook) {
if (addressBook.hasOwnProperty(key)) {
var adddressObject = {};
adddressObject.address = key
adddressObject.address = key;
adddressObject.name = addressBook[key];
addressList.addressData.push(adddressObject);
}
@@ -110,132 +104,104 @@ $(document).on("render_send", function() {
$("#dlgAddressList").iziModal({width: "800px"});
EthoMainGUI.renderTemplate("addresslist.html", addressList, $("#dlgAddressListBody"));
$('#dlgAddressList').iziModal('open');
$("#dlgAddressList").iziModal("open");
$(".btnSelectToAddress").off('click').on('click', function() {
$("#sendToAddressName").html($(this).attr('data-name'));
$("#sendToAddress").val($(this).attr('data-wallet'));
$('#dlgAddressList').iziModal('close');
$(".btnSelectToAddress").off("click").on("click", function () {
$("#sendToAddressName").html($(this).attr("data-name"));
$("#sendToAddress").val($(this).attr("data-wallet"));
$("#dlgAddressList").iziModal("close");
});
$('#addressListFilter').off('input').on('input',function(e){
EthoUtils.filterTable($("#addressTable"), $('#addressListFilter').val());
$("#addressListFilter").off("input").on("input", function (e) {
EthoUtils.filterTable($("#addressTable"), $("#addressListFilter").val());
});
$("#btnClearSearchField").off('click').on('click', function() {
$("#btnClearSearchField").off("click").on("click", function () {
EthoUtils.filterTable($("#addressTable"), "");
$('#addressListFilter').val("")
$("#addressListFilter").val("");
});
});
}
);
});
$("#btnAddToAddressBook").off('click').on('click', function() {
$("#btnAddToAddressBook").off("click").on("click", function () {
if (EthoBlockchain.isAddress($("#sendToAddress").val())) {
$("#dlgAddAddressToBook").iziModal();
$("#inputAddressName").val("");
$('#dlgAddAddressToBook').iziModal('open');
$("#dlgAddAddressToBook").iziModal("open");
function doAddAddressToAddressBook() {
EthoAddressBook.setAddressName($("#sendToAddress").val(), $("#inputAddressName").val());
$('#dlgAddAddressToBook').iziModal('close');
$("#dlgAddAddressToBook").iziModal("close");
iziToast.success({
title: 'Success',
message: 'Address was added to address book',
position: 'topRight',
timeout: 2000
});
iziToast.success({title: "Success", message: "Address was added to address book", position: "topRight", timeout: 2000});
}
} else {
EthoMainGUI.showGeneralError("Recipient address is not valid!");
}
$("#btnAddAddressToBookConfirm").off('click').on('click', function() {
$("#btnAddAddressToBookConfirm").off("click").on("click", function () {
doAddAddressToAddressBook();
});
$("#dlgAddAddressToBook").off('keypress').on('keypress', function(e) {
$("#dlgAddAddressToBook").off("keypress").on("keypress", function (e) {
if (e.which == 13) {
doAddAddressToAddressBook();
}
});
});
$("#btnSendTransaction").off('click').on('click', function() {
$("#btnSendTransaction").off("click").on("click", function () {
if (EthoSend.validateSendForm()) {
EthoBlockchain.getTranasctionFee($("#sendFromAddress").val(), $("#sendToAddress").val(), $("#sendAmmount").val(),
function(error) {
EthoBlockchain.getTranasctionFee($("#sendFromAddress").val(), $("#sendToAddress").val(), $("#sendAmmount").val(), function (error) {
EthoMainGUI.showGeneralError(error);
},
function(data) {
}, function (data) {
$("#dlgSendWalletPassword").iziModal();
$("#walletPassword").val("");
$("#fromAddressInfo").html($("#sendFromAddress").val());
$("#toAddressInfo").html($("#sendToAddress").val());
$("#valueToSendInfo").html($("#sendAmmount").val());
$("#feeToPayInfo").html(parseFloat(web3Local.utils.fromWei(data.toString(), 'ether')));
$('#dlgSendWalletPassword').iziModal('open');
$("#feeToPayInfo").html(parseFloat(web3Local.utils.fromWei(data.toString(), "ether")));
$("#dlgSendWalletPassword").iziModal("open");
function doSendTransaction() {
$('#dlgSendWalletPassword').iziModal('close');
$("#dlgSendWalletPassword").iziModal("close");
EthoBlockchain.prepareTransaction(
$("#walletPassword").val(),
$("#sendFromAddress").val(),
$("#sendToAddress").val(),
$("#sendAmmount").val(),
function(error) {
EthoBlockchain.prepareTransaction($("#walletPassword").val(), $("#sendFromAddress").val(), $("#sendToAddress").val(), $("#sendAmmount").val(), function (error) {
EthoMainGUI.showGeneralError(error);
},
function(data) {
EthoBlockchain.sendTransaction(data.raw,
function(error) {
}, function (data) {
EthoBlockchain.sendTransaction(data.raw, function (error) {
EthoMainGUI.showGeneralError(error);
},
function(data) {
}, function (data) {
EthoSend.resetSendForm();
iziToast.success({
title: 'Sent',
message: 'Transaction was successfully sent to the chain',
position: 'topRight',
timeout: 5000
});
iziToast.success({title: "Sent", message: "Transaction was successfully sent to the chain", position: "topRight", timeout: 5000});
EthoBlockchain.getTransaction(data,
function(error) {
EthoBlockchain.getTransaction(data, function (error) {
EthoMainGUI.showGeneralError(error);
},
function(transaction) {
ipcRenderer.send('storeTransaction', {
}, function (transaction) {
ipcRenderer.send("storeTransaction", {
block: transaction.blockNumber,
txhash: transaction.hash.toLowerCase(),
fromaddr: transaction.from.toLowerCase(),
timestamp: moment().format('YYYY-MM-DD HH:mm:ss'),
timestamp: moment().format("YYYY-MM-DD HH:mm:ss"),
toaddr: transaction.to.toLowerCase(),
value: transaction.value
});
}
);
}
);
}
);
});
});
});
}
$("#btnSendWalletPasswordConfirm").off('click').on('click', function() {
$("#btnSendWalletPasswordConfirm").off("click").on("click", function () {
doSendTransaction();
});
$("#dlgSendWalletPassword").off('keypress').on('keypress', function(e) {
$("#dlgSendWalletPassword").off("keypress").on("keypress", function (e) {
if (e.which == 13) {
doSendTransaction();
}
});
}
);
});
}
});
});

View File

@@ -1,5 +1,5 @@
// In renderer process (web page).
const {ipcRenderer} = require('electron');
const {ipcRenderer} = require("electron");
class Settings {
constructor() {}
@@ -11,7 +11,7 @@ class Settings {
}
$(document).on("render_settings", function () {
$("#btnSettingsCleanTransactions").off('click').on('click', function() {
$("#btnSettingsCleanTransactions").off("click").on("click", function () {
if (isFullySynced) {
EthoMainGUI.showGeneralConfirmation("Do you really want to resync transactions?", function (result) {
if (result) {
@@ -24,7 +24,7 @@ $(document).on("render_settings", function() {
var counters = EthoDatatabse.getCounters();
counters.transactions = 0;
EthoDatatabse.setCounters(counters);
ipcResult = ipcRenderer.sendSync('deleteTransactions', null);
ipcResult = ipcRenderer.sendSync("deleteTransactions", null);
if (ipcResult.success) {
// sync all the transactions to the current block
@@ -35,12 +35,7 @@ $(document).on("render_settings", function() {
EthoTransactions.enableKeepInSync();
EthoTransactions.syncTransactionsForAllAddresses(localBlock.number);
iziToast.success({
title: 'Success',
message: 'Transactions are being resynced',
position: 'topRight',
timeout: 5000
});
iziToast.success({title: "Success", message: "Transactions are being resynced", position: "topRight", timeout: 5000});
}
});
} else {
@@ -50,27 +45,17 @@ $(document).on("render_settings", function() {
}
});
} else {
iziToast.info({
title: 'Wait...',
message: 'You need to be fully sync before cleaning transactions',
position: 'topRight',
timeout: 5000
});
iziToast.info({title: "Wait...", message: "You need to be fully sync before cleaning transactions", position: "topRight", timeout: 5000});
}
});
$("#btnSettingsCleanWallets").off('click').on('click', function() {
$("#btnSettingsCleanWallets").off("click").on("click", function () {
EthoMainGUI.showGeneralConfirmation("Do you really want to delete wallets data?", function (result) {
if (result) {
ipcResult = ipcRenderer.sendSync('deleteWalletData', null);
ipcResult = ipcRenderer.sendSync("deleteWalletData", null);
if (ipcResult.success) {
iziToast.success({
title: 'Success',
message: 'Wallet names were succesfully cleaned',
position: 'topRight',
timeout: 5000
});
iziToast.success({title: "Success", message: "Wallet names were succesfully cleaned", position: "topRight", timeout: 5000});
} else {
EthoMainGUI.showGeneralError("Error clearing wallet names: " + ipcResult.error);
}
@@ -78,24 +63,20 @@ $(document).on("render_settings", function() {
});
});
$("#btnSettingsCleanBlockchain").off('click').on('click', function() {
$("#btnSettingsCleanBlockchain").off("click").on("click", function () {
EthoMainGUI.showGeneralConfirmation("Do you really want to delete the blockchain data? Wallet will close and you will need to restart it!", function (result) {
if (result) {
var loading_screen = pleaseWait({
logo: "assets/images/logo.png",
backgroundColor: '#000000',
loadingHtml: "<div class='spinner'><div class='bounce bounce1'></div><div class='bounce bounce2'></div><div class='bounce bounce3'></div></div><div class='loadingText'>Deleting blockchain data, wallet will automatically close, please wait...</div>"
});
var loading_screen = pleaseWait({logo: "assets/images/logo.png", backgroundColor: "#000000", loadingHtml: "<div class='spinner'><div class='bounce bounce1'></div><div class='bounce bounce2'></div><div class='bounce bounce3'></div></div><div class='loadingText'>Deleting blockchain data, wallet will automatically close, please wait...</div>"});
setTimeout(() => {
// first stop the geth process
ipcResult = ipcRenderer.send('stopGeth', null);
ipcResult = ipcRenderer.send("stopGeth", null);
setTimeout(() => {
// delete the blockchain date async and wait for 5 seconds
ipcResult = ipcRenderer.sendSync('deleteBlockchainData', null);
ipcResult = ipcRenderer.sendSync("deleteBlockchainData", null);
// finally quit the application
ipcResult = ipcRenderer.send('appQuit', null);
ipcResult = ipcRenderer.send("appQuit", null);
}, 5000);
}, 2000);
}

View File

@@ -1,18 +1,17 @@
// In renderer process (web page).
const {ipcRenderer} = require('electron');
const {ipcRenderer} = require("electron");
// Set the provider you want from Web3.providers
SyncProgress = new ProgressBar.Line('#syncProgress',
{
SyncProgress = new ProgressBar.Line("#syncProgress", {
strokeWidth: 6,
easing: 'easeInOut',
easing: "easeInOut",
duration: 1400,
color: "#7A1336",
trailColor: '#eee',
trailColor: "#eee",
trailWidth: 1,
text: {
style: {
color: '#bbb',
color: "#bbb",
position: "absolute",
left: "50%",
top: "-1px",
@@ -23,16 +22,19 @@ SyncProgress = new ProgressBar.Line('#syncProgress',
},
autoStyleContainer: false
},
from: {color: '#FFEA82'},
to: {color: '#ED6A5A'}
from: {
color: "#FFEA82"
},
to: {
color: "#ED6A5A"
}
});
// set initial value for the progress text
SyncProgress.setText("Waiting for blockchain, please wait...");
isFullySynced = false;
var peerCountInterval = setInterval(function()
{
var peerCountInterval = setInterval(function () {
web3Local.eth.net.getPeerCount(function (error, count) {
$("#peerCount").html(vsprintf("Peer Count: %d", [count]));
});
@@ -42,25 +44,23 @@ function StartSyncProcess() {
var alreadyCatchedUp = false;
var nodeSyncInterval = null;
var subscription = web3Local.eth.subscribe('syncing', function(error, sync){
var subscription = web3Local.eth.subscribe("syncing", function (error, sync) {
if (!error) {
if (!sync) {
if (nodeSyncInterval) {
clearInterval(nodeSyncInterval);
}
nodeSyncInterval = setInterval(function()
{
nodeSyncInterval = setInterval(function () {
web3Local.eth.getBlock("latest", function (error, localBlock) {
if (!error) {
if (localBlock.number > 0) {
if (!EthoTransactions.getIsSyncing()) {
SyncProgress.animate(1);
SyncProgress.setText(vsprintf('%d/%d (100%%)', [localBlock.number, localBlock.number]));
SyncProgress.setText(vsprintf("%d/%d (100%%)", [localBlock.number, localBlock.number]));
}
if (alreadyCatchedUp == false)
{
if (alreadyCatchedUp == false) {
// clear the repeat interval and render wallets
$(document).trigger("onNewAccountTransaction");
alreadyCatchedUp = true;
@@ -85,18 +85,25 @@ function StartSyncProcess() {
EthoMainGUI.showGeneralError(error);
}
}).on("data", function (sync) {
if ((sync) && (sync.HighestBlock > 0)) {
if (sync && sync.HighestBlock > 0) {
SyncProgress.animate(sync.CurrentBlock / sync.HighestBlock);
SyncProgress.setText(vsprintf('%d/%d (%d%%)', [sync.CurrentBlock, sync.HighestBlock, Math.floor(sync.CurrentBlock / sync.HighestBlock * 100)]));
SyncProgress.setText(vsprintf("%d/%d (%d%%)", [
sync.CurrentBlock,
sync.HighestBlock,
Math.floor(sync.CurrentBlock / sync.HighestBlock * 100)
]));
}
}).on("changed", function (isSyncing) {
if (isSyncing) {
nodeSyncInterval = setInterval(function()
{
nodeSyncInterval = setInterval(function () {
web3Local.eth.isSyncing(function (error, sync) {
if ((!error) && (sync)) {
if (!error && sync) {
SyncProgress.animate(sync.currentBlock / sync.highestBlock);
SyncProgress.setText(vsprintf('%d/%d (%d%%)', [sync.currentBlock, sync.highestBlock, Math.floor(sync.currentBlock / sync.highestBlock * 100)]));
SyncProgress.setText(vsprintf("%d/%d (%d%%)", [
sync.currentBlock,
sync.highestBlock,
Math.floor(sync.currentBlock / sync.highestBlock * 100)
]));
} else if (error) {
EthoMainGUI.showGeneralError(error);
}
@@ -110,10 +117,9 @@ function StartSyncProcess() {
});
}
var InitWeb3 = setInterval(function()
{
var InitWeb3 = setInterval(function () {
try {
web3Local = new Web3(new Web3.providers.WebsocketProvider('ws://localhost:8546'));
web3Local = new Web3(new Web3.providers.WebsocketProvider("ws://localhost:8546"));
web3Local.eth.net.isListening(function (error, success) {
if (!error) {
@@ -122,8 +128,7 @@ var InitWeb3 = setInterval(function()
StartSyncProcess();
}
});
}
catch(err) {
} catch (err) {
EthoMainGUI.showGeneralError(err);
}
}, 2000);

View File

@@ -5,24 +5,29 @@ class tableTransactions {
initialize(id, data) {
// register the sort datetime format
$.fn.dataTable.moment('MMM Do YYYY HH:mm:ss');
$.fn.dataTable.moment("MMM Do YYYY HH:mm:ss");
var namesType = $.fn.dataTable.absoluteOrderNumber(
[
{ value: null, position: 'top' }
var namesType = $.fn.dataTable.absoluteOrderNumber([
{
value: null,
position: "top"
}
]);
// render the transactions
$(id).DataTable({
"dom": 'Bfrtip',
"paging": false,
"scrollY": "calc(100vh - 115px)",
"responsive": true,
"processing": true,
"order": [[ 1, "desc" ]],
"data": data,
"oSearch": {"sSearch": EthoTransactions.getFilter() },
"buttons":
[
dom: "Bfrtip",
paging: false,
scrollY: "calc(100vh - 115px)",
responsive: true,
processing: true,
order: [
[1, "desc"]
],
data: data,
oSearch: {
sSearch: EthoTransactions.getFilter()
},
buttons: [
{
text: '<i class="fas fa-sync-alt"></i>',
action: function (e, dt, node, config) {
@@ -30,10 +35,10 @@ class tableTransactions {
}
}
],
"columnDefs": [
columnDefs: [
{
"targets": 0,
"render": function ( data, type, row ) {
targets: 0,
render: function (data, type, row) {
if (data == 0) {
return '<i class="fas fa-arrow-left"></i>';
} else if (data == 1) {
@@ -42,28 +47,24 @@ class tableTransactions {
return '<i class="fas fa-arrows-alt-h"></i>';
}
}
},
{
"className": "transactionsBlockNum",
"type": namesType,
"targets": 1
},
{
"targets": 2,
"render": function ( data, type, row ) {
}, {
className: "transactionsBlockNum",
type: namesType,
targets: 1
}, {
targets: 2,
render: function (data, type, row) {
return moment(data, "YYYY-MM-DD HH:mm:ss").format("MMM Do YYYY HH:mm:ss");
}
},
{
"targets": 5,
"render": function ( data, type, row ) {
return parseFloat(web3Local.utils.fromWei(EthoUtils.toFixed(parseFloat(data)).toString(), 'ether')).toFixed(2);
}, {
targets: 5,
render: function (data, type, row) {
return parseFloat(web3Local.utils.fromWei(EthoUtils.toFixed(parseFloat(data)).toString(), "ether")).toFixed(2);
}
},
{
"targets": 6,
"defaultContent": "",
"render": function ( data, type, row ) {
}, {
targets: 6,
defaultContent: "",
render: function (data, type, row) {
if (row[1]) {
return '<i class="fas fa-check"></i>';
} else {
@@ -72,7 +73,7 @@ class tableTransactions {
}
}
],
"drawCallback": function( settings ) {
drawCallback: function (settings) {
$("#loadingTransactionsOverlay").css("display", "none");
}
});

View File

@@ -1,4 +1,4 @@
const {ipcRenderer} = require('electron');
const {ipcRenderer} = require("electron");
class Transactions {
constructor() {
@@ -40,12 +40,16 @@ class Transactions {
SyncProgress.setText(vsprintf("Syncing address transactions %d/%d, please wait...", [counter, addressList.length]));
var startBlock = parseInt(counters.transactions) || 0;
var params = vsprintf('?address=%s&fromBlock=%d&toBlock=%d', [addressList[counter].toLowerCase(), startBlock, lastBlock]);
var params = vsprintf("?address=%s&fromBlock=%d&toBlock=%d", [
addressList[counter].toLowerCase(),
startBlock,
lastBlock
]);
$.getJSON("https://richlist.ether1.org/transactions_list.php" + params, function (result) {
result.data.forEach(element => {
if (element.fromaddr && element.toaddr) {
ipcRenderer.send('storeTransaction', {
ipcRenderer.send("storeTransaction", {
block: element.block.toString(),
txhash: element.txhash.toLowerCase(),
fromaddr: element.fromaddr.toLowerCase(),
@@ -73,15 +77,12 @@ class Transactions {
var counters = EthoDatatabse.getCounters();
var counter = 0;
EthoBlockchain.getAccounts(
function(error) {
EthoBlockchain.getAccounts(function (error) {
EthoMainGUI.showGeneralError(error);
},
function(data) {
}, function (data) {
EthoTransactions.setIsSyncing(true);
EthoTransactions.syncTransactionsForSingleAddress(data, counters, lastBlock, counter);
}
);
});
}
renderTransactions() {
@@ -94,61 +95,56 @@ class Transactions {
$("#loadingTransactionsOverlay").css("display", "block");
setTimeout(() => {
var dataTransactions = ipcRenderer.sendSync('getTransactions');
var dataTransactions = ipcRenderer.sendSync("getTransactions");
var addressList = EthoWallets.getAddressList();
dataTransactions.forEach(function (element) {
var isFromValid = (addressList.indexOf(element[2].toLowerCase()) > -1);
var isToValid = (addressList.indexOf(element[3].toLowerCase()) > -1);
var isFromValid = addressList.indexOf(element[2].toLowerCase()) > -1;
var isToValid = addressList.indexOf(element[3].toLowerCase()) > -1;
if ((isToValid) && (!isFromValid)) {
if (isToValid && !isFromValid) {
element.unshift(0);
} else if ((!isToValid) && (isFromValid)) {
} else if (!isToValid && isFromValid) {
element.unshift(1);
} else {
element.unshift(2);
}
});
EthoTableTransactions.initialize('#tableTransactionsForAll', dataTransactions);
EthoTableTransactions.initialize("#tableTransactionsForAll", dataTransactions);
EthoTransactions.setIsLoading(false);
}, 200);
}
}
enableKeepInSync() {
EthoBlockchain.subsribeNewBlockHeaders(
function(error) {
EthoBlockchain.subsribeNewBlockHeaders(function (error) {
EthoMainGUI.showGeneralError(error);
},
function(data)
{
EthoBlockchain.getBlock(data.number, true,
function(error) {
}, function (data) {
EthoBlockchain.getBlock(data.number, true, function (error) {
EthoMainGUI.showGeneralError(error);
},
function(data) {
}, function (data) {
if (data.transactions) {
data.transactions.forEach(element => {
if (element.from && element.to) {
if ((EthoWallets.getAddressExists(element.from)) || (EthoWallets.getAddressExists(element.to))) {
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.unix(data.timestamp).format('YYYY-MM-DD HH:mm:ss'),
timestamp: moment.unix(data.timestamp).format("YYYY-MM-DD HH:mm:ss"),
toaddr: element.to.toLowerCase(),
value: Number(element.value).toExponential(5).toString().replace('+','')
}
value: Number(element.value).toExponential(5).toString().replace("+", "")
};
// store transaction and notify about new transactions
ipcRenderer.send('storeTransaction', Transaction);
ipcRenderer.send("storeTransaction", Transaction);
$(document).trigger("onNewAccountTransaction");
iziToast.info({
title: 'New Transaction',
message: vsprintf('Transaction from address %s to address %s was just processed', [Transaction.fromaddr, Transaction.toaddr]),
position: 'topRight',
title: "New Transaction",
message: vsprintf("Transaction from address %s to address %s was just processed", [Transaction.fromaddr, Transaction.toaddr]),
position: "topRight",
timeout: 10000
});
@@ -161,21 +157,16 @@ class Transactions {
}
});
}
}
);
}
);
});
});
}
disableKeepInSync() {
EthoBlockchain.unsubsribeNewBlockHeaders(
function(error) {
EthoBlockchain.unsubsribeNewBlockHeaders(function (error) {
EthoMainGUI.showGeneralError(error);
},
function(data) {
}, function (data) {
// success
}
);
});
}
}

View File

@@ -3,17 +3,17 @@ class Utils {
toFixed(x) {
if (Math.abs(x) < 1.0) {
var e = parseInt(x.toString().split('e-')[1]);
var e = parseInt(x.toString().split("e-")[1]);
if (e) {
x *= Math.pow(10, e - 1);
x = '0.' + (new Array(e)).join('0') + x.toString().substring(2);
x = "0." + new Array(e).join("0") + x.toString().substring(2);
}
} else {
var e = parseInt(x.toString().split('+')[1]);
var e = parseInt(x.toString().split("+")[1]);
if (e > 20) {
e -= 20;
x /= Math.pow(10, e);
x += (new Array(e+1)).join('0');
x += new Array(e + 1).join("0");
}
}
return x;
@@ -21,7 +21,11 @@ class Utils {
filterTable(table, text) {
// Declare variables
var filter, tr, td, i, txtValue;
var filter,
tr,
td,
i,
txtValue;
filter = text.toUpperCase();
tr = $(table).find("tr");
@@ -45,13 +49,12 @@ class Utils {
content: text,
delay: 500,
arrow: true,
arrowType: 'round',
size: 'large',
arrowType: "round",
size: "large",
duration: 500,
animation: 'scale'
animation: "scale"
});
}
}
EthoUtils = new Utils();

View File

@@ -1,11 +1,10 @@
const {ipcRenderer} = require('electron');
const {ipcRenderer} = require("electron");
class Wallets {
constructor() {
this.addressList = [];
$.getJSON("https://min-api.cryptocompare.com/data/price?fsym=ETHO&tsyms=USD", function( price )
{
$.getJSON("https://min-api.cryptocompare.com/data/price?fsym=ETHO&tsyms=USD", function (price) {
EthoWallets._setPrice(price.USD);
});
}
@@ -75,11 +74,9 @@ renderWalletsState() {
// clear the list of addresses
EthoWallets.clearAddressList();
EthoBlockchain.getAccountsData(
function(error) {
EthoBlockchain.getAccountsData(function (error) {
EthoMainGUI.showGeneralError(error);
},
function(data) {
}, function (data) {
data.addressData.forEach(element => {
EthoWallets.addAddressToList(element.address);
});
@@ -89,69 +86,63 @@ renderWalletsState() {
$(document).trigger("render_wallets");
EthoWallets.enableButtonTooltips();
$("#labelSumDollars").html(vsprintf("/ %.2f $ / %.4f $ per ETHO", [data.sumBalance * EthoWallets._getPrice(), EthoWallets._getPrice()]));
}
);
$("#labelSumDollars").html(vsprintf("/ %.2f $ / %.4f $ per ETHO", [
data.sumBalance * EthoWallets._getPrice(),
EthoWallets._getPrice()
]));
});
}
}
// the event to tell us that the wallets are rendered
$(document).on("render_wallets", function () {
$('#addressTable').floatThead();
$("#addressTable").floatThead();
$("#btnNewAddress").off('click').on('click', function() {
$("#btnNewAddress").off("click").on("click", function () {
$("#dlgCreateWalletPassword").iziModal();
$("#walletPasswordFirst").val("");
$("#walletPasswordSecond").val("");
$('#dlgCreateWalletPassword').iziModal('open');
$("#dlgCreateWalletPassword").iziModal("open");
function doCreateNewWallet() {
$('#dlgCreateWalletPassword').iziModal('close');
$("#dlgCreateWalletPassword").iziModal("close");
if (EthoWallets.validateNewAccountForm()) {
EthoBlockchain.createNewAccount($("#walletPasswordFirst").val(),
function(error) {
EthoBlockchain.createNewAccount($("#walletPasswordFirst").val(), function (error) {
EthoMainGUI.showGeneralError(error);
},
function(account) {
}, function (account) {
EthoWallets.addAddressToList(account);
EthoWallets.renderWalletsState();
iziToast.success({
title: 'Created',
message: 'New wallet was successfully created',
position: 'topRight',
timeout: 5000
iziToast.success({title: "Created", message: "New wallet was successfully created", position: "topRight", timeout: 5000});
});
}
);
}
}
$("#btnCreateWalletConfirm").off('click').on('click', function() {
$("#btnCreateWalletConfirm").off("click").on("click", function () {
doCreateNewWallet();
});
$("#dlgCreateWalletPassword").off('keypress').on('keypress', function(e) {
$("#dlgCreateWalletPassword").off("keypress").on("keypress", function (e) {
if (e.which == 13) {
doCreateNewWallet();
}
});
});
$(".btnShowAddressTransactions").off('click').on('click', function() {
EthoTransactions.setFilter($(this).attr('data-wallet'));
$(".btnShowAddressTransactions").off("click").on("click", function () {
EthoTransactions.setFilter($(this).attr("data-wallet"));
EthoMainGUI.changeAppState("transactions");
EthoTransactions.renderTransactions();
});
$(".btnChangWalletName").off('click').on('click', function() {
var walletAddress = $(this).attr('data-wallet');
var walletName = $(this).attr('data-name');
$(".btnChangWalletName").off("click").on("click", function () {
var walletAddress = $(this).attr("data-wallet");
var walletName = $(this).attr("data-name");
$("#dlgChangeWalletName").iziModal();
$("#inputWalletName").val(walletName);
$('#dlgChangeWalletName').iziModal('open');
$("#dlgChangeWalletName").iziModal("open");
function doChangeWalletName() {
var wallets = EthoDatatabse.getWallets();
@@ -160,90 +151,73 @@ $(document).on("render_wallets", function() {
wallets.names[walletAddress] = $("#inputWalletName").val();
EthoDatatabse.setWallets(wallets);
$('#dlgChangeWalletName').iziModal('close');
$("#dlgChangeWalletName").iziModal("close");
EthoWallets.renderWalletsState();
}
$("#btnChangeWalletNameConfirm").off('click').on('click', function() {
$("#btnChangeWalletNameConfirm").off("click").on("click", function () {
doChangeWalletName();
});
$("#dlgChangeWalletName").off('keypress').on('keypress', function(e) {
$("#dlgChangeWalletName").off("keypress").on("keypress", function (e) {
if (e.which == 13) {
doChangeWalletName();
}
});
});
$("#btnRefreshAddress").off('click').on('click', function() {
$("#btnRefreshAddress").off("click").on("click", function () {
EthoWallets.renderWalletsState();
});
$("#btnExportAccounts").off('click').on('click', function() {
ipcRenderer.send('exportAccounts', {});
$("#btnExportAccounts").off("click").on("click", function () {
ipcRenderer.send("exportAccounts", {});
});
$("#btnImportAccounts").off('click').on('click', function() {
var ImportResult = ipcRenderer.sendSync('importAccounts', {});
$("#btnImportAccounts").off("click").on("click", function () {
var ImportResult = ipcRenderer.sendSync("importAccounts", {});
if (ImportResult.success) {
iziToast.success({
title: 'Imported',
message: ImportResult.text,
position: 'topRight',
timeout: 2000
});
iziToast.success({title: "Imported", message: ImportResult.text, position: "topRight", timeout: 2000});
} else if (ImportResult.success == false) {
EthoMainGUI.showGeneralError(ImportResult.text);
}
});
$("#btnImportFromPrivateKey").off('click').on('click', function() {
$("#btnImportFromPrivateKey").off("click").on("click", function () {
$("#dlgImportFromPrivateKey").iziModal();
$("#inputPrivateKey").val("");
$('#dlgImportFromPrivateKey').iziModal('open');
$("#dlgImportFromPrivateKey").iziModal("open");
function doImportFromPrivateKeys() {
var account = EthoBlockchain.importFromPrivateKey($("#inputPrivateKey").val());
$('#dlgImportFromPrivateKey').iziModal('close');
$("#dlgImportFromPrivateKey").iziModal("close");
if (account) {
ipcRenderer.sendSync('saveAccount', account[0]);
ipcRenderer.sendSync("saveAccount", account[0]);
EthoWallets.renderWalletsState();
iziToast.success({
title: 'Imported',
message: "Account was succesfully imported",
position: 'topRight',
timeout: 2000
});
iziToast.success({title: "Imported", message: "Account was succesfully imported", position: "topRight", timeout: 2000});
} else {
EthoMainGUI.showGeneralError("Error importing account from private key!");
}
}
$("#btnImportFromPrivateKeyConfirm").off('click').on('click', function() {
$("#btnImportFromPrivateKeyConfirm").off("click").on("click", function () {
doImportFromPrivateKeys();
});
$("#dlgImportFromPrivateKey").off('keypress').on('keypress', function(e) {
$("#dlgImportFromPrivateKey").off("keypress").on("keypress", function (e) {
if (e.which == 13) {
doImportFromPrivateKeys();
}
});
});
$(".textAddress").off('click').on('click', function() {
$(".textAddress").off("click").on("click", function () {
EthoMainGUI.copyToClipboard($(this).html());
iziToast.success({
title: 'Copied',
message: 'Address was copied to clipboard',
position: 'topRight',
timeout: 2000
});
iziToast.success({title: "Copied", message: "Address was copied to clipboard", position: "topRight", timeout: 2000});
});
});