Update to use user-agent and disable tx history.

This commit is contained in:
jwinterm
2016-09-24 17:10:01 -07:00
parent 1ecb52690b
commit 858cbbf886
17 changed files with 110 additions and 48 deletions
+7 -7
View File
@@ -1,21 +1,21 @@
# LightWallet GUI
This is a GUI frontend that runs on top of simplewallet (in RPC mode). It is designed to work with a remote bitmonerod node by default, so that it can function as a lightweight wallet for most users. By default it uses Atrides open node at http://node.moneroclub.com:8880, but you can change the node it uses to a local node during setup or at any launch; to use a local bitmonerod instance set it as http://localhost:18081.
This is a GUI frontend that runs on top of simplewallet (in RPC mode). It is designed to work with a remote bitmonerod node by default, so that it can function as a lightweight wallet for most users. By default it uses Atrides open node at http://node.moneroworld.com:18081, but you can change the node it uses to a local node during setup or at any launch; to use a local bitmonerod instance set it as http://localhost:18081.
**This program is an alpha version, and although I don't think there is really any way to screw up your wallet, please exercise some modicum of caution.**
## Installation
### Windows, Linux, and Mac
The requirements for running the program using the jar file release is a java virtual machine installed v1.7+, and simplewallet v0.9+ in the same directory (on Windows you need simplewallet.exe, libeay32.dll, libwinpthread-1.dll, and ssleay32.dll). If you also want to run a local daemon you'll bitmonerod.exe/bitmonerod binary. The simplewallet and bitmonerod files can be downloaded here: https://github.com/monero-project/bitmonero/releases
The requirements for running the program using the jar file release is a java virtual machine installed v1.7+, and monero-wallet-cli v0.10+ in the same directory. If you also want to run a local daemon you'll monerod.exe/monerod binary. The wallet and daemon files can be downloaded here: https://github.com/monero-project/bitmonero/releases
If you're using the binary LightWallet.exe, you still need to have simplewallet.exe and the dll files in the same directory.
If you're using the binary LightWallet.exe, you still need to have monero-wallet-cli.exe in the same directory.
## Running
It should be OK to launch the program with an instance of bitmonerod and/or simplewallet running.
It should be OK to launch the program with an instance of monerod and/or monero-wallet-cli running.
On the initial run, it will prompt you to create a new wallet or to import one by typing/copying in the path of the keys file or importing a 25 word mnemonic seed. This will create several files in the same directory as LightWallet and simplewallet, including lightwallet.conf. If you ever want to create or import a new wallet, simply delete lightwallet.conf.
On the initial run, it will prompt you to create a new wallet or to import one by typing/copying in the path of the keys file or importing a 25 word mnemonic seed. This will create several files in the same directory as LightWallet and monero-wallet-cli, including lightwallet.conf. If you ever want to create or import a new wallet, simply delete lightwallet.conf.
## Known issues
If you manage to crash the program, you will probably get an instance of simplewallet(.exe) hanging around, so to get rid of it you will need to go into the task manager processes tab and end the simplewallet process on windows, "ps -A | grep simplewallet" to get PID and then "kill PID" or "killall simplewallet" on linux, or restart your computer.
If you manage to crash the program, you will probably get an instance of monero-wallet-cli(.exe) hanging around, so to get rid of it you will need to go into the task manager processes tab and end the monero-wallet-cli process on windows, "ps -A | grep monero-wallet-cli" to get PID and then "kill PID" or "killall monero-wallet-cli" on linux, or restart your computer.
## Future Work
There seems to sometimes be an issue with properly tallying all previous transactions. This is shown in the wallet tab as calculated balance. I would like to make sure that this always matches total/locked balance and all incoming/outgoing transactions are properly accounted for.
Transaction history has been disabled for the time being. If you want to parse your tx history check monero-wallet-cli.log in the same directory.
+2 -1
View File
@@ -34,7 +34,7 @@ public class LightWallet extends Game {
os = System.getProperty("os.name");
if (os.contains("Windows")) {
simplewalletloc = dir + "\\" + "simplewallet.exe";
simplewalletloc = dir + "\\" + "monero-wallet-cli.exe";
System.out.println(simplewalletloc);
}
@@ -53,6 +53,7 @@ public class LightWallet extends Game {
if (line.contains("Wallet address: ")) {walletvalues.setAddress(line.split("address: ")[1]);}
if (line.contains("view key: ")) {walletvalues.setViewkey(line.split("view key: ")[1]);}
if (line.contains("Node address: ")) {walletvalues.setNode(line.split("address: ")[1]);}
if (line.contains("User agent: ")) {walletvalues.setUserAgent(line.split("User agent: ")[1]);}
}
} catch (IOException e) {
// TODO Auto-generated catch block
@@ -3,7 +3,7 @@ package com.jw.lightwallet.daemon;
public class BlockHeader {
int depth;
int difficulty;
long difficulty;
String hash;
int height;
int major_version;
@@ -21,7 +21,7 @@ public class BlockHeader {
public void setDepth(int depth) {
this.depth = depth;
}
public int getDifficulty() {
public long getDifficulty() {
return difficulty;
}
public void setDifficulty(int difficulty) {
@@ -32,7 +32,7 @@ public class DaemonRPC {
DaemonResponse daemonresponse = new Gson().fromJson(response, DaemonResponse.class);
//System.out.print("GSON response is" + daemonresponse.getId());
daemonvalues.setBlockheight(daemonresponse.getResult().getBlock_header().getHeight());
daemonvalues.setDiff(daemonresponse.getResult().getBlock_header().getDifficulty());
daemonvalues.setDiff((daemonresponse.getResult().getBlock_header().getDifficulty()));
daemonvalues.setLastblocktime(daemonresponse.getResult().getBlock_header().getTimestamp());
daemonvalues.setLastblockreward(daemonresponse.getResult().getBlock_header().getReward());
daemonvalues.setStatus(daemonresponse.getResult().getStatus());
@@ -6,6 +6,8 @@ import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
@@ -193,7 +195,7 @@ public class CreateScreen extends AbstractScreen {
System.out.println("Starting creator");
try {
Process wp = Runtime.getRuntime().exec("simplewallet --generate-new-wallet " + name + " --password " + pw);
Process wp = Runtime.getRuntime().exec("monero-wallet-cli --generate-new-wallet " + name + " --password " + pw);
Writer wr = new OutputStreamWriter( wp.getOutputStream() );
BufferedReader rd = new BufferedReader( new InputStreamReader( wp.getInputStream() ) );
@@ -227,10 +229,22 @@ public class CreateScreen extends AbstractScreen {
wr.write( "exit\n" );
wr.flush();
String rando = name + Double.toString(Math.random());
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
md.update(rando.getBytes("UTF-8")); // Change this to "UTF-16" if needed
byte[] digest = md.digest();
game.walletvalues.setName(name);
game.walletvalues.setPw(pw);
game.walletvalues.setSeed(seed);
game.walletvalues.setNode(nodetext.getText());;
game.walletvalues.setNode(nodetext.getText());
game.walletvalues.setUserAgent(digest.toString());
PrintWriter infowriter = new PrintWriter(name + "info.txt", "UTF-8");
infowriter.println("Wallet name: " + name);
@@ -245,6 +259,7 @@ public class CreateScreen extends AbstractScreen {
confwriter.println("Wallet address: " + game.walletvalues.getAddress());
confwriter.println("Wallet view key: " + game.walletvalues.getViewkey());
confwriter.println("Node address: " + nodetext.getText());
confwriter.println("User agent: " + digest.toString());
confwriter.close();
PrintWriter txwriter = new PrintWriter(name + "tx.txt", "UTF-8");
@@ -9,6 +9,8 @@ import java.io.PrintWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
@@ -220,7 +222,7 @@ public class ImportKeysScreen extends AbstractScreen {
try {
Process wp = Runtime.getRuntime().exec("simplewallet --wallet-file " + name + " --password " + pw + " --daemon-address http://localhost:66666");
Process wp = Runtime.getRuntime().exec("monero-wallet-cli --wallet-file " + name + " --password " + pw + " --daemon-address http://localhost:66666");
Writer wr = new OutputStreamWriter( wp.getOutputStream() );
BufferedReader rd = new BufferedReader( new InputStreamReader( wp.getInputStream() ) );
@@ -255,9 +257,22 @@ public class ImportKeysScreen extends AbstractScreen {
wr.write( "exit\n" );
wr.flush();
String rando = name + Double.toString(Math.random());
MessageDigest md = null;
try {
md = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
md.update(rando.getBytes("UTF-8")); // Change this to "UTF-16" if needed
byte[] digest = md.digest();
game.walletvalues.setName(name);
game.walletvalues.setPw(pw);
game.walletvalues.setNode(nodetext.getText());;
game.walletvalues.setNode(nodetext.getText());
game.walletvalues.setUserAgent(digest.toString());
PrintWriter infowriter = new PrintWriter(name + "info.txt", "UTF-8");
infowriter.println("Wallet name: " + name);
@@ -272,6 +287,7 @@ public class ImportKeysScreen extends AbstractScreen {
confwriter.println("Wallet address: " + game.walletvalues.getAddress());
confwriter.println("Wallet view key: " + game.walletvalues.getViewkey());
confwriter.println("Node address: " + nodetext.getText());
confwriter.println("User agent: " + digest.toString());
confwriter.close();
PrintWriter txwriter = new PrintWriter(name + "tx.txt", "UTF-8");
@@ -9,6 +9,8 @@ import java.io.PrintWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
@@ -231,7 +233,7 @@ public class ImportSeedScreen extends AbstractScreen {
try {
Process wp = Runtime.getRuntime().exec("simplewallet --restore-deterministic-wallet --daemon-address http://localhost:66666");
Process wp = Runtime.getRuntime().exec("monero-wallet-cli --restore-deterministic-wallet --daemon-address http://localhost:66666");
Writer wr = new OutputStreamWriter( wp.getOutputStream() );
BufferedReader rd = new BufferedReader( new InputStreamReader( wp.getInputStream() ) );
@@ -253,10 +255,24 @@ public class ImportSeedScreen extends AbstractScreen {
wr.write( seed + "\n" );
wr.flush();
MessageDigest md = null;
String rando = name + Double.toString(Math.random());
try {
md = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
md.update(rando.getBytes("UTF-8")); // Change this to "UTF-16" if needed
byte[] digest = md.digest();
game.walletvalues.setName(name);
game.walletvalues.setPw(pw);
game.walletvalues.setSeed(seed);
game.walletvalues.setNode(nodetext.getText());
game.walletvalues.setUserAgent(digest.toString());
while (true) {
str = rd.readLine();
@@ -278,6 +294,7 @@ public class ImportSeedScreen extends AbstractScreen {
wr.write( "exit\n" );
wr.flush();
PrintWriter infowriter = new PrintWriter(name + "info.txt", "UTF-8");
infowriter.println("Wallet name: " + name);
@@ -292,6 +309,7 @@ public class ImportSeedScreen extends AbstractScreen {
confwriter.println("Wallet address: " + game.walletvalues.getAddress());
confwriter.println("Wallet view key: " + game.walletvalues.getViewkey());
confwriter.println("Node address: " + nodetext.getText());
confwriter.println("User agent: " + digest.toString());
confwriter.close();
PrintWriter txwriter = new PrintWriter(name + "tx.txt", "UTF-8");
@@ -81,15 +81,19 @@ public class MainScreen extends AbstractScreen {
double calcbalance;
DecimalFormat df;
// Wallet sync height
String height;
public MainScreen(final LightWallet game) {
super(game);
wq = new AtomicQueue<String>(1000);
wq = new AtomicQueue<String>(100000);
txlist = new ArrayList<Tx>();
txcount = 0;
calcbalance = 0;
df = new DecimalFormat("#.############");
height = "";
Skin uiSkin = new Skin(Gdx.files.internal("skin/uiskin.json"));
@@ -166,9 +170,9 @@ public class MainScreen extends AbstractScreen {
stage.addActor(screenlayout);
// Check tx file
dumptxlist();
// dumptxlist();
}
public void show() {
super.show();
launchsimplewallet();
@@ -207,8 +211,8 @@ public class MainScreen extends AbstractScreen {
}
public void runtasks() {
// Read simplewallet queue to check for transactions
readwalletqueue();
// Read simplewallet queue to check for transactions
if (fivesectimer == true) {
// Timer task to check balance from simplewallet
balancerpc.getinfo(balancevalues);
@@ -221,6 +225,12 @@ public class MainScreen extends AbstractScreen {
walletview.balancevalue.setStyle(game.uiSkin.get("redlabel", LabelStyle.class));
walletview.unlockedvalue.setStyle(game.uiSkin.get("redlabel", LabelStyle.class));
}
Gdx.app.log(LightWallet.LOG, "Height is at: " + height);
walletview.syncvalue.setText(height + " / " + daemonvalues.getBlockheight());
if (height.equals(Integer.toString(daemonvalues.getBlockheight()))) {
walletview.syncvalue.setStyle(game.uiSkin.get("greenlabel", LabelStyle.class));
} else {walletview.syncvalue.setStyle(game.uiSkin.get("default", LabelStyle.class));}
// dumptxlist();
fivesectimer = false;
accum5s = 0;
}
@@ -234,7 +244,6 @@ public class MainScreen extends AbstractScreen {
if (sixtysectimer == true) {
// Timer task to try and save wallet every minute
walletsaverpc.trysave(walletview.getSavewalletlabel());
dumptxlist();
sixtysectimer = false;
accum60s = 0;
}
@@ -251,12 +260,12 @@ public class MainScreen extends AbstractScreen {
public void run() {
// Setup simplewallet command with the specified file, password, and node address
try {
Gdx.app.log(LightWallet.LOG, "Command is: " + "simplewallet --wallet-file " + game.walletvalues.getName()
Gdx.app.log(LightWallet.LOG, "Command is: " + "monero-wallet-cli --wallet-file " + game.walletvalues.getName()
+ " --password " + game.walletvalues.getPw() + " --daemon-address " + game.walletvalues.getNode()
+ " --rpc-bind-port 19091 --log-level 2");
wp = Runtime.getRuntime().exec("simplewallet --wallet-file " + game.walletvalues.getName()
+ " --rpc-bind-port 19091 --user-agent " + game.walletvalues.getUserAgent() + " --log-level 2");
wp = Runtime.getRuntime().exec("monero-wallet-cli --wallet-file " + game.walletvalues.getName()
+ " --password " + game.walletvalues.getPw() + " --daemon-address " + game.walletvalues.getNode()
+ " --rpc-bind-port 19091 --log-level 2");
+ " --rpc-bind-port 19091 --user-agent " + game.walletvalues.getUserAgent() + " --log-level 2");
wr = new BufferedReader(new InputStreamReader(wp.getInputStream()));
while (true) {
String str = wr.readLine();
@@ -285,18 +294,10 @@ public class MainScreen extends AbstractScreen {
try{
// If the string contains "height" then update the daemon and wallet screen blockheight
if (queuepoll != null && queuepoll.contains("height:")) {
String height = queuepoll.split("height: ")[1].split(",")[0];
walletview.syncvalue.setText(height + " / " + daemonvalues.getBlockheight());
if (height.equals(Integer.toString(daemonvalues.getBlockheight()))) {
walletview.syncvalue.setStyle(game.uiSkin.get("greenlabel", LabelStyle.class));
} else {walletview.syncvalue.setStyle(game.uiSkin.get("default", LabelStyle.class));}
height = queuepoll.split("height: ")[1].split(",")[0];
}
else if (queuepoll != null && queuepoll.contains("height ")) {
String height = queuepoll.split("height ")[1].split(",")[0];
walletview.syncvalue.setText(height + " / " + daemonvalues.getBlockheight());
if (height.equals(Integer.toString(daemonvalues.getBlockheight()))) {
walletview.syncvalue.setStyle(game.uiSkin.get("greenlabel", LabelStyle.class));
} else {walletview.syncvalue.setStyle(game.uiSkin.get("default", LabelStyle.class));}
height = queuepoll.split("height ")[1].split(",")[0];
}
// If the string contains "money" then create a tx and add it to the txlist
else if (queuepoll != null && queuepoll.contains("money")) {
@@ -332,7 +333,7 @@ public class MainScreen extends AbstractScreen {
public void dumptxlist() {
boolean newtx = true; // this is a flag to reset whenever txid or type changes
Tx temptx = new Tx();
// Cycle through list of transactions from queue in last 60 s
// Cycle through list of transactions from queue in last 5 s
if (txlist.size() > 0) {
for (int i = 0; i < txlist.size(); i++) {
// If newtx flag then create a new temporary tx
@@ -388,8 +389,10 @@ public class MainScreen extends AbstractScreen {
historyview.getContainer().add(tmpbtn).fillX().row();
if (line.split(" | ")[0].equals("RECEIVED")) {
calcbalance += Double.parseDouble(tmpbtn.getText().toString().split(" | ")[2]);
Gdx.app.log(LightWallet.LOG, "Adding to balance: " + Double.parseDouble(tmpbtn.getText().toString().split(" | ")[2]));
} else {
calcbalance -= Double.parseDouble(tmpbtn.getText().toString().split(" | ")[2]);
Gdx.app.log(LightWallet.LOG, "Subracting from balance: " + Double.parseDouble(tmpbtn.getText().toString().split(" | ")[2]));
}
walletview.calcedvalue.setText(df.format(calcbalance) + " XMR");
txcount += 1;
@@ -16,7 +16,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.TextField;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.google.gson.Gson;
import com.jw.lightwallet.LightWallet;
import com.jw.lightwallet.daemon.DaemonResponse;
import com.jw.lightwallet.tx.TxResponse;
import com.jw.lightwallet.utils.BalanceValues;
@@ -72,7 +71,7 @@ public class TransactionView {
txlayout.add(idlabel).pad(padvalue).width(100);
txlayout.add(idvalue).pad(padvalue).width(600).row();
sendbtn = new TextButton("Payola!", game.uiSkin);
sendbtn = new TextButton("Send payment!", game.uiSkin);
txlayout.add(new Label("", game.uiSkin));
txlayout.add(sendbtn).width(400);
@@ -7,7 +7,8 @@ public class Constants {
public static final float WORLD_WIDTH = 800;
public static final float WORLD_HEIGHT = 600;
public static final String moneroclubrpc = "http://node.moneroclub.com/json_rpc:8880";
public static final String moneroclubdmn = "http://node.moneroclub.com:8880";
//public static final String moneroclubrpc = "http://node.moneroclub.com/json_rpc:8880";
//public static final String moneroclubdmn = "http://node.moneroclub.com:8880";
public static final String moneroclubrpc = "http://node.moneroworld.com/json_rpc:18081";
public static final String moneroclubdmn = "http://node.moneroworld.com:18081";
}
@@ -1,10 +1,13 @@
package com.jw.lightwallet.utils;
import com.badlogic.gdx.Gdx;
import com.jw.lightwallet.LightWallet;
public class DaemonValues {
int blockheight;
int diff;
int hashrate;
long diff;
long hashrate;
long lastblocktime;
long lastblockreward;
String status;
@@ -17,12 +20,12 @@ public class DaemonValues {
this.blockheight = blockheight;
}
public int getDiff() {
public long getDiff() {
return diff;
}
public void setDiff(int diff) {
this.diff = diff;
this.hashrate = diff/120;
public void setDiff(long l) {
this.diff = l;
this.hashrate = l/120;
}
public float getHashrate() {
return hashrate/1e6f;
@@ -8,7 +8,7 @@ public class WalletValues {
String viewkey;
String seed;
String node;
String useragent;
public String getName() {
@@ -47,6 +47,12 @@ public class WalletValues {
public void setNode(String node) {
this.node = node;
}
public String getUserAgent() {
return useragent;
}
public void setUserAgent(String useragent) {
this.useragent = useragent;
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.