diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..2e93271a
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,22 @@
+os: linux
+dist: bionic
+language: generic
+addons:
+ apt:
+ packages:
+ - libxml-xpath-perl
+services:
+ - docker
+
+env:
+ global:
+ - CONTAINER_JAVA_VER="openjdk-8-jdk=8u252-b09-1~16.04"
+ - CONTAINER_RUST_VER="1.41.0"
+
+script: >-
+ source ci/setup_env.sh &&
+ docker build --pull --no-cache -t zencash/zendoo-sc-cryptolib-builder ./ci &&
+ bash -c "docker run --rm -v $(pwd):/build -v ${HOME}/key.asc:/key.asc --tmpfs /tmp:uid=$(id -u),gid=$(id -g),exec,mode=1777 \
+ --tmpfs /run:uid=$(id -u),gid=$(id -g),exec,mode=1777 -e LOCAL_USER_ID=$(id -u) -e LOCAL_GRP_ID=$(id -g) \
+ $(env | grep -E '^CONTAINER_' | sed -n '/^[^\t]/s/=.*//p' | sed '/^$/d' | sed 's/^/-e /g' | tr '\n' ' ') \
+ zencash/zendoo-sc-cryptolib-builder /build/ci/start_ci.sh"
diff --git a/build_jar.sh b/build_jar.sh
deleted file mode 100644
index a7c9777c..00000000
--- a/build_jar.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-cargo clean
-
-cargo build --release --target=x86_64-pc-windows-gnu
-cargo build --release --target=x86_64-unknown-linux-gnu
-
-
-mkdir -p jni/src/main/resources/native/linux64
-cp target/x86_64-unknown-linux-gnu/release/libzendoo_sc.so jni/src/main/resources/native/linux64/libzendoo_sc.so
-
-mkdir -p jni/src/main/resources/native/windows64
-cp target/x86_64-pc-windows-gnu/release/zendoo_sc.dll jni/src/main/resources/native/windows64/zendoo_sc.dll
-
-cd jni
-mvn clean package
diff --git a/ci/.dockerignore b/ci/.dockerignore
new file mode 100644
index 00000000..3f558562
--- /dev/null
+++ b/ci/.dockerignore
@@ -0,0 +1,2 @@
+*
+!entrypoint*
diff --git a/ci/Dockerfile b/ci/Dockerfile
new file mode 100644
index 00000000..6d257b64
--- /dev/null
+++ b/ci/Dockerfile
@@ -0,0 +1,57 @@
+FROM ubuntu:16.04
+
+MAINTAINER infrastructure@zensystem.io
+
+SHELL ["/bin/bash", "-c"]
+
+COPY entrypoint.sh entrypoint_setup_gpg.sh /usr/local/bin/
+
+# Get Ubuntu packages
+RUN set -eux && export GOSU_VERSION=1.12 && export DEBIAN_FRONTEND=noninteractive \
+ && apt-get update \
+ && apt-get install -y --no-install-recommends build-essential ca-certificates curl dirmngr \
+ gcc-mingw-w64-x86-64 gnupg2 gnupg-curl wget; \
+# save list of currently installed packages for later so we can clean up
+ savedAptMark="$(apt-mark showmanual)"; \
+ apt-get update; \
+ apt-get install -y --no-install-recommends ca-certificates wget; \
+ if ! command -v gpg; then \
+ apt-get install -y --no-install-recommends gnupg2 dirmngr; \
+ elif gpg --version | grep -q '^gpg (GnuPG) 1\.'; then \
+# "This package provides support for HKPS keyservers." (GnuPG 1.x only)
+ apt-get install -y --no-install-recommends gnupg-curl; \
+ fi; \
+ rm -rf /var/lib/apt/lists/*; \
+ \
+ dpkgArch="$(dpkg --print-architecture | awk -F- '{ print $NF }')"; \
+ wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch"; \
+ wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$dpkgArch.asc"; \
+ \
+# verify the signature
+ export GNUPGHOME="$(mktemp -d)"; \
+ gpg2 --batch --keyserver hkps://keys.openpgp.org --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \
+ gpg2 --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \
+ gpg2 --batch --keyserver hkp://ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \
+ gpg2 --batch --keyserver pgp.mit.edu --recv-key B42F6819007F00F88E364FD4036A9C25BF357DD4 || \
+ gpg2 --batch --keyserver keyserver.pgp.com --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 || \
+ gpg2 --batch --keyserver pgp.key-server.io --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4; \
+ gpg2 --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu; \
+ command -v gpgconf && gpgconf --kill all || :; \
+ rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc; \
+ \
+# clean up fetch dependencies
+ apt-mark auto '.*' > /dev/null; \
+ [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; \
+ apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
+ \
+ chmod +x /usr/local/bin/gosu; \
+# verify that the binary works
+ gosu --version; \
+ gosu nobody true \
+ && chmod +x /usr/local/bin/{entrypoint.sh,entrypoint_setup_gpg.sh} \
+ && apt-get -y clean \
+ && apt-get -y autoclean \
+ && rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*.deb
+
+ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
+
diff --git a/ci/build_jar.sh b/ci/build_jar.sh
new file mode 100755
index 00000000..af708528
--- /dev/null
+++ b/ci/build_jar.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+set -euo pipefail
+
+cargo clean
+
+cargo build -j$(($(nproc)+1)) --release --target=x86_64-pc-windows-gnu
+cargo build -j$(($(nproc)+1)) --release --target=x86_64-unknown-linux-gnu
+
+mkdir -p jni/src/main/resources/native/linux64
+cp target/x86_64-unknown-linux-gnu/release/libzendoo_sc.so jni/src/main/resources/native/linux64/libzendoo_sc.so
+
+mkdir -p jni/src/main/resources/native/windows64
+cp target/x86_64-pc-windows-gnu/release/zendoo_sc.dll jni/src/main/resources/native/windows64/zendoo_sc.dll
+
+cd jni
+echo "Building jar"
+mvn clean package -P !build-extras -DskipTests=true -Dmaven.javadoc.skip=true -B
+echo "Testing jar"
+mvn test -P !build-extras -B
+
+if [ "$CONTAINER_PUBLISH" = "true" ]; then
+ echo "Deploying bundle to maven repository"
+ mvn deploy -P sign,build-extras --settings ../ci/mvn_settings.xml -B
+fi
diff --git a/ci/devtools/lint_pom.xml.sh b/ci/devtools/lint_pom.xml.sh
new file mode 100755
index 00000000..f46f51b9
--- /dev/null
+++ b/ci/devtools/lint_pom.xml.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+CONTENT="$(xmllint --format --encode UTF-8 jni/pom.xml)"
+echo "${CONTENT}" > jni/pom.xml
+
+SETTINGS_CONTENT="$(xmllint --format --encode UTF-8 ci/mvn_settings.xml)"
+echo "${SETTINGS_CONTENT}" > ci/mvn_settings.xml
diff --git a/ci/entrypoint.sh b/ci/entrypoint.sh
new file mode 100755
index 00000000..ecddd683
--- /dev/null
+++ b/ci/entrypoint.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+set -euo pipefail
+
+# check required vars are set
+if [ -z "${CONTAINER_JAVA_VER+x}" ] && [ -z "${CONTAINER_RUST_VER+x}" ]; then
+ echo "CONTAINER_JAVA_VER and CONTAINER_RUST_VER environment variables need to be set!"
+ exit 1
+fi
+
+# Add local zenbuilder user
+# Either use LOCAL_USER_ID:LOCAL_GRP_ID if set via environment
+# or fallback to 9001:9001
+
+USER_ID=${LOCAL_USER_ID:-2000}
+GRP_ID=${LOCAL_GRP_ID:-2000}
+
+getent group zenbuilder > /dev/null 2>&1 || groupadd -g $GRP_ID zenbuilder
+id -u zenbuilder > /dev/null 2>&1 || useradd --shell /bin/bash -u $USER_ID -g $GRP_ID -o -c "" -m zenbuilder
+
+LOCAL_UID=$(id -u zenbuilder)
+LOCAL_GID=$(getent group zenbuilder | cut -d ":" -f 3)
+
+if [ ! "$USER_ID" == "$LOCAL_UID" ] || [ ! "$GRP_ID" == "$LOCAL_GID" ]; then
+ echo "Warning: User zenbuilder with differing UID $LOCAL_UID/GID $LOCAL_GID already exists, most likely this container was started before with a different UID/GID. Re-create it to change UID/GID."
+fi
+
+echo "Starting with UID/GID: $LOCAL_UID:$LOCAL_GID"
+
+export HOME=/home/zenbuilder
+
+# Get Java $CONTAINER_JAVA_VER
+apt-get update
+DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y "$CONTAINER_JAVA_VER" maven
+apt-get -y clean
+apt-get -y autoclean
+rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/*.deb
+
+# Get Rust $CONTAINER_RUST_VER
+curl https://sh.rustup.rs -sSf | gosu zenbuilder bash -s -- --default-toolchain none -y
+gosu zenbuilder echo 'source $HOME/.cargo/env' >> $HOME/.bashrc
+export PATH="/home/zenbuilder/.cargo/bin:${PATH}"
+gosu zenbuilder rustup toolchain install "$CONTAINER_RUST_VER"
+gosu zenbuilder rustup target add --toolchain "$CONTAINER_RUST_VER" x86_64-pc-windows-gnu
+# fix "error: could not compile `api`." "/usr/bin/ld: unrecognized option '--nxcompat'"
+# https://github.com/rust-lang/rust/issues/32859#issuecomment-284308455
+# appears to be fixed in rust 1.42.0
+gosu zenbuilder cat << EOF > $HOME/.cargo/config
+[target.x86_64-pc-windows-gnu]
+linker = "$(which x86_64-w64-mingw32-gcc)"
+EOF
+
+# Print version information
+gosu zenbuilder java -version
+gosu zenbuilder rustc --version
+
+# Fix ownership recursively
+chown -RH zenbuilder:zenbuilder /build
+
+exec gosu zenbuilder /usr/local/bin//entrypoint_setup_gpg.sh "$@"
+
diff --git a/ci/entrypoint_setup_gpg.sh b/ci/entrypoint_setup_gpg.sh
new file mode 100755
index 00000000..605b16d2
--- /dev/null
+++ b/ci/entrypoint_setup_gpg.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+set -euo pipefail
+
+if [ "${CONTAINER_PUBLISH}" = "true" ]; then
+ export GNUPGHOME="$(mktemp -d 2>/dev/null || mktemp -d -t 'GNUPGHOME')"
+ # gpg: setting pinentry mode 'loopback' failed: Not supported https://www.fluidkeys.com/tweak-gpg-2.1.11/
+ echo "allow-loopback-pinentry" > "${GNUPGHOME}"/gpg-agent.conf
+ gpg2 --batch --fast-import /key.asc
+fi
+
+exec "$@"
diff --git a/ci/mvn_settings.xml b/ci/mvn_settings.xml
new file mode 100644
index 00000000..cb6433d4
--- /dev/null
+++ b/ci/mvn_settings.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ ossrh
+ ${env.CONTAINER_OSSRH_JIRA_USERNAME}
+ ${env.CONTAINER_OSSRH_JIRA_PASSWORD}
+
+
+
+
+ ossrh
+
+ true
+
+
+ gpg2
+ ${env.CONTAINER_GPG_KEY_NAME}
+ ${env.CONTAINER_GPG_PASSPHRASE}
+
+
+
+
diff --git a/ci/setup_env.sh b/ci/setup_env.sh
new file mode 100755
index 00000000..1657041d
--- /dev/null
+++ b/ci/setup_env.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+set -eo pipefail
+
+pom_version="$(xpath -q -e '/project/version/text()' jni/pom.xml)"
+
+echo "TRAVIS_TAG: $TRAVIS_TAG"
+echo "jni/pom.xml version: $pom_version"
+
+export CONTAINER_PUBLISH="false"
+# empty key.asc file in case we're not signing
+touch "${HOME}/key.asc"
+
+if [ ! -z "${TRAVIS_TAG}" ]; then
+ export GNUPGHOME="$(mktemp -d 2>/dev/null || mktemp -d -t 'GNUPGHOME')"
+ echo "Tagged build, fetching maintainer keys."
+ gpg -v --batch --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys $MAINTAINER_KEYS ||
+ gpg -v --batch --keyserver hkp://ipv4.pool.sks-keyservers.net --recv-keys $MAINTAINER_KEYS ||
+ gpg -v --batch --keyserver hkp://pgp.mit.edu:80 --recv-keys $MAINTAINER_KEYS
+ if git verify-tag -v "${TRAVIS_TAG}"; then
+ echo "Valid signed tag"
+ if [ "${TRAVIS_TAG}" != "${pom_version}" ]; then
+ echo "Aborting, tag differs from the pom file."
+ exit 1
+ else
+ export CONTAINER_PUBLISH="true"
+ echo "Fetching gpg signing keys."
+ curl -sLH "Authorization: token $GITHUB_TOKEN" -H "Accept: application/vnd.github.v3.raw" "$MAVEN_KEY_ARCHIVE_URL" |
+ openssl enc -d -aes-256-cbc -md sha256 -pass pass:$MAVEN_KEY_ARCHIVE_PASSWORD |
+ tar -xzf- -C "${HOME}"
+ fi
+ fi
+fi
+
+# unset credentials if not publishing
+if [ "${CONTAINER_PUBLISH}" = "false" ]; then
+ export CONTAINER_OSSRH_JIRA_USERNAME=""
+ export CONTAINER_OSSRH_JIRA_PASSWORD=""
+ export CONTAINER_GPG_KEY_NAME=""
+ export CONTAINER_GPG_PASSPHRASE=""
+ unset CONTAINER_OSSRH_JIRA_USERNAME
+ unset CONTAINER_OSSRH_JIRA_PASSWORD
+ unset CONTAINER_GPG_KEY_NAME
+ unset CONTAINER_GPG_PASSPHRASE
+fi
+
+# unset credentials after use
+export GITHUB_TOKEN=""
+export MAVEN_KEY_ARCHIVE_URL=""
+export MAVEN_KEY_ARCHIVE_PASSWORD=""
+unset GITHUB_TOKEN
+unset MAVEN_KEY_ARCHIVE_URL
+unset MAVEN_KEY_ARCHIVE_PASSWORD
+
+set +eo pipefail
diff --git a/ci/start_ci.sh b/ci/start_ci.sh
new file mode 100755
index 00000000..1a0aeb5f
--- /dev/null
+++ b/ci/start_ci.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -eo pipefail
+
+echo "execute the build script $(date)"
+
+cd /build && ./ci/build_jar.sh
+
+echo "done $(date)"
diff --git a/jni/pom.xml b/jni/pom.xml
index 38cdde35..0482cbd6 100644
--- a/jni/pom.xml
+++ b/jni/pom.xml
@@ -1,57 +1,165 @@
+
- 4.0.0
- com.horizen
- zendoo-sc-cryptolib
- 0.2-SNAPSHOT
- 2020
-
- UTF-8
- 1.8
- 1.8
- 2.12.8
-
-
-
-
-
- junit
- junit
- 4.12
- test
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.8.0
-
-
-
-
- org.apache.maven.plugins
- maven-dependency-plugin
- 3.1.1
-
-
- copy-dependencies
- package
-
- copy-dependencies
-
-
- ${project.build.directory}/lib
- false
- false
- true
- compile
-
-
-
-
-
-
+ 4.0.0
+ io.horizen
+ zendoo-sc-cryptolib
+ 0.3.0
+ 2020
+ jar
+ ${project.groupId}:${project.artifactId}
+ ${project.artifactId} is a Rust crate that exposes to Java, through JNI, the ginger-lib components needed by the Zendoo sidechain SDK.
+ https://github.com/${project.github.organization}/${project.artifactId}
+
+
+ MIT License
+ https://opensource.org/licenses/MIT
+
+
+
+
+ Zen Blockchain Foundation
+ info@zensystem.io
+ ${project.github.organization}
+ https://github.com/${project.github.organization}
+
+
+
+ scm:git:git://github.com/${project.github.organization}/${project.artifactId}.git
+ scm:git:git@github.com:${project.github.organization}/${project.artifactId}.git
+ https://github.com/${project.github.organization}/${project.artifactId}.git
+ ${project.version}
+
+
+ GitHub
+ https://github.com/${project.github.organization}/${project.artifactId}/issues
+
+
+
+ ossrh
+ https://oss.sonatype.org/content/repositories/snapshots
+
+
+
+ UTF-8
+ ZencashOfficial
+ 1.8
+ 1.8
+ 2.12.8
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
+
+ sign
+
+
+
+ org.apache.maven.plugins
+ maven-gpg-plugin
+ 1.6
+
+
+ sign-artifacts
+ verify
+
+ sign
+
+
+
+ --pinentry-mode
+ loopback
+ --no-tty
+
+
+
+
+
+
+
+
+
+ build-extras
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 3.2.1
+
+
+ attach-sources
+
+ jar-no-fork
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.2.0
+
+
+ attach-javadocs
+
+ jar
+
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.0
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.1.1
+
+
+ copy-dependencies
+ package
+
+ copy-dependencies
+
+
+ ${project.build.directory}/lib
+ false
+ false
+ true
+ compile
+
+
+
+
+
+ org.sonatype.plugins
+ nexus-staging-maven-plugin
+ 1.6.8
+ true
+
+ ossrh
+ https://oss.sonatype.org/
+ true
+
+
+
+