Advertisement
Guest User

Untitled

a guest
Mar 15th, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.00 KB | None | 0 0
  1. /*
  2. Copyright (c) 2017 VoteCoin team, all rights reserved
  3. See LICENSE file for more info
  4. */
  5.  
  6. const electron = require('electron');
  7. const {app, dialog, ipcMain, Menu} = require('electron');
  8. const BrowserWindow = electron.BrowserWindow;
  9. const http = require('./redirect.js').http;
  10. const https = require('./redirect.js').https;
  11. const path = require('path')
  12. const url = require('url')
  13. const spawn = require('child_process').spawn;
  14. const process = require('process');
  15. const fs = require('fs');
  16. const crypto = require("crypto");
  17. const os = require('os');
  18.  
  19. // global variables, will be needed later
  20. var wallet_password="";
  21. var wallet_user="";
  22. var wallet_port="";
  23. var wallet_startup_params=['-experimentalfeatures','-zmergetoaddress','-txindex'];
  24.  
  25. // Keep a global reference of the window object, if you don't, the window will
  26. // be closed automatically when the JavaScript object is garbage collected.
  27. let win;
  28. let splash;
  29. let server;
  30. let canQuit=true;
  31. let showExitPrompt=false;
  32. let lastRPCerr='';
  33.  
  34. function createWindow () {
  35. // Create the browser window.
  36. win = new BrowserWindow({width: 1200, height: 720, icon: path.join(__dirname, 'votecoin.ico')})
  37.  
  38. if (process.platform === 'darwin')
  39. {
  40. var menuTemplate = [];
  41. menuTemplate.push({
  42. label: 'Edit',
  43. submenu: [
  44. {role: 'cut'},
  45. {role: 'copy'},
  46. {role: 'paste'},
  47. {role: 'delete'},
  48. {role: 'selectall'}
  49. ]}
  50. );
  51.  
  52. const applicationMenu = Menu.buildFromTemplate(menuTemplate)
  53. Menu.setApplicationMenu(applicationMenu)
  54. win.setMenu(applicationMenu);
  55. }
  56. else win.setMenu(null);
  57.  
  58. // and load the index.html of the app.
  59. win.loadURL(url.format({
  60. pathname: path.join(__dirname, 'index.html'),
  61. protocol: 'file:',
  62. slashes: true
  63. }))
  64.  
  65. win.on('close', (e) =>
  66. {
  67. if (showExitPrompt)
  68. {
  69. e.preventDefault() // Prevents the window from closing
  70. dialog.showMessageBox({type: 'warning', buttons: [], title: 'Warning', message: 'Please wait for all outgoing payments to complete. This can take few minutes.' });
  71. }
  72. });
  73.  
  74. // Emitted when the window is closed.
  75. win.on('closed', () => {
  76. // Dereference the window object, usually you would store windows
  77. // in an array if your app supports multi windows, this is the time
  78. // when you should delete the corresponding element.
  79. win = null
  80. })
  81. }
  82.  
  83.  
  84. var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory)
  85. {
  86. // Someone tried to run a second instance, we should focus our window.
  87. if (win) { if (win.isMinimized()) win.restore(); win.focus(); }
  88. if (splash) { if (splash.isMinimized()) splash.restore(); splash.focus(); }
  89. });
  90.  
  91. if (shouldQuit) { app.quit(); return; }
  92.  
  93. // register default protocol client
  94. app.setAsDefaultProtocolClient("votecoin");
  95. app.setAsDefaultProtocolClient("vote");
  96.  
  97. // This method will be called when Electron has finished
  98. // initialization and is ready to create browser windows.
  99. // Some APIs can only be used after this event occurs.
  100. app.on('ready', createWindow)
  101.  
  102. // Quit when all windows are closed.
  103. app.on('window-all-closed', () => {
  104. // On macOS it is common for applications and their menu bar
  105. // to stay active until the user quits explicitly with Cmd + Q
  106. if (process.platform !== 'darwin') {
  107. app.quit()
  108. }
  109. })
  110.  
  111. app.on('activate', () => {
  112. // On macOS it's common to re-create a window in the app when the
  113. // dock icon is clicked and there are no other windows open.
  114. if (win === null) {
  115. createWindow()
  116. }
  117. })
  118.  
  119. // -----------------------------------------------------------------------------------
  120.  
  121. function mkdir(path)
  122. {
  123. try { fs.mkdirSync(path); } catch(e) {}
  124. return path;
  125. }
  126.  
  127. function daemon_exe()
  128. {
  129. if (process.platform == 'win32') return "votecoind.exe";
  130. if (process.platform == 'linux') return "votecoind";
  131. if (process.platform == 'darwin') return "votecoind";
  132. }
  133.  
  134. function daemon_path()
  135. {
  136. if (process.platform == 'win32') return mkdir(app.getAppPath());
  137. if (process.platform == 'linux') return mkdir(app.getAppPath());
  138. if (process.platform == 'darwin') return mkdir(app.getAppPath());
  139. }
  140.  
  141. function daemon_data_path()
  142. {
  143. if (process.platform == 'win32') return mkdir(app.getAppPath()+"/VoteCoin");
  144. if (process.platform == 'linux') return mkdir(os.homedir()+"/.votecoin");
  145. if (process.platform == 'darwin') return mkdir(os.homedir()+"/Library/Application Support/VoteCoin");
  146. }
  147.  
  148. function settings_path()
  149. {
  150. if (process.platform == 'win32') return mkdir(app.getAppPath()+"/settings");
  151. if (process.platform == 'linux') return mkdir(os.homedir()+"/.votecoin/settings");
  152. if (process.platform == 'darwin') return mkdir(os.homedir()+"/Library/Application Support/VoteCoin/settings");
  153. }
  154.  
  155. function zksnark_path()
  156. {
  157. if (process.platform == 'win32') return mkdir(app.getAppPath()+"/zkSNARK");
  158. if (process.platform == 'linux') return mkdir(os.homedir()+"/.zcash-params");
  159. if (process.platform == 'darwin') return mkdir(os.homedir()+"/Library/Application Support/ZcashParams");
  160. }
  161.  
  162.  
  163. function walletStop()
  164. {
  165. console.log('wallet stop');
  166.  
  167. splash = new BrowserWindow({width: 400, height: 100, icon: path.join(__dirname, 'votecoin.ico')});
  168. splash.setMenu(null);
  169. splash.loadURL(url.format({
  170. pathname: path.join(__dirname, 'wait.html'),
  171. protocol: 'file:',
  172. slashes: true
  173. }));
  174.  
  175. // if user forces splash close, quit. User's responsibility
  176. splash.on('closed',function(){ canQuit=true; app.quit(); })
  177.  
  178. rpc("stop",[],function(){ canQuit=true; app.quit(); },true);
  179. }
  180.  
  181. function walletStart()
  182. {
  183. console.log('wallet start');
  184. canQuit=false;
  185. server = spawn(daemon_path()+'/'+daemon_exe(), wallet_startup_params, {detached:true, stdio:'ignore', cwd:daemon_path()} )
  186. .on('exit',code=>
  187. {
  188. if (code!=0)
  189. {
  190. // check log for possible rescan
  191. var logfile=daemon_data_path()+"/debug.log";
  192. try {
  193. var log=fs.readFileSync(logfile).toString().split("\n").slice(-300).join("\n");
  194. if (log.match(/ERROR:/g).length>3 && log.match(/Shutdown: done/g).length>3)
  195. {
  196. try { fs.unlinkSync(logfile+".log"); } catch(e) {}
  197. try { fs.renameSync(logfile,logfile+".log"); } catch(e) {}
  198. wallet_startup_params.push(['-reindex']);
  199. }
  200. } catch (e) {}
  201. }
  202. if (!win) { canQuit=true; }
  203. });
  204. }
  205.  
  206. app.on('before-quit', (event) =>
  207. {
  208. console.log("beforequit");
  209. if (!canQuit)
  210. {
  211. event.preventDefault();
  212. walletStop();
  213. }
  214. });
  215.  
  216.  
  217.  
  218. function rpc(method,params,doneFunc,errorFunc,hideErrorMessage)
  219. {
  220. if (!params) params=[];
  221. var data={"method":method, params, id:Math.floor(Math.random()*10000)};
  222. data=JSON.stringify(data);
  223.  
  224. var options = {
  225. host: "127.0.0.1",
  226. port: wallet_port,
  227. path: "/",
  228. method: 'POST',
  229. headers: {
  230. 'Authorization': 'Basic '+Buffer.from(wallet_user+':'+wallet_password).toString('base64'),
  231. 'Content-Type': 'application/json',
  232. 'Connection': 'Close',
  233. 'Content-Length': Buffer.byteLength(data)
  234. }
  235. }
  236.  
  237. var error=function(data)
  238. {
  239. if (data && data.error && data.error.message && !hideErrorMessage) lastRPCerr=data.error.message;
  240. walletStart(); // rpc error encountered means wallet is not running. Start it. If wallet was started, no problem
  241. if (errorFunc===true) setTimeout(function(){ rpc(method,params,doneFunc,errorFunc,hideErrorMessage); },1000);
  242. else if (errorFunc) errorFunc(data);
  243. }
  244.  
  245. // The Request
  246. var request = http.request(options, function(response)
  247. {
  248. var result="";
  249. lastRPCerr="";
  250.  
  251. response.on('data', function(chunk)
  252. {
  253. if (chunk)
  254. {
  255. var data = chunk.toString('utf8');
  256. result+=data;
  257. }
  258. });
  259.  
  260. response.on('end',function(e)
  261. {
  262. try { result=JSON.parse(result); } catch(e){ lastRPCerr=result; console.log("error parsing json response: ",e); console.log(result); result=false; }
  263. if (!result || result.error) error(result);
  264. else if (doneFunc) { doneFunc(result.result); }
  265. });
  266.  
  267. }).on("error", function(e) {
  268. error(data);
  269. });
  270.  
  271. //optionally Timeout Handling
  272. request.on('socket', function(socket)
  273. {
  274. socket.setTimeout(5000);
  275. socket.on('timeout', function() { request.abort(); });
  276. });
  277.  
  278. request.write(data);
  279. request.end();
  280. }
  281.  
  282.  
  283. function downloadFile(host,port,path,targetFile,size,progressFunc,doneFunc)
  284. {
  285. var file = fs.createWriteStream(targetFile);
  286. var bytes=0;
  287. var options = { host: host, port: port, path: path, method: 'GET', headers: {'Connection': 'Close'} }
  288. var request = https.get(options, function(response)
  289. {
  290. response.on('data', function(chunk) { if (chunk) { file.write(chunk); bytes+=chunk.length; progressFunc(path,size,bytes); } });
  291. response.on('end', function(){ file.end(); if (doneFunc) doneFunc(); });
  292. }).on("error", function(e) { console.log(e); });
  293. }
  294.  
  295. // download all files if size does not match
  296.  
  297. var downloads=
  298. [
  299. {host:'z.cash',port:443,path:"/downloads/sprout-verifying.key",target:zksnark_path()+'/sprout-verifying.key', size: 1449},
  300. {host:'z.cash',port:443,path:"/downloads/sprout-proving.key",target:zksnark_path()+'/sprout-proving.key', size: 910173851}
  301. ]
  302.  
  303. function download_all_files(progressFunc,doneFunc)
  304. {
  305. var current=downloads.shift();
  306. if (!current) doneFunc(); // we are done downloading all files
  307. else
  308. {
  309. console.log('Download '+current.target);
  310. if (fs.existsSync(current.target) && fs.statSync(current.target).size==current.size) { download_all_files(progressFunc,doneFunc); return; }
  311. else downloadFile(current.host,current.port,current.path,current.target,current.size,progressFunc,function(){ downloads.push(current); download_all_files(progressFunc,doneFunc); });
  312. }
  313. }
  314.  
  315. function init_rpc_password()
  316. {
  317. var confpath=daemon_data_path()+'/votecoin.conf';
  318. if (!fs.existsSync(confpath))
  319. {
  320. wallet_user="admin";
  321. wallet_password=crypto.randomBytes(20).toString('hex')
  322. wallet_port=6663;
  323. fs.writeFileSync(confpath, "rpcport="+wallet_port+"\nrpcuser="+wallet_user+"\nrpcpassword="+wallet_password+"\nbanscore=500\nbantime=60\nrpcworkqueue=80");
  324. }
  325. else
  326. {
  327. var data=fs.readFileSync(confpath).toString();
  328. wallet_user=data.match(/^rpcuser=(.+)/m)[1];
  329. wallet_password=data.match(/^rpcpassword=(.+)/m)[1];
  330. wallet_port=data.match(/^rpcport=([0-9]+)/m)[1];
  331. }
  332. }
  333.  
  334. function setTransactionInProgress(e)
  335. {
  336. showExitPrompt=!!e;
  337. }
  338.  
  339. function getLastRPCerrorMessage()
  340. {
  341. return lastRPCerr;
  342. }
  343.  
  344. function openDevelTools()
  345. {
  346. win.webContents.openDevTools();
  347. }
  348.  
  349. // -----------------------------------------------------------------------------------------
  350.  
  351. function storage_keyfile(key)
  352. {
  353. return settings_path()+"/"+key.replace(/[^a-zA-Z0-9]/,"_")+".json";
  354. }
  355.  
  356. function storage_save(key,valStr)
  357. {
  358. fs.writeFileSync(storage_keyfile(key),valStr);
  359. }
  360.  
  361. function storage_load(key,default_value)
  362. {
  363. var val;
  364. try { val=fs.readFileSync(storage_keyfile(key)).toString(); } catch(e) { }
  365. if (typeof val == "undefined" || val == null) { val=default_value; storage_save(key,val); }
  366. return val;
  367. }
  368.  
  369. // -----------------------------------------------------------------------------------------
  370.  
  371.  
  372. init_rpc_password();
  373.  
  374. exports.rpc=rpc;
  375. exports.walletStart=walletStart;
  376. exports.download_all_files=download_all_files;
  377. exports.setTransactionInProgress=setTransactionInProgress;
  378. exports.openDevelTools=openDevelTools;
  379. exports.getLastRPCerrorMessage=getLastRPCerrorMessage;
  380. exports.storage_save=storage_save;
  381. exports.storage_load=storage_load;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement