├── .gitignore ├── lib └── asg.cliche-110413.jar ├── src └── main │ ├── resources │ └── net │ │ └── plan99 │ │ └── payfile │ │ └── gui │ │ ├── checkpoints │ │ ├── bitcoin_logo_plain.png │ │ ├── utils │ │ ├── text-validation.css │ │ └── alert.fxml │ │ ├── controls │ │ └── bitcoin_address.fxml │ │ ├── connect_server.fxml │ │ ├── send_money.fxml │ │ └── main.fxml │ ├── java │ └── net │ │ └── plan99 │ │ └── payfile │ │ ├── ProtocolException.java │ │ ├── gui │ │ ├── Settings.java │ │ ├── utils │ │ │ ├── TextFieldValidator.java │ │ │ ├── ThrottledRunLater.java │ │ │ ├── AlertWindowController.java │ │ │ └── GuiUtils.java │ │ ├── BitcoinAddressValidator.java │ │ ├── controls │ │ │ ├── BitcoinAddressValidator.java │ │ │ └── ClickableBitcoinAddress.java │ │ ├── ProgressOutputStream.java │ │ ├── SendMoneyController.java │ │ ├── ConnectServerController.java │ │ ├── Controller.java │ │ └── Main.java │ │ ├── utils │ │ └── Exceptions.java │ │ ├── client │ │ ├── CLI.java │ │ └── PayFileClient.java │ │ └── server │ │ └── Server.java │ └── payfile.proto ├── README.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.wallet 3 | *.spvchain 4 | target/ 5 | *.iml 6 | *.DS_Store 7 | *.tmp 8 | -------------------------------------------------------------------------------- /lib/asg.cliche-110413.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikehearn/PayFile/HEAD/lib/asg.cliche-110413.jar -------------------------------------------------------------------------------- /src/main/resources/net/plan99/payfile/gui/checkpoints: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikehearn/PayFile/HEAD/src/main/resources/net/plan99/payfile/gui/checkpoints -------------------------------------------------------------------------------- /src/main/resources/net/plan99/payfile/gui/bitcoin_logo_plain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikehearn/PayFile/HEAD/src/main/resources/net/plan99/payfile/gui/bitcoin_logo_plain.png -------------------------------------------------------------------------------- /src/main/resources/net/plan99/payfile/gui/utils/text-validation.css: -------------------------------------------------------------------------------- 1 | .text-field.validation_error { 2 | -fx-background-color: red, 3 | linear-gradient( 4 | to bottom, 5 | derive(red,70%) 5%, 6 | derive(red,90%) 40% 7 | ); 8 | } 9 | 10 | .text-field.validation_warning { 11 | -fx-background-color: orange, 12 | linear-gradient( 13 | to bottom, 14 | derive(orange,70%) 5%, 15 | derive(orange,90%) 40% 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/net/plan99/payfile/ProtocolException.java: -------------------------------------------------------------------------------- 1 | package net.plan99.payfile; 2 | 3 | public class ProtocolException extends Exception { 4 | public static enum Code { 5 | GENERIC, 6 | NETWORK_MISMATCH, 7 | INTERNAL_ERROR, 8 | } 9 | 10 | private Code code; 11 | 12 | public ProtocolException(String msg) { 13 | super(msg); 14 | code = Code.GENERIC; 15 | } 16 | 17 | public ProtocolException(Code code, String msg) { 18 | super(msg); 19 | this.code = code; 20 | } 21 | 22 | public Code getCode() { 23 | return code; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PayFile 2 | ======= 3 | 4 | Mike Hearn 5 | 6 | PayFile is a set of three apps showing how to build a simple file server and download client that uses Bitcoin micropayment channels to incrementally pay for each chunk of data. 7 | 8 | It provides a server, a simple console client and a JavaFX2 based GUI. The GUI is designed to act as both a very simple file browser/downloader and also a standalone wallet that money can be loaded into/out of. It's based on the "wallet template" app found inside the source code for the bitcoinj library. 9 | 10 | Current status: incomplete and not yet ready for public announcement. This repository is just acting as a backup area until the project is further along. There is a TODO list in the Main.java file of the GUI client. 11 | -------------------------------------------------------------------------------- /src/main/java/net/plan99/payfile/gui/Settings.java: -------------------------------------------------------------------------------- 1 | package net.plan99.payfile.gui; 2 | 3 | import com.google.common.net.HostAndPort; 4 | import net.plan99.payfile.client.PayFileClient; 5 | 6 | import java.util.prefs.Preferences; 7 | 8 | public class Settings { 9 | private static Preferences preferences = Preferences.userNodeForPackage(Settings.class); 10 | 11 | public static void setLastServer(HostAndPort serverName) { 12 | preferences.put("lastServer", serverName.toString()); 13 | } 14 | 15 | public static HostAndPort getLastServer() { 16 | return HostAndPort.fromString(preferences.get("lastServer", "")).withDefaultPort(PayFileClient.PORT); 17 | } 18 | 19 | public static void setLastPaidServer(HostAndPort serverName) { 20 | preferences.put("lastPaidServer", serverName.toString()); 21 | } 22 | 23 | public static HostAndPort getLastPaidServer() { 24 | final String str = preferences.get("lastPaidServer", ""); 25 | return str == null ? null : HostAndPort.fromString(str).withDefaultPort(PayFileClient.PORT); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/net/plan99/payfile/gui/utils/TextFieldValidator.java: -------------------------------------------------------------------------------- 1 | package net.plan99.payfile.gui.utils; 2 | 3 | import javafx.scene.Scene; 4 | import javafx.scene.control.TextField; 5 | 6 | import java.util.function.Predicate; 7 | 8 | public class TextFieldValidator { 9 | private boolean valid; 10 | 11 | public TextFieldValidator(TextField textField, Predicate validator) { 12 | this.valid = validator.test(textField.getText()); 13 | apply(textField, valid); 14 | textField.textProperty().addListener((observableValue, prev, current) -> { 15 | boolean nowValid = validator.test(current); 16 | if (nowValid == valid) return; 17 | apply(textField, nowValid); 18 | valid = nowValid; 19 | }); 20 | } 21 | 22 | private static void apply(TextField textField, boolean nowValid) { 23 | if (nowValid) { 24 | textField.getStyleClass().remove("validation_error"); 25 | } else { 26 | textField.getStyleClass().add("validation_error"); 27 | } 28 | } 29 | 30 | public static void configureScene(Scene scene) { 31 | final String file = TextFieldValidator.class.getResource("text-validation.css").toString(); 32 | scene.getStylesheets().add(file); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/net/plan99/payfile/gui/controls/bitcoin_address.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 29 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/main/resources/net/plan99/payfile/gui/connect_server.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 54 | 55 | 56 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/main/resources/net/plan99/payfile/gui/main.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 35 | 36 | 37 | 45 | 47 | 48 | 49 | 50 | 51 | 52 |