From 402cb8ae8df7f05584b7c7a0017003c7e3928ef5 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Mon, 22 Oct 2018 11:02:29 +0200 Subject: [PATCH 01/24] btcr-service-client --- .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + build.gradle | 17 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54413 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 172 ++++++++++++++++++ gradlew.bat | 84 +++++++++ settings.gradle | 2 + .../btcr_service_client/BTCRDIDResolver.java | 43 +++++ src/main/java/btcr_service_client/Decode.java | 17 ++ .../java/btcr_service_client/DecodedTx.java | 15 ++ .../btcr_service_client/ResolveBTCRDID.java | 18 ++ .../ServiceConnection.java | 32 ++++ src/main/java/btcr_service_client/Tip.java | 17 ++ .../btcr_service_client/TxIdFromTxRef.java | 17 ++ 16 files changed, 460 insertions(+) create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle create mode 100644 src/main/java/btcr_service_client/BTCRDIDResolver.java create mode 100644 src/main/java/btcr_service_client/Decode.java create mode 100644 src/main/java/btcr_service_client/DecodedTx.java create mode 100644 src/main/java/btcr_service_client/ResolveBTCRDID.java create mode 100644 src/main/java/btcr_service_client/ServiceConnection.java create mode 100644 src/main/java/btcr_service_client/Tip.java create mode 100644 src/main/java/btcr_service_client/TxIdFromTxRef.java diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..e32eceb --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..32aa7d9 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..bafbe18 --- /dev/null +++ b/build.gradle @@ -0,0 +1,17 @@ +plugins { + id 'java' +} + +group 'org.opdup' +version '1.0-SNAPSHOT' + +sourceCompatibility = 1.8 + +repositories { + mavenCentral() +} + +dependencies { + testCompile group: 'junit', name: 'junit', version: '4.12' + implementation "org.json:json:20180813" +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..1948b9074f1016d15d505d185bc3f73deb82d8c8 GIT binary patch literal 54413 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..f955316 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..a7d4341 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'btcr-service-client-java' + diff --git a/src/main/java/btcr_service_client/BTCRDIDResolver.java b/src/main/java/btcr_service_client/BTCRDIDResolver.java new file mode 100644 index 0000000..6b829ed --- /dev/null +++ b/src/main/java/btcr_service_client/BTCRDIDResolver.java @@ -0,0 +1,43 @@ +package btcr_service_client; + +import java.io.IOException; + +public class BTCRDIDResolver { + + private String brtcrDid; + private String txRef; + + public BTCRDIDResolver(String brtcrDid){ + this.brtcrDid = brtcrDid; + this.txRef = this.brtcrDid.substring(9); + } + + // Resolve BTCR DID + public String getBrtcrDidRes() throws IOException { + String url = "https://localhost:8080/txref/"+ this.txRef +"/resolve"; + ResolveBTCRDID resolveBTCRDID = new ResolveBTCRDID(url); + String btrdidRes = resolveBTCRDID.resolve(); + return btrdidRes; + } + + // Following a tip + public String getTip() throws IOException { + String url = "https://localhost:8080/txref"+ this.txRef +"/tip"; + return new Tip(url).getTip(); + } + + // Decode TxRef + public String decode() throws IOException { + String url = "https://localhost:8080/txref"+ this.txRef +"/decode"; + return new Decode(url).decode(); + } + + // Get TxId from TxRef + public String txIdFromTxref() throws IOException { + String url = "https://localhost:8080/txref"+ this.txRef +"/txid"; + return new TxIdFromTxRef(url).getTxIdFromTxRef(); + } + + // Get Decoded Tx from TxId + +} diff --git a/src/main/java/btcr_service_client/Decode.java b/src/main/java/btcr_service_client/Decode.java new file mode 100644 index 0000000..cb8c554 --- /dev/null +++ b/src/main/java/btcr_service_client/Decode.java @@ -0,0 +1,17 @@ +package btcr_service_client; + +import java.io.IOException; + +public class Decode { + + private String url; + + public Decode(String url){ + this.url = url; + } + + public String decode() throws IOException{ + return new ServiceConnection(this.url).getJson(); + } + +} diff --git a/src/main/java/btcr_service_client/DecodedTx.java b/src/main/java/btcr_service_client/DecodedTx.java new file mode 100644 index 0000000..c31ac22 --- /dev/null +++ b/src/main/java/btcr_service_client/DecodedTx.java @@ -0,0 +1,15 @@ +package btcr_service_client; + +import java.io.IOException; + +public class DecodedTx { + + private String url; + + public DecodedTx(String url){ + this.url = url; + } + + + +} diff --git a/src/main/java/btcr_service_client/ResolveBTCRDID.java b/src/main/java/btcr_service_client/ResolveBTCRDID.java new file mode 100644 index 0000000..cd0ff2a --- /dev/null +++ b/src/main/java/btcr_service_client/ResolveBTCRDID.java @@ -0,0 +1,18 @@ +package btcr_service_client; + +import java.io.IOException; + +public class ResolveBTCRDID { + + private String url; + + public ResolveBTCRDID(String url){ + this.url = url; + } + + public String resolve() throws IOException { + ServiceConnection serviceConnection = new ServiceConnection(this.url); + return serviceConnection.getJson(); + } + +} diff --git a/src/main/java/btcr_service_client/ServiceConnection.java b/src/main/java/btcr_service_client/ServiceConnection.java new file mode 100644 index 0000000..dbfc067 --- /dev/null +++ b/src/main/java/btcr_service_client/ServiceConnection.java @@ -0,0 +1,32 @@ +package btcr_service_client; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Scanner; + +public class ServiceConnection { + + private String urlStr; + + public ServiceConnection(String url){ + this.urlStr = url; + } + + public String getJson() throws IOException { + String json = null; + URL url = new URL(this.urlStr); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setDoOutput(true); + connection.setInstanceFollowRedirects(false); + connection.setRequestMethod("GET"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("charset", "utf-8"); + connection.connect(); + InputStream inputStream = connection.getInputStream(); + json = new Scanner(inputStream, "UTF-8").useDelimiter("\\Z").next(); + return json; + } + +} diff --git a/src/main/java/btcr_service_client/Tip.java b/src/main/java/btcr_service_client/Tip.java new file mode 100644 index 0000000..868e26e --- /dev/null +++ b/src/main/java/btcr_service_client/Tip.java @@ -0,0 +1,17 @@ +package btcr_service_client; + +import java.io.IOException; + +public class Tip { + + private String url; + + public Tip(String url){ + this.url = url; + } + + public String getTip() throws IOException{ + return new ServiceConnection(this.url).getJson(); + } + +} diff --git a/src/main/java/btcr_service_client/TxIdFromTxRef.java b/src/main/java/btcr_service_client/TxIdFromTxRef.java new file mode 100644 index 0000000..d90237a --- /dev/null +++ b/src/main/java/btcr_service_client/TxIdFromTxRef.java @@ -0,0 +1,17 @@ +package btcr_service_client; + +import java.io.IOException; + +public class TxIdFromTxRef { + + private String url; + + public TxIdFromTxRef(String url){ + this.url = url; + } + + public String getTxIdFromTxRef() throws IOException{ + return new ServiceConnection(this.url).getJson(); + } + +} From a7a2b969ffd7ddc601801140f665912cd5712c78 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Mon, 22 Oct 2018 11:04:49 +0200 Subject: [PATCH 02/24] btcr-service-client --- .idea/modules.xml | 2 ++ .idea/vcs.xml | 1 + 2 files changed, 3 insertions(+) diff --git a/.idea/modules.xml b/.idea/modules.xml index 32aa7d9..c74f48e 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -3,6 +3,8 @@ + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 35eb1dd..8306744 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -2,5 +2,6 @@ + \ No newline at end of file From f4c874f1b743e2fc4757ca9cc65215446a0470c7 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Fri, 26 Oct 2018 10:16:53 +0200 Subject: [PATCH 03/24] btcr-service-client --- .idea/compiler.xml | 9 +++++ .../btcr_service_client/BTCRDIDResolver.java | 10 +++++ src/main/java/btcr_service_client/Decode.java | 4 +- .../java/btcr_service_client/DecodedTx.java | 7 +++- .../btcr_service_client/ResolveBTCRDID.java | 4 +- .../ServiceConnection.java | 37 ++++++++++++------- src/main/java/btcr_service_client/Tip.java | 4 +- .../btcr_service_client/TxIdFromTxRef.java | 13 ++++++- .../java/btcr_service_client/txidToUTXOs.java | 7 ++++ src/test/java/TestBTCRDIDResolver.java | 10 +++++ 10 files changed, 83 insertions(+), 22 deletions(-) create mode 100644 .idea/compiler.xml create mode 100644 src/main/java/btcr_service_client/txidToUTXOs.java create mode 100644 src/test/java/TestBTCRDIDResolver.java diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..8caef52 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/btcr_service_client/BTCRDIDResolver.java b/src/main/java/btcr_service_client/BTCRDIDResolver.java index 6b829ed..90f5dc5 100644 --- a/src/main/java/btcr_service_client/BTCRDIDResolver.java +++ b/src/main/java/btcr_service_client/BTCRDIDResolver.java @@ -39,5 +39,15 @@ public String txIdFromTxref() throws IOException { } // Get Decoded Tx from TxId + public String getDecodedTx() throws IOException { + String txId = txIdFromTxref(); + String url = "https://localhost:8080/tx"+ txId; + return new DecodedTx(url).getTxFromTxId(); + } + + //Txid to Utxos for the address in Txid + public String getUtxos() throws IOException { + //how to get the address??? + } } diff --git a/src/main/java/btcr_service_client/Decode.java b/src/main/java/btcr_service_client/Decode.java index cb8c554..d79804a 100644 --- a/src/main/java/btcr_service_client/Decode.java +++ b/src/main/java/btcr_service_client/Decode.java @@ -11,7 +11,7 @@ public Decode(String url){ } public String decode() throws IOException{ - return new ServiceConnection(this.url).getJson(); + return new ServiceConnection(this.url).getJsonString(); } -} +} \ No newline at end of file diff --git a/src/main/java/btcr_service_client/DecodedTx.java b/src/main/java/btcr_service_client/DecodedTx.java index c31ac22..066967d 100644 --- a/src/main/java/btcr_service_client/DecodedTx.java +++ b/src/main/java/btcr_service_client/DecodedTx.java @@ -2,6 +2,8 @@ import java.io.IOException; +import org.json.JSONObject; + public class DecodedTx { private String url; @@ -10,6 +12,9 @@ public DecodedTx(String url){ this.url = url; } - + public String getTxFromTxId() throws IOException{ + ServiceConnection serviceConnection = new ServiceConnection(this.url); + return serviceConnection.getJsonString(); + } } diff --git a/src/main/java/btcr_service_client/ResolveBTCRDID.java b/src/main/java/btcr_service_client/ResolveBTCRDID.java index cd0ff2a..c81839d 100644 --- a/src/main/java/btcr_service_client/ResolveBTCRDID.java +++ b/src/main/java/btcr_service_client/ResolveBTCRDID.java @@ -12,7 +12,7 @@ public ResolveBTCRDID(String url){ public String resolve() throws IOException { ServiceConnection serviceConnection = new ServiceConnection(this.url); - return serviceConnection.getJson(); + return serviceConnection.getJsonString(); } -} +} \ No newline at end of file diff --git a/src/main/java/btcr_service_client/ServiceConnection.java b/src/main/java/btcr_service_client/ServiceConnection.java index dbfc067..4c6a078 100644 --- a/src/main/java/btcr_service_client/ServiceConnection.java +++ b/src/main/java/btcr_service_client/ServiceConnection.java @@ -1,5 +1,7 @@ package btcr_service_client; +import org.json.JSONObject; + import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; @@ -8,25 +10,34 @@ public class ServiceConnection { - private String urlStr; + private URL url; + private HttpURLConnection connection; + + public ServiceConnection(String url) throws IOException{ + String urlStr = url; + this.url = new URL(urlStr); + } - public ServiceConnection(String url){ - this.urlStr = url; + public void connect() throws IOException { + this.connection = (HttpURLConnection) this.url.openConnection(); + this.connection.setDoOutput(true); + this.connection.setInstanceFollowRedirects(false); + this.connection.setRequestMethod("GET"); + this.connection.setRequestProperty("Content-Type", "application/json"); + this.connection.setRequestProperty("charset", "utf-8"); + this.connection.connect(); } - public String getJson() throws IOException { + public String getJsonString() throws IOException { String json = null; - URL url = new URL(this.urlStr); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setDoOutput(true); - connection.setInstanceFollowRedirects(false); - connection.setRequestMethod("GET"); - connection.setRequestProperty("Content-Type", "application/json"); - connection.setRequestProperty("charset", "utf-8"); - connection.connect(); + connect(); InputStream inputStream = connection.getInputStream(); json = new Scanner(inputStream, "UTF-8").useDelimiter("\\Z").next(); return json; } -} + public JSONObject getJsonObject() throws IOException { + return new JSONObject(getJsonString()); + } + +} \ No newline at end of file diff --git a/src/main/java/btcr_service_client/Tip.java b/src/main/java/btcr_service_client/Tip.java index 868e26e..45b3d30 100644 --- a/src/main/java/btcr_service_client/Tip.java +++ b/src/main/java/btcr_service_client/Tip.java @@ -11,7 +11,7 @@ public Tip(String url){ } public String getTip() throws IOException{ - return new ServiceConnection(this.url).getJson(); + return new ServiceConnection(this.url).getJsonString(); } -} +} \ No newline at end of file diff --git a/src/main/java/btcr_service_client/TxIdFromTxRef.java b/src/main/java/btcr_service_client/TxIdFromTxRef.java index d90237a..b8b1e30 100644 --- a/src/main/java/btcr_service_client/TxIdFromTxRef.java +++ b/src/main/java/btcr_service_client/TxIdFromTxRef.java @@ -1,5 +1,8 @@ package btcr_service_client; +import org.json.JSONArray; +import org.json.JSONObject; + import java.io.IOException; public class TxIdFromTxRef { @@ -11,7 +14,13 @@ public TxIdFromTxRef(String url){ } public String getTxIdFromTxRef() throws IOException{ - return new ServiceConnection(this.url).getJson(); + String jsonString = new ServiceConnection(this.url).getJsonString(); + JSONObject jsonObject = new JSONObject(jsonString); + String txid = null; + if (jsonObject!=null){ + txid = jsonObject.getString("txid"); + } + return txid; } -} +} \ No newline at end of file diff --git a/src/main/java/btcr_service_client/txidToUTXOs.java b/src/main/java/btcr_service_client/txidToUTXOs.java new file mode 100644 index 0000000..94054a2 --- /dev/null +++ b/src/main/java/btcr_service_client/txidToUTXOs.java @@ -0,0 +1,7 @@ +package btcr_service_client; + +public class txidToUTXOs { + + + +} diff --git a/src/test/java/TestBTCRDIDResolver.java b/src/test/java/TestBTCRDIDResolver.java new file mode 100644 index 0000000..e2fbe53 --- /dev/null +++ b/src/test/java/TestBTCRDIDResolver.java @@ -0,0 +1,10 @@ +import btcr_service_client.BTCRDIDResolver; + +public class TestBTCRDIDResolver { + + public static void main(String[] args) { + String btcrDid=""; + BTCRDIDResolver resolver = new BTCRDIDResolver(btcrDid); + } + +} From 5928ba3a2026018e298698c19383ed90360ae027 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Fri, 26 Oct 2018 10:19:55 +0200 Subject: [PATCH 04/24] btcr-service-client --- src/main/java/btcr_service_client/BTCRDIDResolver.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/btcr_service_client/BTCRDIDResolver.java b/src/main/java/btcr_service_client/BTCRDIDResolver.java index 90f5dc5..0086c5a 100644 --- a/src/main/java/btcr_service_client/BTCRDIDResolver.java +++ b/src/main/java/btcr_service_client/BTCRDIDResolver.java @@ -48,6 +48,7 @@ public String getDecodedTx() throws IOException { //Txid to Utxos for the address in Txid public String getUtxos() throws IOException { //how to get the address??? + return ""; } } From e665b115ca7d58ba3a12b204e9f260f0fc66b0a2 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Fri, 26 Oct 2018 10:31:44 +0200 Subject: [PATCH 05/24] Add files via upload --- BTCRDIDResolver.java | 54 ++++++++++++++++++++++++++++++++++++++++++ Decode.java | 17 +++++++++++++ DecodedTx.java | 20 ++++++++++++++++ ResolveBTCRDID.java | 18 ++++++++++++++ ServiceConnection.java | 43 +++++++++++++++++++++++++++++++++ Tip.java | 17 +++++++++++++ TxIdFromTxRef.java | 26 ++++++++++++++++++++ txidToUTXOs.java | 7 ++++++ 8 files changed, 202 insertions(+) create mode 100644 BTCRDIDResolver.java create mode 100644 Decode.java create mode 100644 DecodedTx.java create mode 100644 ResolveBTCRDID.java create mode 100644 ServiceConnection.java create mode 100644 Tip.java create mode 100644 TxIdFromTxRef.java create mode 100644 txidToUTXOs.java diff --git a/BTCRDIDResolver.java b/BTCRDIDResolver.java new file mode 100644 index 0000000..0086c5a --- /dev/null +++ b/BTCRDIDResolver.java @@ -0,0 +1,54 @@ +package btcr_service_client; + +import java.io.IOException; + +public class BTCRDIDResolver { + + private String brtcrDid; + private String txRef; + + public BTCRDIDResolver(String brtcrDid){ + this.brtcrDid = brtcrDid; + this.txRef = this.brtcrDid.substring(9); + } + + // Resolve BTCR DID + public String getBrtcrDidRes() throws IOException { + String url = "https://localhost:8080/txref/"+ this.txRef +"/resolve"; + ResolveBTCRDID resolveBTCRDID = new ResolveBTCRDID(url); + String btrdidRes = resolveBTCRDID.resolve(); + return btrdidRes; + } + + // Following a tip + public String getTip() throws IOException { + String url = "https://localhost:8080/txref"+ this.txRef +"/tip"; + return new Tip(url).getTip(); + } + + // Decode TxRef + public String decode() throws IOException { + String url = "https://localhost:8080/txref"+ this.txRef +"/decode"; + return new Decode(url).decode(); + } + + // Get TxId from TxRef + public String txIdFromTxref() throws IOException { + String url = "https://localhost:8080/txref"+ this.txRef +"/txid"; + return new TxIdFromTxRef(url).getTxIdFromTxRef(); + } + + // Get Decoded Tx from TxId + public String getDecodedTx() throws IOException { + String txId = txIdFromTxref(); + String url = "https://localhost:8080/tx"+ txId; + return new DecodedTx(url).getTxFromTxId(); + } + + //Txid to Utxos for the address in Txid + public String getUtxos() throws IOException { + //how to get the address??? + return ""; + } + +} diff --git a/Decode.java b/Decode.java new file mode 100644 index 0000000..d79804a --- /dev/null +++ b/Decode.java @@ -0,0 +1,17 @@ +package btcr_service_client; + +import java.io.IOException; + +public class Decode { + + private String url; + + public Decode(String url){ + this.url = url; + } + + public String decode() throws IOException{ + return new ServiceConnection(this.url).getJsonString(); + } + +} \ No newline at end of file diff --git a/DecodedTx.java b/DecodedTx.java new file mode 100644 index 0000000..066967d --- /dev/null +++ b/DecodedTx.java @@ -0,0 +1,20 @@ +package btcr_service_client; + +import java.io.IOException; + +import org.json.JSONObject; + +public class DecodedTx { + + private String url; + + public DecodedTx(String url){ + this.url = url; + } + + public String getTxFromTxId() throws IOException{ + ServiceConnection serviceConnection = new ServiceConnection(this.url); + return serviceConnection.getJsonString(); + } + +} diff --git a/ResolveBTCRDID.java b/ResolveBTCRDID.java new file mode 100644 index 0000000..c81839d --- /dev/null +++ b/ResolveBTCRDID.java @@ -0,0 +1,18 @@ +package btcr_service_client; + +import java.io.IOException; + +public class ResolveBTCRDID { + + private String url; + + public ResolveBTCRDID(String url){ + this.url = url; + } + + public String resolve() throws IOException { + ServiceConnection serviceConnection = new ServiceConnection(this.url); + return serviceConnection.getJsonString(); + } + +} \ No newline at end of file diff --git a/ServiceConnection.java b/ServiceConnection.java new file mode 100644 index 0000000..4c6a078 --- /dev/null +++ b/ServiceConnection.java @@ -0,0 +1,43 @@ +package btcr_service_client; + +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.Scanner; + +public class ServiceConnection { + + private URL url; + private HttpURLConnection connection; + + public ServiceConnection(String url) throws IOException{ + String urlStr = url; + this.url = new URL(urlStr); + } + + public void connect() throws IOException { + this.connection = (HttpURLConnection) this.url.openConnection(); + this.connection.setDoOutput(true); + this.connection.setInstanceFollowRedirects(false); + this.connection.setRequestMethod("GET"); + this.connection.setRequestProperty("Content-Type", "application/json"); + this.connection.setRequestProperty("charset", "utf-8"); + this.connection.connect(); + } + + public String getJsonString() throws IOException { + String json = null; + connect(); + InputStream inputStream = connection.getInputStream(); + json = new Scanner(inputStream, "UTF-8").useDelimiter("\\Z").next(); + return json; + } + + public JSONObject getJsonObject() throws IOException { + return new JSONObject(getJsonString()); + } + +} \ No newline at end of file diff --git a/Tip.java b/Tip.java new file mode 100644 index 0000000..45b3d30 --- /dev/null +++ b/Tip.java @@ -0,0 +1,17 @@ +package btcr_service_client; + +import java.io.IOException; + +public class Tip { + + private String url; + + public Tip(String url){ + this.url = url; + } + + public String getTip() throws IOException{ + return new ServiceConnection(this.url).getJsonString(); + } + +} \ No newline at end of file diff --git a/TxIdFromTxRef.java b/TxIdFromTxRef.java new file mode 100644 index 0000000..b8b1e30 --- /dev/null +++ b/TxIdFromTxRef.java @@ -0,0 +1,26 @@ +package btcr_service_client; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.IOException; + +public class TxIdFromTxRef { + + private String url; + + public TxIdFromTxRef(String url){ + this.url = url; + } + + public String getTxIdFromTxRef() throws IOException{ + String jsonString = new ServiceConnection(this.url).getJsonString(); + JSONObject jsonObject = new JSONObject(jsonString); + String txid = null; + if (jsonObject!=null){ + txid = jsonObject.getString("txid"); + } + return txid; + } + +} \ No newline at end of file diff --git a/txidToUTXOs.java b/txidToUTXOs.java new file mode 100644 index 0000000..94054a2 --- /dev/null +++ b/txidToUTXOs.java @@ -0,0 +1,7 @@ +package btcr_service_client; + +public class txidToUTXOs { + + + +} From 64821266e772d6cf692f9956731723d071bb072b Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Fri, 26 Oct 2018 10:53:19 +0200 Subject: [PATCH 06/24] btcr-service-client --- src/test/java/TestBTCRDIDResolver.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/test/java/TestBTCRDIDResolver.java b/src/test/java/TestBTCRDIDResolver.java index e2fbe53..c1810fe 100644 --- a/src/test/java/TestBTCRDIDResolver.java +++ b/src/test/java/TestBTCRDIDResolver.java @@ -1,10 +1,17 @@ import btcr_service_client.BTCRDIDResolver; +import java.io.IOException; + public class TestBTCRDIDResolver { - public static void main(String[] args) { + public static void main(String[] args) throws IOException { String btcrDid=""; BTCRDIDResolver resolver = new BTCRDIDResolver(btcrDid); + System.out.println("Resolve BTCR DID\n" + resolver.getBrtcrDidRes()); + System.out.println("\n\nFollowing a Tip\n" + resolver.getTip()); + System.out.println("\n\nDecode a Txref\n" + resolver.decode()); + System.out.println("\n\nGet Txid from Txref\n" + resolver.txIdFromTxref()); + System.out.println("\n\nGet decoded Tx from Txid" + resolver.getDecodedTx()); } } From 93ff35f3a7a569df21ec32c266ecea40f33cbba3 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Fri, 26 Oct 2018 10:56:23 +0200 Subject: [PATCH 07/24] Add files via upload --- TestBTCRDIDResolver.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 TestBTCRDIDResolver.java diff --git a/TestBTCRDIDResolver.java b/TestBTCRDIDResolver.java new file mode 100644 index 0000000..c1810fe --- /dev/null +++ b/TestBTCRDIDResolver.java @@ -0,0 +1,17 @@ +import btcr_service_client.BTCRDIDResolver; + +import java.io.IOException; + +public class TestBTCRDIDResolver { + + public static void main(String[] args) throws IOException { + String btcrDid=""; + BTCRDIDResolver resolver = new BTCRDIDResolver(btcrDid); + System.out.println("Resolve BTCR DID\n" + resolver.getBrtcrDidRes()); + System.out.println("\n\nFollowing a Tip\n" + resolver.getTip()); + System.out.println("\n\nDecode a Txref\n" + resolver.decode()); + System.out.println("\n\nGet Txid from Txref\n" + resolver.txIdFromTxref()); + System.out.println("\n\nGet decoded Tx from Txid" + resolver.getDecodedTx()); + } + +} From 936f2f3da66c04bcbdaedb4cc03037478dc8e411 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Sat, 27 Oct 2018 09:30:30 +0200 Subject: [PATCH 08/24] btcr-service-client --- .../btcr_service_client/BTCRDIDResolver.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/btcr_service_client/BTCRDIDResolver.java b/src/main/java/btcr_service_client/BTCRDIDResolver.java index 0086c5a..adb9ccf 100644 --- a/src/main/java/btcr_service_client/BTCRDIDResolver.java +++ b/src/main/java/btcr_service_client/BTCRDIDResolver.java @@ -1,5 +1,6 @@ package btcr_service_client; +import java.awt.*; import java.io.IOException; public class BTCRDIDResolver { @@ -7,6 +8,10 @@ public class BTCRDIDResolver { private String brtcrDid; private String txRef; + private String PROTOCOL = "https://"; + private String ADDRESS = "localhost"; + private String PORT = "8080"; + public BTCRDIDResolver(String brtcrDid){ this.brtcrDid = brtcrDid; this.txRef = this.brtcrDid.substring(9); @@ -14,34 +19,32 @@ public BTCRDIDResolver(String brtcrDid){ // Resolve BTCR DID public String getBrtcrDidRes() throws IOException { - String url = "https://localhost:8080/txref/"+ this.txRef +"/resolve"; - ResolveBTCRDID resolveBTCRDID = new ResolveBTCRDID(url); - String btrdidRes = resolveBTCRDID.resolve(); - return btrdidRes; + String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/resolve"; + return new ResolveBTCRDID(url).resolve(); } // Following a tip public String getTip() throws IOException { - String url = "https://localhost:8080/txref"+ this.txRef +"/tip"; + String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/tip"; return new Tip(url).getTip(); } // Decode TxRef public String decode() throws IOException { - String url = "https://localhost:8080/txref"+ this.txRef +"/decode"; + String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/decode"; return new Decode(url).decode(); } // Get TxId from TxRef public String txIdFromTxref() throws IOException { - String url = "https://localhost:8080/txref"+ this.txRef +"/txid"; + String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/txid"; return new TxIdFromTxRef(url).getTxIdFromTxRef(); } // Get Decoded Tx from TxId public String getDecodedTx() throws IOException { String txId = txIdFromTxref(); - String url = "https://localhost:8080/tx"+ txId; + String url = PROTOCOL + ADDRESS + ":" + PORT + "/tx" + txId; return new DecodedTx(url).getTxFromTxId(); } From 9a07d3f9fff1c96043cf3cffb28b8b7dd236bbd9 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Sat, 27 Oct 2018 15:56:41 +0200 Subject: [PATCH 09/24] Add files via upload --- BTCRDIDResolver.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/BTCRDIDResolver.java b/BTCRDIDResolver.java index 0086c5a..adb9ccf 100644 --- a/BTCRDIDResolver.java +++ b/BTCRDIDResolver.java @@ -1,5 +1,6 @@ package btcr_service_client; +import java.awt.*; import java.io.IOException; public class BTCRDIDResolver { @@ -7,6 +8,10 @@ public class BTCRDIDResolver { private String brtcrDid; private String txRef; + private String PROTOCOL = "https://"; + private String ADDRESS = "localhost"; + private String PORT = "8080"; + public BTCRDIDResolver(String brtcrDid){ this.brtcrDid = brtcrDid; this.txRef = this.brtcrDid.substring(9); @@ -14,34 +19,32 @@ public BTCRDIDResolver(String brtcrDid){ // Resolve BTCR DID public String getBrtcrDidRes() throws IOException { - String url = "https://localhost:8080/txref/"+ this.txRef +"/resolve"; - ResolveBTCRDID resolveBTCRDID = new ResolveBTCRDID(url); - String btrdidRes = resolveBTCRDID.resolve(); - return btrdidRes; + String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/resolve"; + return new ResolveBTCRDID(url).resolve(); } // Following a tip public String getTip() throws IOException { - String url = "https://localhost:8080/txref"+ this.txRef +"/tip"; + String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/tip"; return new Tip(url).getTip(); } // Decode TxRef public String decode() throws IOException { - String url = "https://localhost:8080/txref"+ this.txRef +"/decode"; + String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/decode"; return new Decode(url).decode(); } // Get TxId from TxRef public String txIdFromTxref() throws IOException { - String url = "https://localhost:8080/txref"+ this.txRef +"/txid"; + String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/txid"; return new TxIdFromTxRef(url).getTxIdFromTxRef(); } // Get Decoded Tx from TxId public String getDecodedTx() throws IOException { String txId = txIdFromTxref(); - String url = "https://localhost:8080/tx"+ txId; + String url = PROTOCOL + ADDRESS + ":" + PORT + "/tx" + txId; return new DecodedTx(url).getTxFromTxId(); } From fd8bef0adb7b2568947731f6b890af952d75b8e2 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Fri, 2 Nov 2018 10:22:26 +0100 Subject: [PATCH 10/24] btcr-service-client --- gradlew.bat | 168 +++++++++--------- .../btcr_service_client/BTCRDIDResolver.java | 5 +- .../java/btcr_service_client/TxidToUTXOs.java | 11 ++ 3 files changed, 99 insertions(+), 85 deletions(-) create mode 100644 src/main/java/btcr_service_client/TxidToUTXOs.java diff --git a/gradlew.bat b/gradlew.bat index f955316..e95643d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,84 +1,84 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/btcr_service_client/BTCRDIDResolver.java b/src/main/java/btcr_service_client/BTCRDIDResolver.java index adb9ccf..dda5b5c 100644 --- a/src/main/java/btcr_service_client/BTCRDIDResolver.java +++ b/src/main/java/btcr_service_client/BTCRDIDResolver.java @@ -50,7 +50,10 @@ public String getDecodedTx() throws IOException { //Txid to Utxos for the address in Txid public String getUtxos() throws IOException { - //how to get the address??? + String txId = txIdFromTxref(); + String addr = ""; + String url = PROTOCOL + ADDRESS + ":" + PORT + "/addr/" + addr + "/spends"; + String utxo = ""; return ""; } diff --git a/src/main/java/btcr_service_client/TxidToUTXOs.java b/src/main/java/btcr_service_client/TxidToUTXOs.java new file mode 100644 index 0000000..44c3ace --- /dev/null +++ b/src/main/java/btcr_service_client/TxidToUTXOs.java @@ -0,0 +1,11 @@ +package btcr_service_client; + +public class TxidToUTXOs { + + private String url; + + public TxidToUTXOs(String url){ + this.url = url; + } + +} From cfde89d09eed224604d098e9f60f65c68f44fc90 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Tue, 6 Nov 2018 18:14:32 +0100 Subject: [PATCH 11/24] added tests --- .../java/btcr_service_client/TxidToUTXOs.java | 6 +----- .../java/btcr_service_client/txidToUTXOs.java | 7 ------- src/test/java/TestBTCRDIDResolver.java | 17 ----------------- 3 files changed, 1 insertion(+), 29 deletions(-) delete mode 100644 src/main/java/btcr_service_client/txidToUTXOs.java delete mode 100644 src/test/java/TestBTCRDIDResolver.java diff --git a/src/main/java/btcr_service_client/TxidToUTXOs.java b/src/main/java/btcr_service_client/TxidToUTXOs.java index 44c3ace..94054a2 100644 --- a/src/main/java/btcr_service_client/TxidToUTXOs.java +++ b/src/main/java/btcr_service_client/TxidToUTXOs.java @@ -1,11 +1,7 @@ package btcr_service_client; -public class TxidToUTXOs { +public class txidToUTXOs { - private String url; - public TxidToUTXOs(String url){ - this.url = url; - } } diff --git a/src/main/java/btcr_service_client/txidToUTXOs.java b/src/main/java/btcr_service_client/txidToUTXOs.java deleted file mode 100644 index 94054a2..0000000 --- a/src/main/java/btcr_service_client/txidToUTXOs.java +++ /dev/null @@ -1,7 +0,0 @@ -package btcr_service_client; - -public class txidToUTXOs { - - - -} diff --git a/src/test/java/TestBTCRDIDResolver.java b/src/test/java/TestBTCRDIDResolver.java deleted file mode 100644 index c1810fe..0000000 --- a/src/test/java/TestBTCRDIDResolver.java +++ /dev/null @@ -1,17 +0,0 @@ -import btcr_service_client.BTCRDIDResolver; - -import java.io.IOException; - -public class TestBTCRDIDResolver { - - public static void main(String[] args) throws IOException { - String btcrDid=""; - BTCRDIDResolver resolver = new BTCRDIDResolver(btcrDid); - System.out.println("Resolve BTCR DID\n" + resolver.getBrtcrDidRes()); - System.out.println("\n\nFollowing a Tip\n" + resolver.getTip()); - System.out.println("\n\nDecode a Txref\n" + resolver.decode()); - System.out.println("\n\nGet Txid from Txref\n" + resolver.txIdFromTxref()); - System.out.println("\n\nGet decoded Tx from Txid" + resolver.getDecodedTx()); - } - -} From 5cd68e1cfcfc73f50efceeb69d8dd13ed392d184 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Tue, 6 Nov 2018 18:25:46 +0100 Subject: [PATCH 12/24] deleted files --- BTCRDIDResolver.java | 57 ---------------------------------------- Decode.java | 17 ------------ DecodedTx.java | 20 -------------- ResolveBTCRDID.java | 18 ------------- ServiceConnection.java | 43 ------------------------------ TestBTCRDIDResolver.java | 17 ------------ Tip.java | 17 ------------ TxIdFromTxRef.java | 26 ------------------ 8 files changed, 215 deletions(-) delete mode 100644 BTCRDIDResolver.java delete mode 100644 Decode.java delete mode 100644 DecodedTx.java delete mode 100644 ResolveBTCRDID.java delete mode 100644 ServiceConnection.java delete mode 100644 TestBTCRDIDResolver.java delete mode 100644 Tip.java delete mode 100644 TxIdFromTxRef.java diff --git a/BTCRDIDResolver.java b/BTCRDIDResolver.java deleted file mode 100644 index adb9ccf..0000000 --- a/BTCRDIDResolver.java +++ /dev/null @@ -1,57 +0,0 @@ -package btcr_service_client; - -import java.awt.*; -import java.io.IOException; - -public class BTCRDIDResolver { - - private String brtcrDid; - private String txRef; - - private String PROTOCOL = "https://"; - private String ADDRESS = "localhost"; - private String PORT = "8080"; - - public BTCRDIDResolver(String brtcrDid){ - this.brtcrDid = brtcrDid; - this.txRef = this.brtcrDid.substring(9); - } - - // Resolve BTCR DID - public String getBrtcrDidRes() throws IOException { - String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/resolve"; - return new ResolveBTCRDID(url).resolve(); - } - - // Following a tip - public String getTip() throws IOException { - String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/tip"; - return new Tip(url).getTip(); - } - - // Decode TxRef - public String decode() throws IOException { - String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/decode"; - return new Decode(url).decode(); - } - - // Get TxId from TxRef - public String txIdFromTxref() throws IOException { - String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/txid"; - return new TxIdFromTxRef(url).getTxIdFromTxRef(); - } - - // Get Decoded Tx from TxId - public String getDecodedTx() throws IOException { - String txId = txIdFromTxref(); - String url = PROTOCOL + ADDRESS + ":" + PORT + "/tx" + txId; - return new DecodedTx(url).getTxFromTxId(); - } - - //Txid to Utxos for the address in Txid - public String getUtxos() throws IOException { - //how to get the address??? - return ""; - } - -} diff --git a/Decode.java b/Decode.java deleted file mode 100644 index d79804a..0000000 --- a/Decode.java +++ /dev/null @@ -1,17 +0,0 @@ -package btcr_service_client; - -import java.io.IOException; - -public class Decode { - - private String url; - - public Decode(String url){ - this.url = url; - } - - public String decode() throws IOException{ - return new ServiceConnection(this.url).getJsonString(); - } - -} \ No newline at end of file diff --git a/DecodedTx.java b/DecodedTx.java deleted file mode 100644 index 066967d..0000000 --- a/DecodedTx.java +++ /dev/null @@ -1,20 +0,0 @@ -package btcr_service_client; - -import java.io.IOException; - -import org.json.JSONObject; - -public class DecodedTx { - - private String url; - - public DecodedTx(String url){ - this.url = url; - } - - public String getTxFromTxId() throws IOException{ - ServiceConnection serviceConnection = new ServiceConnection(this.url); - return serviceConnection.getJsonString(); - } - -} diff --git a/ResolveBTCRDID.java b/ResolveBTCRDID.java deleted file mode 100644 index c81839d..0000000 --- a/ResolveBTCRDID.java +++ /dev/null @@ -1,18 +0,0 @@ -package btcr_service_client; - -import java.io.IOException; - -public class ResolveBTCRDID { - - private String url; - - public ResolveBTCRDID(String url){ - this.url = url; - } - - public String resolve() throws IOException { - ServiceConnection serviceConnection = new ServiceConnection(this.url); - return serviceConnection.getJsonString(); - } - -} \ No newline at end of file diff --git a/ServiceConnection.java b/ServiceConnection.java deleted file mode 100644 index 4c6a078..0000000 --- a/ServiceConnection.java +++ /dev/null @@ -1,43 +0,0 @@ -package btcr_service_client; - -import org.json.JSONObject; - -import java.io.IOException; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.Scanner; - -public class ServiceConnection { - - private URL url; - private HttpURLConnection connection; - - public ServiceConnection(String url) throws IOException{ - String urlStr = url; - this.url = new URL(urlStr); - } - - public void connect() throws IOException { - this.connection = (HttpURLConnection) this.url.openConnection(); - this.connection.setDoOutput(true); - this.connection.setInstanceFollowRedirects(false); - this.connection.setRequestMethod("GET"); - this.connection.setRequestProperty("Content-Type", "application/json"); - this.connection.setRequestProperty("charset", "utf-8"); - this.connection.connect(); - } - - public String getJsonString() throws IOException { - String json = null; - connect(); - InputStream inputStream = connection.getInputStream(); - json = new Scanner(inputStream, "UTF-8").useDelimiter("\\Z").next(); - return json; - } - - public JSONObject getJsonObject() throws IOException { - return new JSONObject(getJsonString()); - } - -} \ No newline at end of file diff --git a/TestBTCRDIDResolver.java b/TestBTCRDIDResolver.java deleted file mode 100644 index c1810fe..0000000 --- a/TestBTCRDIDResolver.java +++ /dev/null @@ -1,17 +0,0 @@ -import btcr_service_client.BTCRDIDResolver; - -import java.io.IOException; - -public class TestBTCRDIDResolver { - - public static void main(String[] args) throws IOException { - String btcrDid=""; - BTCRDIDResolver resolver = new BTCRDIDResolver(btcrDid); - System.out.println("Resolve BTCR DID\n" + resolver.getBrtcrDidRes()); - System.out.println("\n\nFollowing a Tip\n" + resolver.getTip()); - System.out.println("\n\nDecode a Txref\n" + resolver.decode()); - System.out.println("\n\nGet Txid from Txref\n" + resolver.txIdFromTxref()); - System.out.println("\n\nGet decoded Tx from Txid" + resolver.getDecodedTx()); - } - -} diff --git a/Tip.java b/Tip.java deleted file mode 100644 index 45b3d30..0000000 --- a/Tip.java +++ /dev/null @@ -1,17 +0,0 @@ -package btcr_service_client; - -import java.io.IOException; - -public class Tip { - - private String url; - - public Tip(String url){ - this.url = url; - } - - public String getTip() throws IOException{ - return new ServiceConnection(this.url).getJsonString(); - } - -} \ No newline at end of file diff --git a/TxIdFromTxRef.java b/TxIdFromTxRef.java deleted file mode 100644 index b8b1e30..0000000 --- a/TxIdFromTxRef.java +++ /dev/null @@ -1,26 +0,0 @@ -package btcr_service_client; - -import org.json.JSONArray; -import org.json.JSONObject; - -import java.io.IOException; - -public class TxIdFromTxRef { - - private String url; - - public TxIdFromTxRef(String url){ - this.url = url; - } - - public String getTxIdFromTxRef() throws IOException{ - String jsonString = new ServiceConnection(this.url).getJsonString(); - JSONObject jsonObject = new JSONObject(jsonString); - String txid = null; - if (jsonObject!=null){ - txid = jsonObject.getString("txid"); - } - return txid; - } - -} \ No newline at end of file From fca34f2026179f20e98b2bd229b7ba630a034006 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Tue, 6 Nov 2018 18:27:07 +0100 Subject: [PATCH 13/24] added tests --- src/test/.DS_Store | Bin 0 -> 6148 bytes .../BTCRDIDResolverTest.java | 48 ++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 src/test/.DS_Store create mode 100644 src/test/java/btcr_service_client/BTCRDIDResolverTest.java diff --git a/src/test/.DS_Store b/src/test/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c38abe608bd908e6875d993d6b6cd2338bf362ef GIT binary patch literal 6148 zcmeHK&2G~`5S~o~T?Zj@sMH>PsnkObDXE$RLbB3w=&h0wJpgL$CZa~hTg6TzNQ3+u z@CJR9K0zM`zS&)({=gL?G$YM^v$Hd6@3+>jhltc*GTbI=6Oo28HUc!i5guoKAPw(n z0u|43kekyqH!1o&p~&(xz z#!BOrpN8IJyTRkR*c3r zIU9};^6n@rhGsf2lVVufd15!9b)bXe_Qq_s)9-b{-t*mgC!F>B-A=gE+nvt?y}r5q z^5Ept=P$F%`PXl5FBCphE6+Usg6}XE3%rQOMQ(}@@Ns-VV;WIOh9%0FZwpt-!Xw{=kqO zz{q3m5FUtfsX&*ie2Jla<)BnJJ9O!!?2|E%f3orwit>er3T-&4$f2~tfG}{E zffd(n^Zozo&-MS^BnZ8$9HWAJ%O@tTfU#h~=wz b18N2SkPTquv33X#M1BM;4blh$f0cos#`S2> literal 0 HcmV?d00001 diff --git a/src/test/java/btcr_service_client/BTCRDIDResolverTest.java b/src/test/java/btcr_service_client/BTCRDIDResolverTest.java new file mode 100644 index 0000000..ac0ea57 --- /dev/null +++ b/src/test/java/btcr_service_client/BTCRDIDResolverTest.java @@ -0,0 +1,48 @@ +package btcr_service_client; + +import org.junit.Test; + +import java.io.IOException; +import static org.junit.Assert.*; + +public class BTCRDIDResolverTest { + + private String BtcrDidString = "did:btcr:x705-jzv2-qqaz-7vuz"; //https://github.com/w3c-ccg/did-hackathon-2018/blob/master/BTCR-DID-Tests.md + private BTCRDIDResolver tester = new BTCRDIDResolver(this.BtcrDidString); + + @Test + public void getBtcrDidResolve() throws IOException { + String string = tester.getBtcrDidResolve(); + assertFalse(string.isEmpty()); + } + + @Test + public void getTip() throws IOException { + String string = tester.getTip(); + assertFalse(string.isEmpty()); + } + + @Test + public void decode() throws IOException { + String string = tester.decode(); + assertFalse(string.isEmpty()); + } + + @Test + public void txIdFromTxref() throws IOException{ + String string = tester.txIdFromTxref(); + assertFalse(string.isEmpty()); + } + + @Test + public void getDecodedTx() throws IOException { + String string = tester.getDecodedTx(); + assertFalse(string.isEmpty()); + } + + @Test + public void getUtxos() throws IOException { + String string = tester.getUtxos(); + assertFalse(string.isEmpty()); + } +} \ No newline at end of file From 8716017ef6ae7659f096319a0fdf4d88d70f84d4 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Tue, 6 Nov 2018 18:28:58 +0100 Subject: [PATCH 14/24] deleted file --- txidToUTXOs.java | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 txidToUTXOs.java diff --git a/txidToUTXOs.java b/txidToUTXOs.java deleted file mode 100644 index 94054a2..0000000 --- a/txidToUTXOs.java +++ /dev/null @@ -1,7 +0,0 @@ -package btcr_service_client; - -public class txidToUTXOs { - - - -} From 986028e0b48886fae50a13f50465c4880fb2a20a Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Tue, 6 Nov 2018 21:16:41 +0100 Subject: [PATCH 15/24] Deleted unused import in BTCRDIDResolver.java --- src/main/java/btcr_service_client/BTCRDIDResolver.java | 8 +++++--- src/main/java/btcr_service_client/DecodedTx.java | 1 - src/main/java/btcr_service_client/TxidToUTXOs.java | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/btcr_service_client/BTCRDIDResolver.java b/src/main/java/btcr_service_client/BTCRDIDResolver.java index dda5b5c..790c350 100644 --- a/src/main/java/btcr_service_client/BTCRDIDResolver.java +++ b/src/main/java/btcr_service_client/BTCRDIDResolver.java @@ -1,6 +1,5 @@ package btcr_service_client; -import java.awt.*; import java.io.IOException; public class BTCRDIDResolver { @@ -11,14 +10,17 @@ public class BTCRDIDResolver { private String PROTOCOL = "https://"; private String ADDRESS = "localhost"; private String PORT = "8080"; + private int TX_REF_SUBSTRING = 9; + //Constructor public BTCRDIDResolver(String brtcrDid){ this.brtcrDid = brtcrDid; - this.txRef = this.brtcrDid.substring(9); + this.txRef = this.brtcrDid.substring(TX_REF_SUBSTRING); } + // Resolve BTCR DID - public String getBrtcrDidRes() throws IOException { + public String getBtcrDidResolve() throws IOException { String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/resolve"; return new ResolveBTCRDID(url).resolve(); } diff --git a/src/main/java/btcr_service_client/DecodedTx.java b/src/main/java/btcr_service_client/DecodedTx.java index 066967d..21f784d 100644 --- a/src/main/java/btcr_service_client/DecodedTx.java +++ b/src/main/java/btcr_service_client/DecodedTx.java @@ -1,7 +1,6 @@ package btcr_service_client; import java.io.IOException; - import org.json.JSONObject; public class DecodedTx { diff --git a/src/main/java/btcr_service_client/TxidToUTXOs.java b/src/main/java/btcr_service_client/TxidToUTXOs.java index 94054a2..0795768 100644 --- a/src/main/java/btcr_service_client/TxidToUTXOs.java +++ b/src/main/java/btcr_service_client/TxidToUTXOs.java @@ -1,6 +1,6 @@ package btcr_service_client; -public class txidToUTXOs { +public class TxidToUTXOs { From 660d036b078b9bac943242adf10eda6961da463c Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Thu, 15 Nov 2018 10:45:53 +0100 Subject: [PATCH 16/24] Swtich to Android Wallet, with a new project structure --- .gitignore | 72 +------- .idea/compiler.xml | 9 - .idea/misc.xml | 6 - .idea/modules.xml | 10 -- .idea/vcs.xml | 7 - app/.gitignore | 1 + app/build.gradle | 30 ++++ app/proguard-rules.pro | 21 +++ .../btcwallet/ExampleInstrumentedTest.java | 26 +++ app/src/main/AndroidManifest.xml | 21 +++ .../btcrserviceclient/BTCRDIDResolver.java | 76 ++++++++ .../com/opdup/btcrserviceclient}/Decode.java | 7 +- .../opdup/btcrserviceclient}/DecodedTx.java | 8 +- .../btcrserviceclient}/ResolveBTCRDID.java | 7 +- .../btcrserviceclient}/ServiceConnection.java | 11 +- .../com/opdup/btcrserviceclient}/Tip.java | 7 +- .../btcrserviceclient}/TxIdFromTxRef.java | 13 +- .../btcrserviceclient/UtxosForAddress.java | 19 ++ .../com/opdup/btcwallet/MainActivity.java | 13 ++ .../drawable-v24/ic_launcher_foreground.xml | 34 ++++ .../res/drawable/ic_launcher_background.xml | 170 ++++++++++++++++++ app/src/main/res/layout/activity_main.xml | 18 ++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 2963 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 4905 bytes app/src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2060 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2783 bytes app/src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4490 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 6895 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6387 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10413 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9128 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15132 bytes app/src/main/res/values/colors.xml | 6 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/styles.xml | 11 ++ .../opdup/btcwallet}/BTCRDIDResolverTest.java | 30 +++- .../com/opdup/btcwallet/ExampleUnitTest.java | 17 ++ build.gradle | 35 ++-- gradle.properties | 15 ++ gradle/wrapper/gradle-wrapper.jar | Bin 54413 -> 54329 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- settings.gradle | 3 +- .../btcr_service_client/BTCRDIDResolver.java | 62 ------- .../java/btcr_service_client/TxidToUTXOs.java | 7 - src/test/.DS_Store | Bin 6148 -> 0 bytes 47 files changed, 577 insertions(+), 211 deletions(-) delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml create mode 100644 app/.gitignore create mode 100644 app/build.gradle create mode 100644 app/proguard-rules.pro create mode 100644 app/src/androidTest/java/com/opdup/btcwallet/ExampleInstrumentedTest.java create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java rename {src/main/java/btcr_service_client => app/src/main/java/com/opdup/btcrserviceclient}/Decode.java (65%) rename {src/main/java/btcr_service_client => app/src/main/java/com/opdup/btcrserviceclient}/DecodedTx.java (70%) rename {src/main/java/btcr_service_client => app/src/main/java/com/opdup/btcrserviceclient}/ResolveBTCRDID.java (70%) rename {src/main/java/btcr_service_client => app/src/main/java/com/opdup/btcrserviceclient}/ServiceConnection.java (82%) rename {src/main/java/btcr_service_client => app/src/main/java/com/opdup/btcrserviceclient}/Tip.java (65%) rename {src/main/java/btcr_service_client => app/src/main/java/com/opdup/btcrserviceclient}/TxIdFromTxRef.java (59%) create mode 100644 app/src/main/java/com/opdup/btcrserviceclient/UtxosForAddress.java create mode 100644 app/src/main/java/com/opdup/btcwallet/MainActivity.java create mode 100644 app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/layout/activity_main.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/styles.xml rename {src/test/java/btcr_service_client => app/src/test/java/com/opdup/btcwallet}/BTCRDIDResolverTest.java (56%) create mode 100644 app/src/test/java/com/opdup/btcwallet/ExampleUnitTest.java create mode 100644 gradle.properties delete mode 100644 src/main/java/btcr_service_client/BTCRDIDResolver.java delete mode 100644 src/main/java/btcr_service_client/TxidToUTXOs.java delete mode 100644 src/test/.DS_Store diff --git a/.gitignore b/.gitignore index 39b6783..fd45b12 100644 --- a/.gitignore +++ b/.gitignore @@ -1,65 +1,11 @@ -# Built application files -*.apk -*.ap_ - -# Files for the ART/Dalvik VM -*.dex - -# Java class files -*.class - -# Generated files -bin/ -gen/ -out/ - -# Gradle files -.gradle/ -build/ - -# Local configuration file (sdk path, etc) -local.properties - -# Proguard folder generated by Eclipse -proguard/ - -# Log Files -*.log - -# Android Studio Navigation editor temp files -.navigation/ - -# Android Studio captures folder -captures/ - -# IntelliJ *.iml -.idea/workspace.xml -.idea/tasks.xml -.idea/gradle.xml -.idea/assetWizardSettings.xml -.idea/dictionaries -.idea/libraries -.idea/caches - -# Keystore files -# Uncomment the following line if you do not want to check your keystore files in. -#*.jks - -# External native build folder generated in Android Studio 2.2 and later +.gradle +/local.properties +/.idea/caches/build_file_checksums.ser +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +.DS_Store +/build +/captures .externalNativeBuild - -# Google Services (e.g. APIs or Firebase) -google-services.json - -# Freeline -freeline.py -freeline/ -freeline_project_description.json - -# fastlane -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots -fastlane/test_output -fastlane/readme.md diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index 8caef52..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index e32eceb..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index c74f48e..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 8306744..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..778cd3d --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,30 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "com.opdup.btcwallet" + minSdkVersion 15 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + testImplementation 'junit:junit:4.12' + testImplementation 'org.mockito:mockito-core:2.7.22' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + androidTestImplementation 'org.mockito:mockito-android:2.7.22' +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/app/src/androidTest/java/com/opdup/btcwallet/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/opdup/btcwallet/ExampleInstrumentedTest.java new file mode 100644 index 0000000..9116689 --- /dev/null +++ b/app/src/androidTest/java/com/opdup/btcwallet/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.opdup.btcwallet; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.opdup.btcwallet", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..316c7d5 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java b/app/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java new file mode 100644 index 0000000..c5d7035 --- /dev/null +++ b/app/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java @@ -0,0 +1,76 @@ +package com.opdup.btcrserviceclient; + +import org.json.JSONException; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +public class BTCRDIDResolver { + + private String btcrDid; + private String txRef; + + private URL root; + private URL endpoint; + private String PROTOCOL = "https"; + private String ADDRESS = "localhost"; + private String PORT = "8080"; + private int TX_REF_SUBSTRING = 9; + + //Constructor + public BTCRDIDResolver(String btcrDid) throws MalformedURLException { + this.root = new URL(this.PROTOCOL, this.ADDRESS, this.PORT); + this.btcrDid = btcrDid; + this.txRef = this.btcrDid.substring(TX_REF_SUBSTRING); + } + + public BTCRDIDResolver(String btcrDid, URL rootURl) throws MalformedURLException { + this.root = rootURl; + this.btcrDid = btcrDid; + this.txRef = this.btcrDid.substring(TX_REF_SUBSTRING); + } + + // Resolve BTCR DID + public String getBtcrDidResolve() throws IOException { + this.endpoint = new URL(this.root, "txref/" + this.txRef + "/resolve"); + //String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/resolve"; + return new ResolveBTCRDID(this.endpoint).resolve(); + } + + // Following a tip + public String getTip() throws IOException { + this.endpoint = new URL(this.root, "txref/" + this.txRef + "/tip"); + //String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/tip"; + return new Tip(this.endpoint).getTip(); + } + + // Decode TxRef + public String decode() throws IOException { + this.endpoint = new URL(this.root, "txref/" + this.txRef + "/decode"); + //String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/decode"; + return new Decode(this.endpoint).decode(); + } + + // Get TxId from TxRef + public String txIdFromTxref() throws IOException, JSONException { + this.endpoint = new URL(this.root, "txref/" + this.txRef + "/txid"); + //String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/txid"; + return new TxIdFromTxRef(this.endpoint).getTxIdFromTxRef(); + } + + // Get Decoded Tx from TxId + public String getDecodedTx() throws IOException, JSONException { + String txId = txIdFromTxref(); + this.endpoint = new URL(this.root, "tx/" + txId); + //String url = PROTOCOL + ADDRESS + ":" + PORT + "/tx" + txId; + return new DecodedTx(this.endpoint).getTxFromTxId(); + } + + //Txid to Utxos for the address in Txid + public String getUtxosForAddress(String address) throws IOException { + this.endpoint = new URL(this.root, "addr/" + address + "/spends"); + return new UtxosForAddress(this.endpoint).getUtxos(); + } + +} diff --git a/src/main/java/btcr_service_client/Decode.java b/app/src/main/java/com/opdup/btcrserviceclient/Decode.java similarity index 65% rename from src/main/java/btcr_service_client/Decode.java rename to app/src/main/java/com/opdup/btcrserviceclient/Decode.java index d79804a..8347b08 100644 --- a/src/main/java/btcr_service_client/Decode.java +++ b/app/src/main/java/com/opdup/btcrserviceclient/Decode.java @@ -1,12 +1,13 @@ -package btcr_service_client; +package com.opdup.btcrserviceclient; import java.io.IOException; +import java.net.URL; public class Decode { - private String url; + private URL url; - public Decode(String url){ + public Decode(URL url){ this.url = url; } diff --git a/src/main/java/btcr_service_client/DecodedTx.java b/app/src/main/java/com/opdup/btcrserviceclient/DecodedTx.java similarity index 70% rename from src/main/java/btcr_service_client/DecodedTx.java rename to app/src/main/java/com/opdup/btcrserviceclient/DecodedTx.java index 21f784d..d6d6779 100644 --- a/src/main/java/btcr_service_client/DecodedTx.java +++ b/app/src/main/java/com/opdup/btcrserviceclient/DecodedTx.java @@ -1,13 +1,13 @@ -package btcr_service_client; +package com.opdup.btcrserviceclient; import java.io.IOException; -import org.json.JSONObject; +import java.net.URL; public class DecodedTx { - private String url; + private URL url; - public DecodedTx(String url){ + public DecodedTx(URL url){ this.url = url; } diff --git a/src/main/java/btcr_service_client/ResolveBTCRDID.java b/app/src/main/java/com/opdup/btcrserviceclient/ResolveBTCRDID.java similarity index 70% rename from src/main/java/btcr_service_client/ResolveBTCRDID.java rename to app/src/main/java/com/opdup/btcrserviceclient/ResolveBTCRDID.java index c81839d..e7d1941 100644 --- a/src/main/java/btcr_service_client/ResolveBTCRDID.java +++ b/app/src/main/java/com/opdup/btcrserviceclient/ResolveBTCRDID.java @@ -1,12 +1,13 @@ -package btcr_service_client; +package com.opdup.btcrserviceclient; import java.io.IOException; +import java.net.URL; public class ResolveBTCRDID { - private String url; + private URL url; - public ResolveBTCRDID(String url){ + public ResolveBTCRDID(URL url){ this.url = url; } diff --git a/src/main/java/btcr_service_client/ServiceConnection.java b/app/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java similarity index 82% rename from src/main/java/btcr_service_client/ServiceConnection.java rename to app/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java index 4c6a078..e603ff0 100644 --- a/src/main/java/btcr_service_client/ServiceConnection.java +++ b/app/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java @@ -1,5 +1,6 @@ -package btcr_service_client; +package com.opdup.btcrserviceclient; +import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; @@ -13,11 +14,11 @@ public class ServiceConnection { private URL url; private HttpURLConnection connection; - public ServiceConnection(String url) throws IOException{ - String urlStr = url; - this.url = new URL(urlStr); + public ServiceConnection(URL url) throws IOException{ + this.url = url; } + public void connect() throws IOException { this.connection = (HttpURLConnection) this.url.openConnection(); this.connection.setDoOutput(true); @@ -36,7 +37,7 @@ public String getJsonString() throws IOException { return json; } - public JSONObject getJsonObject() throws IOException { + public JSONObject getJsonObject() throws IOException, JSONException { return new JSONObject(getJsonString()); } diff --git a/src/main/java/btcr_service_client/Tip.java b/app/src/main/java/com/opdup/btcrserviceclient/Tip.java similarity index 65% rename from src/main/java/btcr_service_client/Tip.java rename to app/src/main/java/com/opdup/btcrserviceclient/Tip.java index 45b3d30..a6e1d7d 100644 --- a/src/main/java/btcr_service_client/Tip.java +++ b/app/src/main/java/com/opdup/btcrserviceclient/Tip.java @@ -1,12 +1,13 @@ -package btcr_service_client; +package com.opdup.btcrserviceclient; import java.io.IOException; +import java.net.URL; public class Tip { - private String url; + private URL url; - public Tip(String url){ + public Tip(URL url){ this.url = url; } diff --git a/src/main/java/btcr_service_client/TxIdFromTxRef.java b/app/src/main/java/com/opdup/btcrserviceclient/TxIdFromTxRef.java similarity index 59% rename from src/main/java/btcr_service_client/TxIdFromTxRef.java rename to app/src/main/java/com/opdup/btcrserviceclient/TxIdFromTxRef.java index b8b1e30..d60e107 100644 --- a/src/main/java/btcr_service_client/TxIdFromTxRef.java +++ b/app/src/main/java/com/opdup/btcrserviceclient/TxIdFromTxRef.java @@ -1,23 +1,24 @@ -package btcr_service_client; +package com.opdup.btcrserviceclient; -import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; +import java.net.URL; public class TxIdFromTxRef { - private String url; + private URL url; - public TxIdFromTxRef(String url){ + public TxIdFromTxRef(URL url){ this.url = url; } - public String getTxIdFromTxRef() throws IOException{ + public String getTxIdFromTxRef() throws IOException, JSONException { String jsonString = new ServiceConnection(this.url).getJsonString(); JSONObject jsonObject = new JSONObject(jsonString); String txid = null; - if (jsonObject!=null){ + if (jsonObject != null){ txid = jsonObject.getString("txid"); } return txid; diff --git a/app/src/main/java/com/opdup/btcrserviceclient/UtxosForAddress.java b/app/src/main/java/com/opdup/btcrserviceclient/UtxosForAddress.java new file mode 100644 index 0000000..e065925 --- /dev/null +++ b/app/src/main/java/com/opdup/btcrserviceclient/UtxosForAddress.java @@ -0,0 +1,19 @@ +package com.opdup.btcrserviceclient; + +import java.io.IOException; +import java.net.URL; + +public class UtxosForAddress { + + private URL url; + + public UtxosForAddress(URL url) { + this.url = url; + } + + public String getUtxos() throws IOException { + ServiceConnection serviceConnection = new ServiceConnection(this.url); + return serviceConnection.getJsonString(); + } + +} diff --git a/app/src/main/java/com/opdup/btcwallet/MainActivity.java b/app/src/main/java/com/opdup/btcwallet/MainActivity.java new file mode 100644 index 0000000..300a80a --- /dev/null +++ b/app/src/main/java/com/opdup/btcwallet/MainActivity.java @@ -0,0 +1,13 @@ +package com.opdup.btcwallet; + +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; + +public class MainActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + } +} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1f6bb29 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..0d025f9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..84f1951 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..898f3ed59ac9f3248734a00e5902736c9367d455 GIT binary patch literal 2963 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 JPDHLkV1g@XpTGbB literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..dffca3601eba7bf5f409bdd520820e2eb5122c75 GIT binary patch literal 4905 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 lV%Z2*hu);6rydA(}wUDXPCF_W1vnaRBK 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..14ed0af35023e4f1901cf03487b6c524257b8483 GIT binary patch literal 6895 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..b0907cac3bfd8fbfdc46e1108247f0a1055387ec GIT binary patch literal 6387 zcma($WmFVQySpr~^b#u_OG=0|(kva)DP1B+cP_AmARxJ*NC=Wrg0zUl5(`L)gp{N- z(%_OG?|Z*r_s2c=$2@ap&UtF)$(eXP9W_!SdLjS-K&qjxY;ZTH{xb;h@8E{&N(%r$ z+p3|gU=%dFmq%!1q&9_NsUvvk-GvvZjaIJ%uU(o!Ypc=Wv%E8e<<)SFdRM{tz(T@!nKT{;0jT2A&dgKu3 zk|GDUX<&73+f+CnZza0G4g29@hmNkl+2wP#$0yi6=u-4CD#*a8LxJLG9KlkveQ7v} z>E#)-tL=xh89y&5li1I!>Zzc!_i6V~nKP^5-+!69FtnX*f=*tr+cf&UpZtLBY|wv< zJ6r*Z5374 zi$7+B3A@szy#|*$Tb~kkzc_N~h3;oe8q95K$w@e#5FRGcF}wXTR}t#^!OnNc>Z52w zu23YrlIQY7UrLLcFSW5ctMBzwrTz=X-m{1Y!*LWUbO~;u&&q8Lu;wlGFqO2h4olL; z{rpPfr}7f=Z)eZhFw1_ITpft-VzPF1CHv-W>u;OCBJBEOEn$HmTpFjX=xN6-H5#V{ zn6Si;q3V*@lFMd>H8;M}vOp8McQcJ}^bBfV`1xb0g0`9ZZa9(wb+L_RGO6wD&I8ouM<}YVDFU ztMSz*yMDz3AkS0YO)3_lYDarEUyj?A#9s@-ln${-1Op^nD7zREi=%4Hy%V?=YS7G`L@>`3kHM4eAD%)t@F};|C zfj?B^Kox-WuPMuDp2=LPZU3Obgnl7{dD>|>*A`fn-0|^8uAHJz;<)tkTXA8lI&dHt&xG(4Il=e~QNN6o9YD7H{TR?17eM>#Z8#Y@_=7fZ?HkZX8i|mEGs5mR`uBi^ zzFh5AG^3EMyvpx(a*)!eOI1?nPTn?v0Ly$)KlQ16Xfrzh+}+Ua_I!5XU@ciwrAZ>O z<7!MU$n6`x${EB6YH$hWOMuSEw+72Lb~rgO*Yp26LGdNp*;^;HAD@(SAr(Dk;j7w! zQ>!M4rxUFYn7E?v7)2q)2rJ2%PY>A>-1O7bY~nt&n)jYnG$(iR#hvlih1p}c)I+|I zy^C;=uIJImfY zL~pm6t6Zw8FiOIY<1>EBS(<5`Cv8DBcZEpTCQ{@@-|2$Bhi;6H?Pofq1Z%b2@)&at zUA{9iaqi62D1|=T{xTe3Czr|z52P;M7EB|V-ss{qspYc0Cj~hUUURef8?i5H?e;kA z<~qW5`JIc(rCLz_oJ~>x8O2IVR%>+7%}`TBSQt%i+m+4tV?z0(?5cf&1v8cNlz7Lg z%ZS>-e!({r)+sH_1+QJvE5BqOgmfK_$X*P0*x6beoRN|0FV zBu+T9^1E5}1I>g&wC|Bn^{(R$!_A@+E4<}3n|QMU=H|GuQZRAZ+zSZ}SS{MNj&mi0 zRY+fp&8IQn-}zGeIVj+qntrIP-IpXF?2xAoyT|i)X+@HL$+|t{#ZAvBrd?L!=9aLy z%@CY;X7U41O6VpHq<1UBk2vi~afo_h1Xrb{vQ%cE|Fvi8EjFCP^~ zabJnB#=NPyBD*BaNSQW*VI+TbEmlu2&HD<4U_UQNUR_`K~u~XWideSoLc(k)vEtG^CT* zG`Zdarw^M&6C=~oi^6W#WL!BMe{E&Gg9Arbg2gg;cO^sJ#+L$ zWBP!R+lcV(p-B#aK<&Ly>?*3fngF)TwSRSmGJ!zET{Brabip#AUPyChm}S9IFG!l{ z%+I_?Cl?zVm9nbGSU`Ksi%z1{vEPpxnv}!StZLIR4yl9y>GM~KIIbNdVs|xsuCpX=J#rE`8<@v*FO%Lb)=#c`~s7W#9EDhRI!G*VBK(y z5D`)jJo4o1={q}Kg%YGhdH~@PGate(xi{(OiQn~MMSZM;!kHNh*1-e<+YS5-j3b?2 zq7SYPWMn1a!^Gqxr4d1gZ5G`QQ(&4Ag*OcnWO}~9rz5xeE3Ycol5cj$@jggn@8x2* z)UpG-U2|Av7a)Hi=b^@SNp#`PEDfswF$nyx&rD*+4SF}`_U48`=1VnBn}aEm{Funk zSWQuC>r8yUkd_D(dKEqo`7i}}{#+a?O4 zDIg~&^q#d5-Ji>``G%gDDzV<~+=*qePTy_lbVjK?!d`>ygnhxwtyL65_G4A=A}{Dh zq;iS@h|Y-wJdeGj1b{KBTkst|klERM7*Hwy#ZO<~Q$5~GzC~WjZHz>=z3~>oAVbbv zzmgOw2JQ#Kv)GT9dwrXGJKz5(Jw%&rYPjfi;TI|dyVJrvaZ*ivGRT;i>R6}8B>7*j zbJi0%9UfLcYKp+TU9qXLSp`rm`)3(g6YOdHa4cv2Y)-JCPZ&g1Z*%F~T@dw@_HA~- zxeq6NeOi{(yh(ziMZ)4yIfDP6nhTg;)$=9N_-{KO!ZB@c@e$(SVH`%0b3YF`lgX)? zmPOF$H%(2yD*LrQ;d*vDgW=s=2h+1RYg?DCXa2gXNT~W+Hu+pBZ$bO8IlS+nqXw^| zBM2iS@v_S^5P@J5V0gw2hamKs7Wro(xWlv)U$%_D)AA{;Mb;l$7?FOK*2{U?f_M(W z4#aOFFlOC*Grkxzi#w)?qgNP48e=dJ*`EYNKfLm6BlZ-j@VMi+{0T>$Y6e%gC|6;v z4=~J;U-H`Rv(<}l7sEXpm?7;(jXl{O>aLca zP;<5GjkKb?74YTOqJAtFKzq|v(-+j{(@?GPIKVS95tsog!>*S60XwAsnYHqG)dW<#@2UIte}({hi5+*r;^rQeDpKps%Ql|LRink z=CR6^g!&1h1Ks5JplDey{0{E~MNPgvQNeH21%lrCFFh~_7#;b73>@zaFo0B}hXo(J z#OVP*a2!ZeK|x0LfazsE0=vAP5xpQ58{e}Xtzn5B`l%b)PM2PI{UmZ`}XbW%4eE=4-VAbQ|zojxNh6BnLDzTlx-stKQP0|=pi5R7qw0g}ivih_z$ zN`Pc6h9K3P5vFz^s^};EaGwq5yEdpH4Um!3Lju85e*w5hg)|yEkihSklp#pqhWjij zaK_T%_)PG>g`7N9$25qwhR3WB{&pp8G2;J-#qe6%xdFHO2AeceqW`Q#`J1X4*a>V4 z;Y4EVTMA!^vxOA;$ZDCt!CPots~0yn*Erio(G!n)@W*|^D_=Wy;f*k=tF~9Zmr)dn zCzfODoJ@UXXs>1NP-A4#YmmhGXavn<+z_gJ`>cZaGo@Iz2J)=M7{{ zJ;n45y6T86%gls;?`*1bFl=sXf1H<+2AiBU`}H6YM=+eFPoz%Sg=s>Dva{ls1mJO? zTWP*i(U7Ec^3%Z$g`f%l##*mSt_wOa-d&(0A0@(ms#pY$P8SX-ZAVg)> zpsk00`SNH__*AQ#=>~|-wScS`e>RBCs6NsQ18sz`Q({qI(fOQUY10Mt%YO^v{>w>TEBSR zi>oS_n(}3A8W+^iWG~}cr3Bv#s3W>CFUJm0ejS>=V^X>!UmDV@|xH@hWB5yhc zuXagN9&cY%tMFc@?PqIxYmy+OSGU`O5gvK2Yaic7tFAiaz`*T*dLafG4tz~<{L=*n z1iRA9k6#TYhCWcSFW6P4&4yOea4q&Fy6Mbkfl&!{&@KmDXMWs7;2Q2bRU~gBtDs>o zNeUgzt#lWV4oq=C=5{Id0)=a+u5HaCtDZwXnX5u!bO%{LbXF-L40}KeG4lG*uU{E_AOMMd4ch=Q9&rc=;3fB`I@EFBuF!XcuT783*FH`4zO zxZ=AOG#fzwnh^u6!|A7Fqf5u{$IesB&EF?V9g5dyhcmbVh)|M3^!U*}qJEYbGFaK2 z#0I`dWniJzl~+;sJs^jty%7`^Yv#{r+=Q<#CleH22pEWpQ)lwX9b5uv064&fPlS+b zqZM<&o~(2`QgUJ$O29zuo%|4(uP+zAeibd;jfc(zz|+6+9EUrZ?#^|ymX-knV0Dsz zFn=Bg(*p-JjWR}+{_C#CZ~dR&on|-C9&{&ij%~0x9gtgIMPCkr_rc{WE_}pL*bCnZ z3d?M3AYq3)iUS7jPOFD3m9DVG)E&SJ1*`YXzZQib9R(``({n~0aGXEhgZnJU3vy*N zlEAeqef_?@nqICTH{?wuZFw#7F{`&i?NLpf<7G2noyziDxMHBmK=Z&P8jf>~^fSVF zFmD1h)DVg7D8erkb}OkfElv2i`s#7j5-;7~&l>SlgLRqNM90B`oFJ!3Z!I+~g7^$B zkD<7Y^U2QID5DVT!a*uS%0aL5KAD#Lk5^|WCC!!OQcFyxCl$386q*ohKGP#?pNL0_ zG0d|NfxU%N?);5-{u0rA@S7+4>7&sDwppXmJaj`?8D#?9@k90l(a-Vg>E`q1zXh9B zEsyo)21!OKE@yf_^P?a!d>O%I$~z&Bg| z{KuO5lVh07O|keMJh@ks$3EfHm`nFk6qNS&_PxPbKN1c~Ds8?;y>OzV;B0$XVQ=LQx12PJ2~x!&?qm%Tl)eivoas}<)&`&84*`tT{?ou45c+RPjX;imIsuwmXJs;5Klbii3#Q0kSLKcW+Y@xKcRce+GJ-RTlpMp(c)D`xrv zd|#_rj!Bm<&cad=Pq($+uKOY#CGCK-8EXOLAo{LJ2l({+_%87YR(e2EErULI*gm@X z*m6LuczdHTQHH`3=)x;unt9KH-4duW3nu}xk&Cu4-DS4wjNG}S$tO5H_$l1*S3Go6 z0HH1rN4WcDUK${}+a@ICZ(ZC#*`6h6EK7)q2OePook_w)c5%-9AxwoT6E*>!XDxpM zy_C$yP!`aN2TiCVLn_z`_E((J%LUYuw%2%(GBL3Cve+5zmepidD|^#$=@2Wfp!?NR zUpV2SwaMg68}9+`X#n-Ust|TK-Qk@HXu7dM*@>KO~@YA_S!geT; zxLp>TbIo9^WI=ZuT?ErRN;LqRSZX$7)+{MdSSiDnSdSwQ+6Yqb#nF393O_Ow-rRZD z1MtC55vP=~4kwe+$#2C8b3Q6*<^!T_D^X($HS$*Ns2(pd5~m<_QgfsetRt77rwh}yjg#yx`@p|%;RnzvAN8~6i5D;EQg*azSU-+F9W;M>-%sM=r4J zY%}@{t+!2883WSGMgw_85U#I}O75Rr0Q_D5;Du8|l@ zHWBq-r2&(pezi>6+daPx-qwVIQ3A6$h}GxIH72G*;HeRgyXKy?Uf!HvVg$M3Vs?lo j7HB*8-{6~e<}KKy%g|C8?m&3=nE}vH(NX@WXdCq(XawjJ literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..d8ae03154975f397f8ed1b84f2d4bf9783ecfa26 GIT binary patch literal 10413 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 XdJ+W}DiIkV00000NkvXXu0mjfKBlg6 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..2c18de9e66108411737e910f5c1972476f03ddbf GIT binary patch literal 9128 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 I20H400LcNok^lez literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..beed3cdd2c32af5114a7dc70b9ef5b698eb8797e GIT binary patch literal 15132 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..69b2233 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + #008577 + #00574B + #D81B60 + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..bc00fa7 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + BTCWallet + diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..5885930 --- /dev/null +++ b/app/src/main/res/values/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/src/test/java/btcr_service_client/BTCRDIDResolverTest.java b/app/src/test/java/com/opdup/btcwallet/BTCRDIDResolverTest.java similarity index 56% rename from src/test/java/btcr_service_client/BTCRDIDResolverTest.java rename to app/src/test/java/com/opdup/btcwallet/BTCRDIDResolverTest.java index ac0ea57..e25cf6f 100644 --- a/src/test/java/btcr_service_client/BTCRDIDResolverTest.java +++ b/app/src/test/java/com/opdup/btcwallet/BTCRDIDResolverTest.java @@ -1,14 +1,30 @@ -package btcr_service_client; +package com.opdup.btcwallet; +import com.opdup.btcrserviceclient.BTCRDIDResolver; + +import java.net.MalformedURLException; + +import org.json.JSONException; import org.junit.Test; import java.io.IOException; import static org.junit.Assert.*; +//import static org.mockito.mock.*; -public class BTCRDIDResolverTest { +public class BTCRDIDResolverTest { private String BtcrDidString = "did:btcr:x705-jzv2-qqaz-7vuz"; //https://github.com/w3c-ccg/did-hackathon-2018/blob/master/BTCR-DID-Tests.md - private BTCRDIDResolver tester = new BTCRDIDResolver(this.BtcrDidString); + private String address = ""; + + private BTCRDIDResolver tester; + + { + try { + tester = new BTCRDIDResolver(this.BtcrDidString); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } @Test public void getBtcrDidResolve() throws IOException { @@ -29,20 +45,20 @@ public void decode() throws IOException { } @Test - public void txIdFromTxref() throws IOException{ + public void txIdFromTxref() throws IOException, JSONException { String string = tester.txIdFromTxref(); assertFalse(string.isEmpty()); } @Test - public void getDecodedTx() throws IOException { + public void getDecodedTx() throws IOException, JSONException { String string = tester.getDecodedTx(); assertFalse(string.isEmpty()); } @Test - public void getUtxos() throws IOException { - String string = tester.getUtxos(); + public void getUtxos() throws IOException, JSONException { + String string = tester.getUtxosForAddress(this.address); assertFalse(string.isEmpty()); } } \ No newline at end of file diff --git a/app/src/test/java/com/opdup/btcwallet/ExampleUnitTest.java b/app/src/test/java/com/opdup/btcwallet/ExampleUnitTest.java new file mode 100644 index 0000000..f6d3a87 --- /dev/null +++ b/app/src/test/java/com/opdup/btcwallet/ExampleUnitTest.java @@ -0,0 +1,17 @@ +package com.opdup.btcwallet; + +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Example local unit test, which will execute on the development machine (host). + * + * @see Testing documentation + */ +public class ExampleUnitTest { + @Test + public void addition_isCorrect() { + assertEquals(4, 2 + 2); + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index bafbe18..13c49a1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,17 +1,28 @@ -plugins { - id 'java' -} - -group 'org.opdup' -version '1.0-SNAPSHOT' +// Top-level build file where you can add configuration options common to all sub-projects/modules. -sourceCompatibility = 1.8 +buildscript { + + repositories { + google() + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + -repositories { - mavenCentral() + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } } -dependencies { - testCompile group: 'junit', name: 'junit', version: '4.12' - implementation "org.json:json:20180813" +allprojects { + repositories { + google() + jcenter() + mavenCentral() + } } + +task clean(type: Delete) { + delete rootProject.buildDir +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..82618ce --- /dev/null +++ b/gradle.properties @@ -0,0 +1,15 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + + diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1948b9074f1016d15d505d185bc3f73deb82d8c8..f6b961fd5a86aa5fbfe90f707c3138408be7c718 100644 GIT binary patch delta 7286 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 delta 7399 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 Da{n=i diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae021cd..9a4163a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Wed Oct 17 16:27:40 CEST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.8-all.zip diff --git a/settings.gradle b/settings.gradle index a7d4341..e7b4def 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1 @@ -rootProject.name = 'btcr-service-client-java' - +include ':app' diff --git a/src/main/java/btcr_service_client/BTCRDIDResolver.java b/src/main/java/btcr_service_client/BTCRDIDResolver.java deleted file mode 100644 index 790c350..0000000 --- a/src/main/java/btcr_service_client/BTCRDIDResolver.java +++ /dev/null @@ -1,62 +0,0 @@ -package btcr_service_client; - -import java.io.IOException; - -public class BTCRDIDResolver { - - private String brtcrDid; - private String txRef; - - private String PROTOCOL = "https://"; - private String ADDRESS = "localhost"; - private String PORT = "8080"; - private int TX_REF_SUBSTRING = 9; - - //Constructor - public BTCRDIDResolver(String brtcrDid){ - this.brtcrDid = brtcrDid; - this.txRef = this.brtcrDid.substring(TX_REF_SUBSTRING); - } - - - // Resolve BTCR DID - public String getBtcrDidResolve() throws IOException { - String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/resolve"; - return new ResolveBTCRDID(url).resolve(); - } - - // Following a tip - public String getTip() throws IOException { - String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/tip"; - return new Tip(url).getTip(); - } - - // Decode TxRef - public String decode() throws IOException { - String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/decode"; - return new Decode(url).decode(); - } - - // Get TxId from TxRef - public String txIdFromTxref() throws IOException { - String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/txid"; - return new TxIdFromTxRef(url).getTxIdFromTxRef(); - } - - // Get Decoded Tx from TxId - public String getDecodedTx() throws IOException { - String txId = txIdFromTxref(); - String url = PROTOCOL + ADDRESS + ":" + PORT + "/tx" + txId; - return new DecodedTx(url).getTxFromTxId(); - } - - //Txid to Utxos for the address in Txid - public String getUtxos() throws IOException { - String txId = txIdFromTxref(); - String addr = ""; - String url = PROTOCOL + ADDRESS + ":" + PORT + "/addr/" + addr + "/spends"; - String utxo = ""; - return ""; - } - -} diff --git a/src/main/java/btcr_service_client/TxidToUTXOs.java b/src/main/java/btcr_service_client/TxidToUTXOs.java deleted file mode 100644 index 0795768..0000000 --- a/src/main/java/btcr_service_client/TxidToUTXOs.java +++ /dev/null @@ -1,7 +0,0 @@ -package btcr_service_client; - -public class TxidToUTXOs { - - - -} diff --git a/src/test/.DS_Store b/src/test/.DS_Store deleted file mode 100644 index c38abe608bd908e6875d993d6b6cd2338bf362ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK&2G~`5S~o~T?Zj@sMH>PsnkObDXE$RLbB3w=&h0wJpgL$CZa~hTg6TzNQ3+u z@CJR9K0zM`zS&)({=gL?G$YM^v$Hd6@3+>jhltc*GTbI=6Oo28HUc!i5guoKAPw(n z0u|43kekyqH!1o&p~&(xz z#!BOrpN8IJyTRkR*c3r zIU9};^6n@rhGsf2lVVufd15!9b)bXe_Qq_s)9-b{-t*mgC!F>B-A=gE+nvt?y}r5q z^5Ept=P$F%`PXl5FBCphE6+Usg6}XE3%rQOMQ(}@@Ns-VV;WIOh9%0FZwpt-!Xw{=kqO zz{q3m5FUtfsX&*ie2Jla<)BnJJ9O!!?2|E%f3orwit>er3T-&4$f2~tfG}{E zffd(n^Zozo&-MS^BnZ8$9HWAJ%O@tTfU#h~=wz b18N2SkPTquv33X#M1BM;4blh$f0cos#`S2> From 18b38dbee97757803326d041f617f0faab9dad05 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Thu, 22 Nov 2018 16:41:43 +0100 Subject: [PATCH 17/24] Add ServiceConnection tests using MockWebServer and Mockito frameworks --- .idea/codeStyles/Project.xml | 29 +++++++++ .../opdup/btcwallet/BTCRDIDResolverTest.java | 64 ------------------- .../com/opdup/btcwallet/ExampleUnitTest.java | 17 ----- .../btcwallet/ServiceConnectionTester.java | 4 ++ 4 files changed, 33 insertions(+), 81 deletions(-) create mode 100644 .idea/codeStyles/Project.xml delete mode 100644 app/src/test/java/com/opdup/btcwallet/BTCRDIDResolverTest.java delete mode 100644 app/src/test/java/com/opdup/btcwallet/ExampleUnitTest.java create mode 100644 app/src/test/java/com/opdup/btcwallet/ServiceConnectionTester.java diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..30aa626 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/test/java/com/opdup/btcwallet/BTCRDIDResolverTest.java b/app/src/test/java/com/opdup/btcwallet/BTCRDIDResolverTest.java deleted file mode 100644 index e25cf6f..0000000 --- a/app/src/test/java/com/opdup/btcwallet/BTCRDIDResolverTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.opdup.btcwallet; - -import com.opdup.btcrserviceclient.BTCRDIDResolver; - -import java.net.MalformedURLException; - -import org.json.JSONException; -import org.junit.Test; - -import java.io.IOException; -import static org.junit.Assert.*; -//import static org.mockito.mock.*; - -public class BTCRDIDResolverTest { - - private String BtcrDidString = "did:btcr:x705-jzv2-qqaz-7vuz"; //https://github.com/w3c-ccg/did-hackathon-2018/blob/master/BTCR-DID-Tests.md - private String address = ""; - - private BTCRDIDResolver tester; - - { - try { - tester = new BTCRDIDResolver(this.BtcrDidString); - } catch (MalformedURLException e) { - e.printStackTrace(); - } - } - - @Test - public void getBtcrDidResolve() throws IOException { - String string = tester.getBtcrDidResolve(); - assertFalse(string.isEmpty()); - } - - @Test - public void getTip() throws IOException { - String string = tester.getTip(); - assertFalse(string.isEmpty()); - } - - @Test - public void decode() throws IOException { - String string = tester.decode(); - assertFalse(string.isEmpty()); - } - - @Test - public void txIdFromTxref() throws IOException, JSONException { - String string = tester.txIdFromTxref(); - assertFalse(string.isEmpty()); - } - - @Test - public void getDecodedTx() throws IOException, JSONException { - String string = tester.getDecodedTx(); - assertFalse(string.isEmpty()); - } - - @Test - public void getUtxos() throws IOException, JSONException { - String string = tester.getUtxosForAddress(this.address); - assertFalse(string.isEmpty()); - } -} \ No newline at end of file diff --git a/app/src/test/java/com/opdup/btcwallet/ExampleUnitTest.java b/app/src/test/java/com/opdup/btcwallet/ExampleUnitTest.java deleted file mode 100644 index f6d3a87..0000000 --- a/app/src/test/java/com/opdup/btcwallet/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.opdup.btcwallet; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/app/src/test/java/com/opdup/btcwallet/ServiceConnectionTester.java b/app/src/test/java/com/opdup/btcwallet/ServiceConnectionTester.java new file mode 100644 index 0000000..7510ed7 --- /dev/null +++ b/app/src/test/java/com/opdup/btcwallet/ServiceConnectionTester.java @@ -0,0 +1,4 @@ +package com.opdup.btcwallet; + +public class ServiceConnectionTester { +} From 8bf108c96969f8ce89bb660f865868fcf5975546 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Thu, 29 Nov 2018 14:17:19 +0100 Subject: [PATCH 18/24] Change project structure adding new Android module for the library --- .../com/opdup/btcwallet/ServiceConnectionTester.java | 4 ---- btcrserviceclient/.gitignore | 1 + btcrserviceclient/build.gradle | 8 ++++++++ .../com/opdup/btcrserviceclient/BTCRDIDResolver.java | 10 ++++++++-- .../main/java/com/opdup/btcrserviceclient/Decode.java | 0 .../java/com/opdup/btcrserviceclient/DecodedTx.java | 0 .../com/opdup/btcrserviceclient/ResolveBTCRDID.java | 0 .../com/opdup/btcrserviceclient/ServiceConnection.java | 2 +- .../src/main/java/com/opdup/btcrserviceclient/Tip.java | 0 .../com/opdup/btcrserviceclient/TxIdFromTxRef.java | 0 .../com/opdup/btcrserviceclient/UtxosForAddress.java | 0 .../btcrserviceclient/ServiceConnectionTester.java | 5 +++++ 12 files changed, 23 insertions(+), 7 deletions(-) delete mode 100644 app/src/test/java/com/opdup/btcwallet/ServiceConnectionTester.java create mode 100644 btcrserviceclient/.gitignore create mode 100644 btcrserviceclient/build.gradle rename {app => btcrserviceclient}/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java (92%) rename {app => btcrserviceclient}/src/main/java/com/opdup/btcrserviceclient/Decode.java (100%) rename {app => btcrserviceclient}/src/main/java/com/opdup/btcrserviceclient/DecodedTx.java (100%) rename {app => btcrserviceclient}/src/main/java/com/opdup/btcrserviceclient/ResolveBTCRDID.java (100%) rename {app => btcrserviceclient}/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java (96%) rename {app => btcrserviceclient}/src/main/java/com/opdup/btcrserviceclient/Tip.java (100%) rename {app => btcrserviceclient}/src/main/java/com/opdup/btcrserviceclient/TxIdFromTxRef.java (100%) rename {app => btcrserviceclient}/src/main/java/com/opdup/btcrserviceclient/UtxosForAddress.java (100%) create mode 100644 btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/ServiceConnectionTester.java diff --git a/app/src/test/java/com/opdup/btcwallet/ServiceConnectionTester.java b/app/src/test/java/com/opdup/btcwallet/ServiceConnectionTester.java deleted file mode 100644 index 7510ed7..0000000 --- a/app/src/test/java/com/opdup/btcwallet/ServiceConnectionTester.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.opdup.btcwallet; - -public class ServiceConnectionTester { -} diff --git a/btcrserviceclient/.gitignore b/btcrserviceclient/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/btcrserviceclient/.gitignore @@ -0,0 +1 @@ +/build diff --git a/btcrserviceclient/build.gradle b/btcrserviceclient/build.gradle new file mode 100644 index 0000000..68bb776 --- /dev/null +++ b/btcrserviceclient/build.gradle @@ -0,0 +1,8 @@ +apply plugin: 'java-library' + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) +} + +sourceCompatibility = "7" +targetCompatibility = "7" diff --git a/app/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java similarity index 92% rename from app/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java rename to btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java index c5d7035..67ec5c1 100644 --- a/app/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java @@ -22,13 +22,13 @@ public class BTCRDIDResolver { public BTCRDIDResolver(String btcrDid) throws MalformedURLException { this.root = new URL(this.PROTOCOL, this.ADDRESS, this.PORT); this.btcrDid = btcrDid; - this.txRef = this.btcrDid.substring(TX_REF_SUBSTRING); + this.txRef = getTxRef(btcrDid); } public BTCRDIDResolver(String btcrDid, URL rootURl) throws MalformedURLException { this.root = rootURl; this.btcrDid = btcrDid; - this.txRef = this.btcrDid.substring(TX_REF_SUBSTRING); + this.txRef = getTxRef(btcrDid); } // Resolve BTCR DID @@ -73,4 +73,10 @@ public String getUtxosForAddress(String address) throws IOException { return new UtxosForAddress(this.endpoint).getUtxos(); } + + //Get the TxRef from BTCR DID + private String getTxRef(String btcrDid){ + return btcrDid.substring(TX_REF_SUBSTRING); + } + } diff --git a/app/src/main/java/com/opdup/btcrserviceclient/Decode.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Decode.java similarity index 100% rename from app/src/main/java/com/opdup/btcrserviceclient/Decode.java rename to btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Decode.java diff --git a/app/src/main/java/com/opdup/btcrserviceclient/DecodedTx.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/DecodedTx.java similarity index 100% rename from app/src/main/java/com/opdup/btcrserviceclient/DecodedTx.java rename to btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/DecodedTx.java diff --git a/app/src/main/java/com/opdup/btcrserviceclient/ResolveBTCRDID.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ResolveBTCRDID.java similarity index 100% rename from app/src/main/java/com/opdup/btcrserviceclient/ResolveBTCRDID.java rename to btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ResolveBTCRDID.java diff --git a/app/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java similarity index 96% rename from app/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java rename to btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java index e603ff0..a6ec7ca 100644 --- a/app/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java @@ -19,7 +19,7 @@ public ServiceConnection(URL url) throws IOException{ } - public void connect() throws IOException { + private void connect() throws IOException { this.connection = (HttpURLConnection) this.url.openConnection(); this.connection.setDoOutput(true); this.connection.setInstanceFollowRedirects(false); diff --git a/app/src/main/java/com/opdup/btcrserviceclient/Tip.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java similarity index 100% rename from app/src/main/java/com/opdup/btcrserviceclient/Tip.java rename to btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java diff --git a/app/src/main/java/com/opdup/btcrserviceclient/TxIdFromTxRef.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/TxIdFromTxRef.java similarity index 100% rename from app/src/main/java/com/opdup/btcrserviceclient/TxIdFromTxRef.java rename to btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/TxIdFromTxRef.java diff --git a/app/src/main/java/com/opdup/btcrserviceclient/UtxosForAddress.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/UtxosForAddress.java similarity index 100% rename from app/src/main/java/com/opdup/btcrserviceclient/UtxosForAddress.java rename to btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/UtxosForAddress.java diff --git a/btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/ServiceConnectionTester.java b/btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/ServiceConnectionTester.java new file mode 100644 index 0000000..2a23544 --- /dev/null +++ b/btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/ServiceConnectionTester.java @@ -0,0 +1,5 @@ +import static org.junit.jupiter.api.Assertions.*; + +class ServiceConnectionTest { + +} \ No newline at end of file From 06a24f58a007bfcebc51a584b092e2d279d850c8 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Mon, 3 Dec 2018 16:49:29 +0100 Subject: [PATCH 19/24] Add more tests on ServiceConnectionTester.java, add get transactions details and get public key following a tip on TxDetails and Tip classes --- .../opdup/btcrserviceclient/{ResolveBTCRDID.java => Resolve.java} | 0 .../btcrserviceclient/{TxIdFromTxRef.java => TxDetails.java} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/{ResolveBTCRDID.java => Resolve.java} (100%) rename btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/{TxIdFromTxRef.java => TxDetails.java} (100%) diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ResolveBTCRDID.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Resolve.java similarity index 100% rename from btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ResolveBTCRDID.java rename to btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Resolve.java diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/TxIdFromTxRef.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/TxDetails.java similarity index 100% rename from btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/TxIdFromTxRef.java rename to btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/TxDetails.java From 4b6ca9373445ad0b4fde74ac21beda78dd8963c3 Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Thu, 6 Dec 2018 10:13:48 +0100 Subject: [PATCH 20/24] Add tests for ServiceConnection The test mock the btcr service --- .idea/encodings.xml | 4 + .idea/gradle.xml | 19 ++ .idea/misc.xml | 44 +++++ .idea/runConfigurations.xml | 12 ++ .idea/vcs.xml | 6 + app/build.gradle | 7 +- btcrserviceclient/build.gradle | 5 + .../btcrserviceclient/BTCRDIDResolver.java | 31 ++- .../com/opdup/btcrserviceclient/Resolve.java | 4 +- .../java/com/opdup/btcrserviceclient/Tip.java | 29 ++- .../opdup/btcrserviceclient/TxDetails.java | 26 ++- .../ServiceConnectionTester.java | 185 +++++++++++++++++- settings.gradle | 2 +- 13 files changed, 349 insertions(+), 25 deletions(-) create mode 100644 .idea/encodings.xml create mode 100644 .idea/gradle.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/runConfigurations.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..a13f9ca --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..51fa3e5 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 778cd3d..e562ae7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,9 +22,12 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'com.google.code.gson:gson:2.7' testImplementation 'junit:junit:4.12' - testImplementation 'org.mockito:mockito-core:2.7.22' + testImplementation 'org.mockito:mockito-core:2.23.0' + testImplementation 'com.squareup.okhttp3:mockwebserver:3.12.0' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' - androidTestImplementation 'org.mockito:mockito-android:2.7.22' + androidTestImplementation 'org.mockito:mockito-android:2.23.0' + androidTestImplementation 'com.squareup.okhttp3:mockwebserver:3.12.0' } diff --git a/btcrserviceclient/build.gradle b/btcrserviceclient/build.gradle index 68bb776..447aa19 100644 --- a/btcrserviceclient/build.gradle +++ b/btcrserviceclient/build.gradle @@ -2,6 +2,11 @@ apply plugin: 'java-library' dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.google.code.gson:gson:2.7' + implementation 'org.json:json:20180813' + testImplementation 'junit:junit:4.12' + testImplementation 'org.mockito:mockito-core:2.23.0' + testImplementation 'com.squareup.okhttp3:mockwebserver:3.12.0' } sourceCompatibility = "7" diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java index 67ec5c1..2e8def6 100644 --- a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java @@ -32,38 +32,53 @@ public BTCRDIDResolver(String btcrDid, URL rootURl) throws MalformedURLException } // Resolve BTCR DID - public String getBtcrDidResolve() throws IOException { + public String resolve() throws IOException { this.endpoint = new URL(this.root, "txref/" + this.txRef + "/resolve"); - //String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/resolve"; - return new ResolveBTCRDID(this.endpoint).resolve(); + /* + 1. mock to return json from https://btcr-service.opdup.com/txref/txtest1:x705-jzv2-qqaz-7vuz/txid + 2. get the tx details from https://btcr-service.opdup.com/tx//txid + 3. Check by hitting /tip, if there is a tip, if there isn't on then go to 4, else goto 5 + 4. From the transaction received, find the pubkey in the scriptSig + 5. Show that the DID is revoked + + */ + return new Resolve(this.endpoint).resolve(); + } + + // Get Tx Details + public String getTxDetails() throws IOException { + this.endpoint = new URL(this.root, "txref/" + this.txRef + "/txid"); + return new TxDetails(this.endpoint).getTxDetails(); } // Following a tip public String getTip() throws IOException { this.endpoint = new URL(this.root, "txref/" + this.txRef + "/tip"); - //String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/tip"; return new Tip(this.endpoint).getTip(); } + // Get public key following a tip + public String getPublicKey() throws IOException { + this.endpoint = new URL(this.root, "txref/" + this.txRef + "/tip"); + return new Tip(this.endpoint).getPubKey(); + } + // Decode TxRef public String decode() throws IOException { this.endpoint = new URL(this.root, "txref/" + this.txRef + "/decode"); - //String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/decode"; return new Decode(this.endpoint).decode(); } // Get TxId from TxRef public String txIdFromTxref() throws IOException, JSONException { this.endpoint = new URL(this.root, "txref/" + this.txRef + "/txid"); - //String url = PROTOCOL + ADDRESS + ":" + PORT + "/txref/" + this.txRef + "/txid"; - return new TxIdFromTxRef(this.endpoint).getTxIdFromTxRef(); + return new TxDetails(this.endpoint).getTxIdFromTxRef(); } // Get Decoded Tx from TxId public String getDecodedTx() throws IOException, JSONException { String txId = txIdFromTxref(); this.endpoint = new URL(this.root, "tx/" + txId); - //String url = PROTOCOL + ADDRESS + ":" + PORT + "/tx" + txId; return new DecodedTx(this.endpoint).getTxFromTxId(); } diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Resolve.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Resolve.java index e7d1941..4886209 100644 --- a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Resolve.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Resolve.java @@ -3,11 +3,11 @@ import java.io.IOException; import java.net.URL; -public class ResolveBTCRDID { +public class Resolve { private URL url; - public ResolveBTCRDID(URL url){ + public Resolve(URL url){ this.url = url; } diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java index a6e1d7d..d0d288d 100644 --- a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java @@ -1,5 +1,8 @@ package com.opdup.btcrserviceclient; +import org.json.JSONArray; +import org.json.JSONObject; + import java.io.IOException; import java.net.URL; @@ -7,12 +10,36 @@ public class Tip { private URL url; + private JSONArray jsonArray; + private JSONObject jsonObject; + + private String tipJsonString; + public Tip(URL url){ this.url = url; } - public String getTip() throws IOException{ + public String getTip() throws IOException { return new ServiceConnection(this.url).getJsonString(); } + public String getPubKey() throws IOException { + this.tipJsonString = getTip(); + this.jsonArray = new JSONArray(tipJsonString); + String publicKey=null; + for (int i=0; i/txid + @Test + public void testTxDetails() throws IOException { + url = new URL("https://btcr-service.opdup.com/txref/txtest1:x705-jzv2-qqaz-7vuz/txid"); + serviceConnection = new ServiceConnection(url); + String jsonString = serviceConnection.getJsonString(); + + JSONObject jsonObject = new JSONObject(jsonString); + String txId = jsonObject.getString("txid"); + + System.out.println(txId); //print txid + + url = new URL("https://btcr-service.opdup.com/tx/" + txId); + serviceConnection = new ServiceConnection(url); + jsonString = serviceConnection.getJsonString(); + + System.out.println(jsonString); // tx details + assertTrue(!jsonString.isEmpty()); + assertEquals(jsonString, "{\"hex\":\"010000000151ace177cd6250209c9da1878e6d8058d04318125d30b1f3bc5c7471925d5f3e010000006b483045022100fca4787f193c3ec6929a6054e68352c4c085f36ac400832d901d33769084fc3c02205a56132832cfd08112740f044790e6976b3ea1bca76a4f99870eff276c9c9edc012102e0e01a8c302976e1556e95c54146e8464adac8626a5d29474718a7281133ff49ffffffff01a04bde03000000001976a9147055778c9993c43f422a0c963fdf7d2263a7a37188ac00000000\",\"txid\":\"80871cf043c1d96f3d716f5bc02daa15a5e534b2a00e81a530fb40aa07ceceb6\",\"hash\":\"80871cf043c1d96f3d716f5bc02daa15a5e534b2a00e81a530fb40aa07ceceb6\",\"size\":192,\"vsize\":192,\"version\":1,\"locktime\":0,\"vin\":[{\"txid\":\"3e5f5d9271745cbcf3b1305d121843d058806d8e87a19d9c205062cd77e1ac51\",\"vout\":1,\"scriptSig\":{\"asm\":\"3045022100fca4787f193c3ec6929a6054e68352c4c085f36ac400832d901d33769084fc3c02205a56132832cfd08112740f044790e6976b3ea1bca76a4f99870eff276c9c9edc01 02e0e01a8c302976e1556e95c54146e8464adac8626a5d29474718a7281133ff49\",\"hex\":\"483045022100fca4787f193c3ec6929a6054e68352c4c085f36ac400832d901d33769084fc3c02205a56132832cfd08112740f044790e6976b3ea1bca76a4f99870eff276c9c9edc012102e0e01a8c302976e1556e95c54146e8464adac8626a5d29474718a7281133ff49\"},\"sequence\":4294967295}],\"vout\":[{\"value\":0.649,\"n\":0,\"scriptPubKey\":{\"asm\":\"OP_DUP OP_HASH160 7055778c9993c43f422a0c963fdf7d2263a7a371 OP_EQUALVERIFY OP_CHECKSIG\",\"hex\":\"76a9147055778c9993c43f422a0c963fdf7d2263a7a37188ac\",\"reqSigs\":1,\"type\":\"pubkeyhash\",\"addresses\":[\"mqkvMtYfTufj3iEXjYHmnopZrsowMFxrKw\"]}}],\"blockhash\":\"0000000000000035b43f523828f38f5c97e5e34c524f7971940602d9c7d425ed\",\"confirmations\":57053,\"time\":1531769423,\"blocktime\":1531769423}"); + } + + @Test + public void testFollowTip() throws IOException { + mockResponse.setBody("{ Following tip }"); + mockWebServer.enqueue(mockResponse); + url = mockWebServer.url("/txref/" + this.txRef + "/tip").url(); + + serviceConnection = new ServiceConnection(url); + String jsonString = serviceConnection.getJsonString(); + assertTrue(!jsonString.isEmpty()); + assertEquals(jsonString, "{ Following tip }"); + } + + + //Test follow tip using https://btcr-service.opdup.com + @Test + public void testFollowTip2() throws IOException { + url = new URL("https://btcr-service.opdup.com/txref/txtest1:x705-jzv2-qqaz-7vuz/tip"); + serviceConnection = new ServiceConnection(url); + String jsonString = serviceConnection.getJsonString(); + JSONArray jsonArray = new JSONArray(jsonString); + for (int i=0; i Date: Mon, 10 Dec 2018 18:23:16 +0100 Subject: [PATCH 21/24] Add BTCRDIDResolverTester test Add BTCRDIDResolverTester test and modify getDDOForTxref method in BTCRDIDResolve class --- .../btcrserviceclient/BTCRDIDResolver.java | 92 ++++++++++++++++++- .../com/opdup/btcrserviceclient/Resolve.java | 20 ++++ .../btcrserviceclient/ServiceConnection.java | 15 ++- .../java/com/opdup/btcrserviceclient/Tip.java | 23 ++++- .../BTCRDIDResolverTester.java | 71 ++++++++++++++ 5 files changed, 211 insertions(+), 10 deletions(-) create mode 100644 btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/BTCRDIDResolverTester.java diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java index 2e8def6..eeb95aa 100644 --- a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java @@ -1,10 +1,13 @@ package com.opdup.btcrserviceclient; +import org.json.JSONArray; import org.json.JSONException; +import org.json.JSONObject; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.util.regex.Pattern; public class BTCRDIDResolver { @@ -18,6 +21,8 @@ public class BTCRDIDResolver { private String PORT = "8080"; private int TX_REF_SUBSTRING = 9; + //private static final Pattern pattern = Pattern.compile("^[^\\s]+ ([0-9a-fA-F]+)$"); //Pattern as in Universal Resolver + //Constructor public BTCRDIDResolver(String btcrDid) throws MalformedURLException { this.root = new URL(this.PROTOCOL, this.ADDRESS, this.PORT); @@ -38,13 +43,27 @@ public String resolve() throws IOException { 1. mock to return json from https://btcr-service.opdup.com/txref/txtest1:x705-jzv2-qqaz-7vuz/txid 2. get the tx details from https://btcr-service.opdup.com/tx//txid 3. Check by hitting /tip, if there is a tip, if there isn't on then go to 4, else goto 5 - 4. From the transaction received, find the pubkey in the scriptSig + 4. Fetch all transactions for the address in the txref by going to /resolve. + 4.1 From all the the transaction received, find the one matching the txid received from 7txid + 4.2 Find the pubkey in the scriptSig using the regular expression used by uniresolver 5. Show that the DID is revoked */ return new Resolve(this.endpoint).resolve(); } + //Resolve returning JSONObject + public JSONObject resolveJSONObject() throws IOException { + this.endpoint = new URL(this.root, "txref/" + this.txRef + "/resolve"); + return new Resolve(this.endpoint).resolveJSONObject(); + } + + //Resolve returning JSONArray + public JSONArray resolveJSONArray() throws IOException { + this.endpoint = new URL(this.root, "txref/" + this.txRef + "/resolve"); + return new Resolve(this.endpoint).resolveJSONArray(); + } + // Get Tx Details public String getTxDetails() throws IOException { this.endpoint = new URL(this.root, "txref/" + this.txRef + "/txid"); @@ -57,11 +76,11 @@ public String getTip() throws IOException { return new Tip(this.endpoint).getTip(); } - // Get public key following a tip + /*// Get public key following a tip public String getPublicKey() throws IOException { this.endpoint = new URL(this.root, "txref/" + this.txRef + "/tip"); return new Tip(this.endpoint).getPubKey(); - } + }*/ // Decode TxRef public String decode() throws IOException { @@ -94,4 +113,71 @@ private String getTxRef(String btcrDid){ return btcrDid.substring(TX_REF_SUBSTRING); } + //Get the TxId from the TxDetails class + private String getTxId() throws IOException{ + this.endpoint = new URL(this.root, "txref/" + this.txRef + "/txid"); + return new TxDetails(this.endpoint).getTxIdFromTxRef(); + } + + + public String getDDOForTxref() throws IOException { + + String pubKey = null; + String txid = getTxId(); + String tip = getTip(); + String asm = null; + + if (tip != null){ + return "BTCR DID couldn't be resolved"; + }else{ + + JSONArray allTxs = resolveJSONArray(); + JSONArray vin; + + JSONObject object; + JSONObject txObject; + JSONObject scriptSig = null; + JSONObject vinObject = null; + + String txIdString = null; + + for (int i = 0; i < allTxs.length(); i++){ + + object = allTxs.getJSONObject(i); + txObject = object.getJSONObject("Transaction"); + txIdString = txObject.getString("txid"); + + if (txIdString.equals(txid)){ + + vin = txObject.getJSONArray("vin"); + for (int j = 0; j < vin.length(); j++){ + vinObject = vin.getJSONObject(j); + scriptSig = vinObject.getJSONObject("scriptSig"); + } + + if (scriptSig == null){ + return null; + } + + asm = scriptSig.getString("asm"); + + if (asm == null){ + return null; + } + + String[] values = asm.split("\\s+"); + pubKey = values[1]; + + } + + } + + } + + /*loop over alltxs to find tx matching txid + use regexp matching to find pubkey in tx + return pubkyey for now*/ + return pubKey; + } + } diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Resolve.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Resolve.java index 4886209..3adda49 100644 --- a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Resolve.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Resolve.java @@ -1,5 +1,8 @@ package com.opdup.btcrserviceclient; +import org.json.JSONArray; +import org.json.JSONObject; + import java.io.IOException; import java.net.URL; @@ -11,9 +14,26 @@ public Resolve(URL url){ this.url = url; } + //Get String public String resolve() throws IOException { ServiceConnection serviceConnection = new ServiceConnection(this.url); return serviceConnection.getJsonString(); } + //Get JSONObject + public JSONObject resolveJSONObject() throws IOException { + ServiceConnection serviceConnection = new ServiceConnection(this.url); + return serviceConnection.getJsonObject(); + } + + //Get JSONArray + public JSONArray resolveJSONArray() throws IOException { + ServiceConnection serviceConnection = new ServiceConnection(this.url); + return serviceConnection.getJsonArray(); + } + + //public String getTxForTxid(String Txid){} + + //public String getPubKeyHex(String transaction){} + } \ No newline at end of file diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java index a6ec7ca..527d570 100644 --- a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java @@ -1,5 +1,6 @@ package com.opdup.btcrserviceclient; +import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -13,6 +14,7 @@ public class ServiceConnection { private URL url; private HttpURLConnection connection; + private String json = null; public ServiceConnection(URL url) throws IOException{ this.url = url; @@ -30,15 +32,22 @@ private void connect() throws IOException { } public String getJsonString() throws IOException { - String json = null; connect(); InputStream inputStream = connection.getInputStream(); - json = new Scanner(inputStream, "UTF-8").useDelimiter("\\Z").next(); - return json; + this.json = new Scanner(inputStream, "UTF-8").useDelimiter("\\Z").next(); + if (json == null){ + return "null"; + }else{ + return this.json; + } } public JSONObject getJsonObject() throws IOException, JSONException { return new JSONObject(getJsonString()); } + public JSONArray getJsonArray() throws IOException { + return new JSONArray(getJsonString()); + } + } \ No newline at end of file diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java index d0d288d..493982a 100644 --- a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java @@ -13,17 +13,32 @@ public class Tip { private JSONArray jsonArray; private JSONObject jsonObject; - private String tipJsonString; + private String tipJsonString = null; public Tip(URL url){ this.url = url; } - public String getTip() throws IOException { + private String getTipJsonString() throws IOException { return new ServiceConnection(this.url).getJsonString(); } - public String getPubKey() throws IOException { + public String getTip() throws IOException { + this.tipJsonString = getTipJsonString(); + this.jsonArray = new JSONArray(tipJsonString); + for (int i = 0; i Date: Tue, 18 Dec 2018 09:29:57 +0100 Subject: [PATCH 22/24] Add new tests on BTCRDIDResolverTest Add more tests on the BTCRDIDResolverTest class --- .../btcrserviceclient/BTCRDIDResolver.java | 31 +-- .../btcrserviceclient/ServiceConnection.java | 27 ++- .../java/com/opdup/btcrserviceclient/Tip.java | 19 -- .../BTCRDIDResolverTest.java | 180 ++++++++++++++++++ .../BTCRDIDResolverTester.java | 71 ------- ...Tester.java => ServiceConnectionTest.java} | 22 ++- 6 files changed, 222 insertions(+), 128 deletions(-) create mode 100644 btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/BTCRDIDResolverTest.java delete mode 100644 btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/BTCRDIDResolverTester.java rename btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/{ServiceConnectionTester.java => ServiceConnectionTest.java} (93%) diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java index eeb95aa..60c9fa2 100644 --- a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java @@ -7,7 +7,6 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; -import java.util.regex.Pattern; public class BTCRDIDResolver { @@ -21,8 +20,6 @@ public class BTCRDIDResolver { private String PORT = "8080"; private int TX_REF_SUBSTRING = 9; - //private static final Pattern pattern = Pattern.compile("^[^\\s]+ ([0-9a-fA-F]+)$"); //Pattern as in Universal Resolver - //Constructor public BTCRDIDResolver(String btcrDid) throws MalformedURLException { this.root = new URL(this.PROTOCOL, this.ADDRESS, this.PORT); @@ -30,7 +27,7 @@ public BTCRDIDResolver(String btcrDid) throws MalformedURLException { this.txRef = getTxRef(btcrDid); } - public BTCRDIDResolver(String btcrDid, URL rootURl) throws MalformedURLException { + public BTCRDIDResolver(String btcrDid, URL rootURl) { this.root = rootURl; this.btcrDid = btcrDid; this.txRef = getTxRef(btcrDid); @@ -76,27 +73,21 @@ public String getTip() throws IOException { return new Tip(this.endpoint).getTip(); } - /*// Get public key following a tip - public String getPublicKey() throws IOException { - this.endpoint = new URL(this.root, "txref/" + this.txRef + "/tip"); - return new Tip(this.endpoint).getPubKey(); - }*/ - // Decode TxRef public String decode() throws IOException { this.endpoint = new URL(this.root, "txref/" + this.txRef + "/decode"); return new Decode(this.endpoint).decode(); } - // Get TxId from TxRef - public String txIdFromTxref() throws IOException, JSONException { + //Get the TxId from the TxDetails class + public String getTxId() throws IOException{ this.endpoint = new URL(this.root, "txref/" + this.txRef + "/txid"); return new TxDetails(this.endpoint).getTxIdFromTxRef(); } // Get Decoded Tx from TxId public String getDecodedTx() throws IOException, JSONException { - String txId = txIdFromTxref(); + String txId = getTxId(); this.endpoint = new URL(this.root, "tx/" + txId); return new DecodedTx(this.endpoint).getTxFromTxId(); } @@ -107,19 +98,12 @@ public String getUtxosForAddress(String address) throws IOException { return new UtxosForAddress(this.endpoint).getUtxos(); } - //Get the TxRef from BTCR DID private String getTxRef(String btcrDid){ - return btcrDid.substring(TX_REF_SUBSTRING); + return "txtest1:" + btcrDid.substring(TX_REF_SUBSTRING); } - //Get the TxId from the TxDetails class - private String getTxId() throws IOException{ - this.endpoint = new URL(this.root, "txref/" + this.txRef + "/txid"); - return new TxDetails(this.endpoint).getTxIdFromTxRef(); - } - - + //Return public key public String getDDOForTxref() throws IOException { String pubKey = null; @@ -174,9 +158,6 @@ public String getDDOForTxref() throws IOException { } - /*loop over alltxs to find tx matching txid - use regexp matching to find pubkey in tx - return pubkyey for now*/ return pubKey; } diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java index 527d570..94ee749 100644 --- a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/ServiceConnection.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; +import java.net.SocketException; import java.net.URL; import java.util.Scanner; @@ -20,15 +21,21 @@ public ServiceConnection(URL url) throws IOException{ this.url = url; } - - private void connect() throws IOException { - this.connection = (HttpURLConnection) this.url.openConnection(); - this.connection.setDoOutput(true); - this.connection.setInstanceFollowRedirects(false); - this.connection.setRequestMethod("GET"); - this.connection.setRequestProperty("Content-Type", "application/json"); - this.connection.setRequestProperty("charset", "utf-8"); - this.connection.connect(); + private void connect() { + try { + this.connection = (HttpURLConnection) this.url.openConnection(); + this.connection.setDoOutput(true); + this.connection.setInstanceFollowRedirects(false); + this.connection.setRequestMethod("GET"); + this.connection.setRequestProperty("Content-Type", "application/json"); + this.connection.setRequestProperty("charset", "utf-8"); + //this.connection.setConnectTimeout(5000); //Connection timeout + this.connection.connect(); + } catch (SocketException e) { + System.err.print(e.getMessage()); + } catch (IOException e) { + System.err.print(e.getMessage()); + } } public String getJsonString() throws IOException { @@ -37,7 +44,7 @@ public String getJsonString() throws IOException { this.json = new Scanner(inputStream, "UTF-8").useDelimiter("\\Z").next(); if (json == null){ return "null"; - }else{ + } else { return this.json; } } diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java index 493982a..057fd4c 100644 --- a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/Tip.java @@ -38,23 +38,4 @@ public String getTip() throws IOException { return tipJsonString; } - /*public String getPubKey() throws IOException { - this.tipJsonString = getTip(); - this.jsonArray = new JSONArray(tipJsonString); - String publicKey=null; - for (int i=0; i Date: Wed, 9 Jan 2019 20:57:02 +0100 Subject: [PATCH 23/24] Add testGetUtxosForAddress method on BTCRDIDResolverTest class and build.gradle createJar task testGetUtxosForAddress method on BTCRDIDResolverTest class and on build.gradle add deleteJar and createJar task to create a jar file of the library that can be imported --- app/build.gradle | 2 +- btcrserviceclient/build.gradle | 15 +++++++++++- .../btcrserviceclient/BTCRDIDResolver.java | 10 -------- .../BTCRDIDResolverTest.java | 23 ++++++++++++++++--- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e562ae7..9ca5296 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,7 +22,7 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' - implementation 'com.google.code.gson:gson:2.7' + implementation 'com.google.code.gson:gson:2.8.5' testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-core:2.23.0' testImplementation 'com.squareup.okhttp3:mockwebserver:3.12.0' diff --git a/btcrserviceclient/build.gradle b/btcrserviceclient/build.gradle index 447aa19..a55e72f 100644 --- a/btcrserviceclient/build.gradle +++ b/btcrserviceclient/build.gradle @@ -2,12 +2,25 @@ apply plugin: 'java-library' dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.google.code.gson:gson:2.7' + implementation 'com.google.code.gson:gson:2.8.5' implementation 'org.json:json:20180813' testImplementation 'junit:junit:4.12' testImplementation 'org.mockito:mockito-core:2.23.0' testImplementation 'com.squareup.okhttp3:mockwebserver:3.12.0' } +task deleteJar(type: Delete) { + delete 'libs/jars/btcrserviceclientlib.jar' +} + +task createJar(type: Copy) { + from('build/intermediates/bundles/release/') + into('libs/jars/') + include('classes.jar') + rename('classes.jar', 'btcrserviceclientlib.jar') +} + +createJar.dependsOn(deleteJar, build) + sourceCompatibility = "7" targetCompatibility = "7" diff --git a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java index 60c9fa2..7b48145 100644 --- a/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java +++ b/btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/BTCRDIDResolver.java @@ -36,16 +36,6 @@ public BTCRDIDResolver(String btcrDid, URL rootURl) { // Resolve BTCR DID public String resolve() throws IOException { this.endpoint = new URL(this.root, "txref/" + this.txRef + "/resolve"); - /* - 1. mock to return json from https://btcr-service.opdup.com/txref/txtest1:x705-jzv2-qqaz-7vuz/txid - 2. get the tx details from https://btcr-service.opdup.com/tx//txid - 3. Check by hitting /tip, if there is a tip, if there isn't on then go to 4, else goto 5 - 4. Fetch all transactions for the address in the txref by going to /resolve. - 4.1 From all the the transaction received, find the one matching the txid received from 7txid - 4.2 Find the pubkey in the scriptSig using the regular expression used by uniresolver - 5. Show that the DID is revoked - - */ return new Resolve(this.endpoint).resolve(); } diff --git a/btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/BTCRDIDResolverTest.java b/btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/BTCRDIDResolverTest.java index a4c434f..f7d75b5 100644 --- a/btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/BTCRDIDResolverTest.java +++ b/btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/BTCRDIDResolverTest.java @@ -153,9 +153,15 @@ public void testGetTxId() throws IOException { @Test public void testGetDecodedTx() throws IOException { URL url; - //String txRef = "x705-jzv2-qqaz-7vuz"; + String txRef = "x705-jzv2-qqaz-7vuz"; String btcrDid = "btcr:did:x705-jzv2-qqaz-7vuz"; + //getTxid response + mockResponse.setBody("{\"txid\":\"80871cf043c1d96f3d716f5bc02daa15a5e534b2a00e81a530fb40aa07ceceb6\",\"utxo_index\":\"0\"}"); + mockWebServer.enqueue(mockResponse); + url = mockWebServer.url("/txref/" + txRef + "/txid").url(); + + String txid = "80871cf043c1d96f3d716f5bc02daa15a5e534b2a00e81a530fb40aa07ceceb6"; String response = "{\"hex\":\"010000000151ace177cd6250209c9da1878e6d8058d04318125d30b1f3bc5c7471925d5f3e010000006b483045022100fca4787f193c3ec6929a6054e68352c4c085f36ac400832d901d33769084fc3c02205a56132832cfd08112740f044790e6976b3ea1bca76a4f99870eff276c9c9edc012102e0e01a8c302976e1556e95c54146e8464adac8626a5d29474718a7281133ff49ffffffff01a04bde03000000001976a9147055778c9993c43f422a0c963fdf7d2263a7a37188ac00000000\",\"txid\":\"80871cf043c1d96f3d716f5bc02daa15a5e534b2a00e81a530fb40aa07ceceb6\",\"hash\":\"80871cf043c1d96f3d716f5bc02daa15a5e534b2a00e81a530fb40aa07ceceb6\",\"size\":192,\"vsize\":192,\"version\":1,\"locktime\":0,\"vin\":[{\"txid\":\"3e5f5d9271745cbcf3b1305d121843d058806d8e87a19d9c205062cd77e1ac51\",\"vout\":1,\"scriptSig\":{\"asm\":\"3045022100fca4787f193c3ec6929a6054e68352c4c085f36ac400832d901d33769084fc3c02205a56132832cfd08112740f044790e6976b3ea1bca76a4f99870eff276c9c9edc01 02e0e01a8c302976e1556e95c54146e8464adac8626a5d29474718a7281133ff49\",\"hex\":\"483045022100fca4787f193c3ec6929a6054e68352c4c085f36ac400832d901d33769084fc3c02205a56132832cfd08112740f044790e6976b3ea1bca76a4f99870eff276c9c9edc012102e0e01a8c302976e1556e95c54146e8464adac8626a5d29474718a7281133ff49\"},\"sequence\":4294967295}],\"vout\":[{\"value\":0.649,\"n\":0,\"scriptPubKey\":{\"asm\":\"OP_DUP OP_HASH160 7055778c9993c43f422a0c963fdf7d2263a7a371 OP_EQUALVERIFY OP_CHECKSIG\",\"hex\":\"76a9147055778c9993c43f422a0c963fdf7d2263a7a37188ac\",\"reqSigs\":1,\"type\":\"pubkeyhash\",\"addresses\":[\"mqkvMtYfTufj3iEXjYHmnopZrsowMFxrKw\"]}}],\"blockhash\":\"0000000000000035b43f523828f38f5c97e5e34c524f7971940602d9c7d425ed\",\"confirmations\":57053,\"time\":1531769423,\"blocktime\":1531769423}"; @@ -171,10 +177,21 @@ public void testGetDecodedTx() throws IOException { } // Test getUtxosForAddress - /*@Test + @Test public void testGetUtxosForAddress() throws IOException { URL url; String btcrDid = "btcr:did:x705-jzv2-qqaz-7vuz"; + String address = "mqkvMtYfTufj3iEXjYHmnopZrsowMFxrKw"; + String response = "[{\"hex\":\"010000000151ace177cd6250209c9da1878e6d8058d04318125d30b1f3bc5c7471925d5f3e010000006b483045022100fca4787f193c3ec6929a6054e68352c4c085f36ac400832d901d33769084fc3c02205a56132832cfd08112740f044790e6976b3ea1bca76a4f99870eff276c9c9edc012102e0e01a8c302976e1556e95c54146e8464adac8626a5d29474718a7281133ff49ffffffff01a04bde03000000001976a9147055778c9993c43f422a0c963fdf7d2263a7a37188ac00000000\",\"txid\":\"80871cf043c1d96f3d716f5bc02daa15a5e534b2a00e81a530fb40aa07ceceb6\",\"hash\":\"\",\"size\":\"\",\"vsize\":\"\",\"version\":1,\"locktime\":0,\"vin\":[{\"txid\":\"3e5f5d9271745cbcf3b1305d121843d058806d8e87a19d9c205062cd77e1ac51\",\"vout\":1,\"scriptSig\":{\"asm\":\"3045022100fca4787f193c3ec6929a6054e68352c4c085f36ac400832d901d33769084fc3c02205a56132832cfd08112740f044790e6976b3ea1bca76a4f99870eff276c9c9edc01 02e0e01a8c302976e1556e95c54146e8464adac8626a5d29474718a7281133ff49\",\"hex\":\"483045022100fca4787f193c3ec6929a6054e68352c4c085f36ac400832d901d33769084fc3c02205a56132832cfd08112740f044790e6976b3ea1bca76a4f99870eff276c9c9edc012102e0e01a8c302976e1556e95c54146e8464adac8626a5d29474718a7281133ff49\"},\"prevOut\":{\"addresses\":[\"mo8pqoxeu4EWSisZ8n94niyvPVJzDL3epg\"],\"value\":0.65},\"sequence\":4294967295}],\"vout\":[{\"value\":0.649,\"n\":0,\"scriptPubKey\":{\"asm\":\"OP_DUP OP_HASH160 7055778c9993c43f422a0c963fdf7d2263a7a371 OP_EQUALVERIFY OP_CHECKSIG\",\"hex\":\"76a9147055778c9993c43f422a0c963fdf7d2263a7a37188ac\",\"reqSigs\":1,\"type\":\"pubkeyhash\",\"addresses\":[\"mqkvMtYfTufj3iEXjYHmnopZrsowMFxrKw\"]}}],\"blockhash\":\"0000000000000035b43f523828f38f5c97e5e34c524f7971940602d9c7d425ed\",\"confirmations\":57053,\"time\":1531769423,\"blocktime\":1531769423},{\"hex\":\"010000000138c9b5aef6444e43697ec87cbe3c34fe54372f7b5200b19f224aaf0445b5ac6f000000006a47304402207126a4516a93f376c3fc3b8922f63ca95f0e472e43bc7c243e3e8d9a3fb070a7022030fa154fa3f56471e77006cb5b3823ea4c7f4c849dedd8ba7df0d5b43be524360121020a5a5c8c3575489cd2c17d43f642fc2b34792d47c9b026fafe33b3469e31b841ffffffff01e01dbe07000000001976a9147055778c9993c43f422a0c963fdf7d2263a7a37188ac00000000\",\"txid\":\"2f1838f481be7b4f4d37542a751aa3a27be7114f798feb24ff0fc764730973d0\",\"hash\":\"\",\"size\":\"\",\"vsize\":\"\",\"version\":1,\"locktime\":0,\"vin\":[{\"txid\":\"6facb54504af4a229fb100527b2f3754fe343cbe7cc87e69434e44f6aeb5c938\",\"vout\":0,\"scriptSig\":{\"asm\":\"304402207126a4516a93f376c3fc3b8922f63ca95f0e472e43bc7c243e3e8d9a3fb070a7022030fa154fa3f56471e77006cb5b3823ea4c7f4c849dedd8ba7df0d5b43be5243601 020a5a5c8c3575489cd2c17d43f642fc2b34792d47c9b026fafe33b3469e31b841\",\"hex\":\"47304402207126a4516a93f376c3fc3b8922f63ca95f0e472e43bc7c243e3e8d9a3fb070a7022030fa154fa3f56471e77006cb5b3823ea4c7f4c849dedd8ba7df0d5b43be524360121020a5a5c8c3575489cd2c17d43f642fc2b34792d47c9b026fafe33b3469e31b841\"},\"prevOut\":{\"addresses\":[\"n3oaLYUpxwEnQQS8zcX3zGiLUgFi5dH313\"],\"value\":1.3},\"sequence\":4294967295}],\"vout\":[{\"value\":1.299,\"n\":0,\"scriptPubKey\":{\"asm\":\"OP_DUP OP_HASH160 7055778c9993c43f422a0c963fdf7d2263a7a371 OP_EQUALVERIFY OP_CHECKSIG\",\"hex\":\"76a9147055778c9993c43f422a0c963fdf7d2263a7a37188ac\",\"reqSigs\":1,\"type\":\"pubkeyhash\",\"addresses\":[\"mqkvMtYfTufj3iEXjYHmnopZrsowMFxrKw\"]}}],\"blockhash\":\"000000000000005561a0b82b1dd8eefd1c3ba0cf674a67cf6699a3f66410df39\",\"confirmations\":57035,\"time\":1531778011,\"blocktime\":1531778011},{\"hex\":\"0100000001b6cece07aa40fb30a5810ea0b234e5a515aa2dc05b6f713d6fd9c143f01c8780000000006b483045022100ba6a336470cd220ccd62afaeda7a105677bb9e20c27080b67f0bada5c33698b202204f6d1f311244033be88e62c46a36bf0b8af9f91048e5313cf59929a9e2fdf1b4012103ceba0298eb4a026b9d9b1486c90c088a92e15892dd4c4044e3e6ad076c9b262fffffffff0100c5dc03000000001976a9145aeb70a7801a42c849732a2b36727c21f61793f988ac00000000\",\"txid\":\"be5be4b2c4e530b49af139a8448ae2ae8b5882f2e7f5c7908eca0268f72494e9\",\"hash\":\"\",\"size\":\"\",\"vsize\":\"\",\"version\":1,\"locktime\":0,\"vin\":[{\"txid\":\"80871cf043c1d96f3d716f5bc02daa15a5e534b2a00e81a530fb40aa07ceceb6\",\"vout\":0,\"scriptSig\":{\"asm\":\"3045022100ba6a336470cd220ccd62afaeda7a105677bb9e20c27080b67f0bada5c33698b202204f6d1f311244033be88e62c46a36bf0b8af9f91048e5313cf59929a9e2fdf1b401 03ceba0298eb4a026b9d9b1486c90c088a92e15892dd4c4044e3e6ad076c9b262f\",\"hex\":\"483045022100ba6a336470cd220ccd62afaeda7a105677bb9e20c27080b67f0bada5c33698b202204f6d1f311244033be88e62c46a36bf0b8af9f91048e5313cf59929a9e2fdf1b4012103ceba0298eb4a026b9d9b1486c90c088a92e15892dd4c4044e3e6ad076c9b262f\"},\"prevOut\":{\"addresses\":[\"mqkvMtYfTufj3iEXjYHmnopZrsowMFxrKw\"],\"value\":0.649},\"sequence\":4294967295}],\"vout\":[{\"value\":0.648,\"n\":0,\"scriptPubKey\":{\"asm\":\"OP_DUP OP_HASH160 5aeb70a7801a42c849732a2b36727c21f61793f9 OP_EQUALVERIFY OP_CHECKSIG\",\"hex\":\"76a9145aeb70a7801a42c849732a2b36727c21f61793f988ac\",\"reqSigs\":1,\"type\":\"pubkeyhash\",\"addresses\":[\"mooh9yq5aV4u5gSR9oRZGfYS9qbydBVLjA\"]}}],\"blockhash\":\"0000000000000011fd70846401c79e3b04ba2f0b75c6d160cbaae71287a9c1b7\",\"confirmations\":57032,\"time\":1531781125,\"blocktime\":1531781125}]"; + + mockResponse.setBody(response); + mockWebServer.enqueue(mockResponse); + url = mockWebServer.url("/addr/" + address + "/spends").url(); - }*/ + btcrdidResolver = new BTCRDIDResolver(btcrDid, url); + String utxos = btcrdidResolver.getUtxosForAddress(address); + + assertTrue(!utxos.isEmpty()); + assertEquals(response, utxos); + } } From 6f8ac3cb2b33f492de4f77eb59bdc03def0b55dd Mon Sep 17 00:00:00 2001 From: Francesco Micheli Date: Tue, 16 Jul 2019 16:27:03 +0200 Subject: [PATCH 24/24] Add DDO generation with JSONLD Add DDO generation using the jsonldjava Android library --- .gitignore | 1 + .idea/codeStyles/Project.xml | 29 - .idea/gradle.xml | 4 +- .idea/misc.xml | 38 +- btcrserviceclient/build.gradle | 48 +- btcrserviceclient/proguard-rules.pro | 21 + .../ExampleInstrumentedTest.java | 26 + .../src/main/AndroidManifest.xml | 7 + .../btcrserviceclient/BTCRDIDResolver.java | 181 +- .../java/com/opdup/btcrserviceclient/DDO.java | 134 ++ .../com/opdup/btcrserviceclient/Decode.java | 7 +- .../opdup/btcrserviceclient/DecodedTx.java | 10 +- .../com/opdup/btcrserviceclient/Resolve.java | 24 +- .../btcrserviceclient/ServiceConnection.java | 83 +- .../java/com/opdup/btcrserviceclient/Tip.java | 42 +- .../opdup/btcrserviceclient/TxDetails.java | 36 +- .../btcrserviceclient/UtxosForAddress.java | 6 +- .../src/main/res/values/strings.xml | 3 + .../btcrdidserviceclient/ExampleUnitTest.java | 17 + .../BTCRDIDResolverTest.java | 197 -- .../ServiceConnectionTest.java | 200 -- build.gradle | 13 +- gradle/wrapper/gradle-wrapper.properties | 2 +- jsonldjava/.gitignore | 1 + jsonldjava/build.gradle | 36 + jsonldjava/proguard-rules.pro | 21 + .../jsonldjava/ExampleInstrumentedTest.java | 26 + jsonldjava/src/main/AndroidManifest.xml | 2 + .../com/github/jsonldjava/core/Context.java | 1197 ++++++++++ .../jsonldjava/core/DocumentLoader.java | 58 + .../jsonldjava/core/IdentifierIssuer.java | 112 + .../com/github/jsonldjava/core/JsonLdApi.java | 2058 +++++++++++++++++ .../github/jsonldjava/core/JsonLdConsts.java | 65 + .../github/jsonldjava/core/JsonLdError.java | 142 ++ .../github/jsonldjava/core/JsonLdOptions.java | 222 ++ .../jsonldjava/core/JsonLdProcessor.java | 570 +++++ .../jsonldjava/core/JsonLdTripleCallback.java | 44 + .../github/jsonldjava/core/JsonLdUtils.java | 487 ++++ .../jsonldjava/core/NormalizeUtils.java | 627 +++++ .../github/jsonldjava/core/RDFDataset.java | 714 ++++++ .../jsonldjava/core/RDFDatasetUtils.java | 373 +++ .../com/github/jsonldjava/core/RDFParser.java | 47 + .../com/github/jsonldjava/core/Regex.java | 56 + .../jsonldjava/core/RemoteDocument.java | 84 + .../github/jsonldjava/core/UniqueNamer.java | 72 + .../com/github/jsonldjava/core/Urdna2015.java | 678 ++++++ .../jsonldjava/impl/NQuadRDFParser.java | 19 + .../jsonldjava/impl/NQuadTripleCallback.java | 12 + .../github/jsonldjava/utils/JsonLdUrl.java | 315 +++ .../jsonldjava/utils/JsonNormalizer.java | 50 + .../github/jsonldjava/utils/JsonUtils.java | 251 ++ .../java/com/github/jsonldjava/utils/Obj.java | 108 + jsonldjava/src/main/res/values/strings.xml | 3 + .../com/opdup/jsonldjava/ExampleUnitTest.java | 17 + settings.gradle | 3 +- 55 files changed, 8923 insertions(+), 676 deletions(-) delete mode 100644 .idea/codeStyles/Project.xml create mode 100644 btcrserviceclient/proguard-rules.pro create mode 100644 btcrserviceclient/src/androidTest/java/com/opdup/btcrdidserviceclient/ExampleInstrumentedTest.java create mode 100644 btcrserviceclient/src/main/AndroidManifest.xml create mode 100644 btcrserviceclient/src/main/java/com/opdup/btcrserviceclient/DDO.java create mode 100644 btcrserviceclient/src/main/res/values/strings.xml create mode 100644 btcrserviceclient/src/test/java/com/opdup/btcrdidserviceclient/ExampleUnitTest.java delete mode 100644 btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/BTCRDIDResolverTest.java delete mode 100644 btcrserviceclient/src/test/java/com/opdup/btcrserviceclient/ServiceConnectionTest.java create mode 100644 jsonldjava/.gitignore create mode 100644 jsonldjava/build.gradle create mode 100644 jsonldjava/proguard-rules.pro create mode 100644 jsonldjava/src/androidTest/java/com/opdup/jsonldjava/ExampleInstrumentedTest.java create mode 100644 jsonldjava/src/main/AndroidManifest.xml create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/Context.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/DocumentLoader.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/IdentifierIssuer.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/JsonLdApi.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/JsonLdConsts.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/JsonLdError.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/JsonLdOptions.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/JsonLdProcessor.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/JsonLdTripleCallback.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/JsonLdUtils.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/NormalizeUtils.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/RDFDataset.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/RDFDatasetUtils.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/RDFParser.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/Regex.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/RemoteDocument.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/UniqueNamer.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/core/Urdna2015.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/impl/NQuadRDFParser.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/impl/NQuadTripleCallback.java create mode 100755 jsonldjava/src/main/java/com/github/jsonldjava/utils/JsonLdUrl.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/utils/JsonNormalizer.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/utils/JsonUtils.java create mode 100644 jsonldjava/src/main/java/com/github/jsonldjava/utils/Obj.java create mode 100644 jsonldjava/src/main/res/values/strings.xml create mode 100644 jsonldjava/src/test/java/com/opdup/jsonldjava/ExampleUnitTest.java diff --git a/.gitignore b/.gitignore index fd45b12..ff69e6a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .gradle /local.properties /.idea/caches/build_file_checksums.ser +/.idea/caches /.idea/libraries /.idea/modules.xml /.idea/workspace.xml diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 30aa626..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index a13f9ca..0afeaa6 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -3,12 +3,14 @@