Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/dx-e2e-beta.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,33 @@ jobs:
channel: beta
journey: ${{ matrix.journey }}
github-token: ${{ secrets.GITHUB_TOKEN }}

java-sdk:
name: beta (ubuntu-24.04 · 12-java-sdk)
needs: warmup
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
cache: maven
- name: Require Maven 3.9
shell: bash
run: mvn -version | head -n1 | grep -Eq '^Apache Maven 3[.]9[.]'
- uses: ./.github/actions/dx-e2e-run
with:
channel: beta
journey: 12-java-sdk
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Require Java toolchain floors (no skipped coverage)
shell: bash
run: |
source lib/common.sh
channel_bin="${HOME}/.tx3/beta/bin"
tx3c_version="$("${channel_bin}/tx3c" --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)"
trix_version="$("${channel_bin}/trix" --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)"
[[ -n "${tx3c_version}" && -n "${trix_version}" ]] || die "could not read Java toolchain versions"
version_ge "${tx3c_version}" 0.25.0 || die "Java CI requires tx3c >= 0.25.0"
version_ge "${trix_version}" 0.28.0 || die "Java CI requires trix >= 0.28.0"
30 changes: 30 additions & 0 deletions .github/workflows/dx-e2e-stable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,33 @@ jobs:
channel: stable
journey: ${{ matrix.journey }}
github-token: ${{ secrets.GITHUB_TOKEN }}

java-sdk:
name: stable (ubuntu-24.04 · 12-java-sdk)
needs: warmup
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
cache: maven
- name: Require Maven 3.9
shell: bash
run: mvn -version | head -n1 | grep -Eq '^Apache Maven 3[.]9[.]'
- uses: ./.github/actions/dx-e2e-run
with:
channel: stable
journey: 12-java-sdk
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Require Java toolchain floors (no skipped coverage)
shell: bash
run: |
source lib/common.sh
channel_bin="${HOME}/.tx3/stable/bin"
tx3c_version="$("${channel_bin}/tx3c" --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)"
trix_version="$("${channel_bin}/trix" --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n1)"
[[ -n "${tx3c_version}" && -n "${trix_version}" ]] || die "could not read Java toolchain versions"
version_ge "${tx3c_version}" 0.25.0 || die "Java CI requires tx3c >= 0.25.0"
version_ge "${trix_version}" 0.28.0 || die "Java CI requires trix >= 0.28.0"
47 changes: 47 additions & 0 deletions journeys/12-java-sdk/JavaSdkJourney.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package e2e;

import java.math.BigInteger;
import java.net.URI;
import land.tx3.generated.demo.DemoClient;
import land.tx3.sdk.Address;
import land.tx3.sdk.CardanoSigner;
import land.tx3.sdk.ClientOptions;
import land.tx3.sdk.Party;
import land.tx3.sdk.PollConfig;

/** Host application for the generated Java client journey. */
public final class JavaSdkJourney {
// Public test vector from the Java SDK; funded only by this disposable devnet.
private static final String ALICE_MNEMONIC =
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon "
+ "abandon about";

private JavaSdkJourney() {}

/** Runs one generated-client transfer through confirmation. */
public static void main(String[] args) {
if (args.length != 3) {
throw new IllegalArgumentException(
"usage: JavaSdkJourney <trp-endpoint> <sender-address> <receiver-address>");
}

var sender = new Address(args[1]);
var signer = new CardanoSigner(ALICE_MNEMONIC, sender);
var client =
new DemoClient(ClientOptions.forEndpoint(URI.create(args[0])), DemoClient.Profile.LOCAL)
.withSender(Party.signer(signer))
.withReceiver(Party.address(new Address(args[2])));

var resolved =
client
.transfer(new DemoClient.TransferParams(BigInteger.valueOf(2_000_000)))
.resolve()
.join();
var submitted = resolved.sign().submit().join();
var confirmed = submitted.waitForConfirmed(PollConfig.defaults()).join();

System.out.printf(
"{\"hash\":\"%s\",\"stage\":\"%s\",\"confirmations\":%d}%n",
submitted.hash(), confirmed.stage().wireValue(), confirmed.confirmations());
}
}
34 changes: 34 additions & 0 deletions journeys/12-java-sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 12-java-sdk

The Java generated-client path with real released components: seed trix's
`java-client` plugin, render tx3c's built-in template, compile the generated
Maven project against `land.tx3:tx3-sdk:0.15.0`, and consume that installed
artifact from a separate Java 21 host project. The host then resolves, signs,
submits, and confirms a transfer through the generated `DemoClient` against a
disposable local devnet.

- **Scope:** runtime. The generated project and consumer use an isolated Maven
repository; normal released-channel validation downloads dependencies from
Maven Central without credentials. No preprod endpoint or secret is used.
- **Toolchain gate:** `#@ min-tx3c: 0.25.0`, the first tx3c release with the
built-in `java-client` template, and trix 0.28.0 or newer for the built-in
Java plugin registration that invokes `--template java-client`. The Java CI
jobs require both floors, so a below-floor skip cannot count as coverage.
- **Host baseline:** CI runs only on `ubuntu-24.04` with Temurin 21 and Maven
3.9. A local run without Java/Maven skips; CI treats either missing tool as a
failure so absent prerequisites cannot count as coverage.
- **Identity:** the checked-in phrase and address are the Java SDK's public,
checksum-verified CIP-1852 test vector. The address is funded only by this
disposable devnet; the phrase is never a live credential. The receiver is
trix's deterministic `bob` identity.

Run from the e2e root with `./run.sh --channel stable --journey 12-java-sdk`
or `./run.sh --channel beta --journey 12-java-sdk`. With explicit compatible
`TX3_*_PATH` binaries, use `./run.sh --local --journey 12-java-sdk`.
Failure logs and the consumer workdir are preserved by the harness; devnet
cleanup targets only this journey's unique configuration path.

For reviewed pre-publication testing, install `0.15.0-SNAPSHOT` into an isolated
Maven repository, set `TX3_JAVA_M2_REPO` to that directory, and set
`TX3_JAVA_SDK_VERSION=0.15.0-SNAPSHOT`. The released-channel acceptance path
leaves both overrides unset and resolves `0.15.0` from Maven Central.
4 changes: 4 additions & 0 deletions journeys/12-java-sdk/devnet.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Checksum-verified Java SDK signer vector, funded only inside this disposable devnet.
[[utxos]]
address = "addr_test1vq8ac7qqy0vtulyl7wntmsxc6wex80gvcyjy33qffrhm7ss9hjl0y"
value = 100000000000
114 changes: 114 additions & 0 deletions journeys/12-java-sdk/journey.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#!/usr/bin/env bash
#
# Journey 12 — generated Java SDK client. See README.md for coverage.
# Run via e2e/run.sh, which provides $TRIX and an isolated working directory.
#
#@ min-tx3c: 0.25.0

source "${E2E_LIB:?E2E_LIB not set — run this journey via e2e/run.sh}"

JOURNEY_HOME="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"

journey_begin "12-java-sdk" "generate a Java client → compile a clean consumer → resolve, sign, submit, and confirm (devnet)"

# Java and Maven are host infrastructure. GitHub's selected job installs both;
# a missing CI prerequisite is a failure, while a developer without Java may
# still run the rest of the repository's journeys.
if ! command -v java >/dev/null 2>&1 || ! command -v mvn >/dev/null 2>&1; then
if [[ -n "${CI:-}" ]]; then
die "java and Maven are required for the selected Java SDK CI journey"
fi
skip "java/Maven not found — skipping Java SDK journey"
journey_end
exit 0
fi

java -version 2>&1 | head -n1 | grep -Eq 'version "21([.]|\")' \
|| die "Java 21 is required for the Java SDK journey"
mvn -version | head -n1 | grep -Eq '^Apache Maven 3[.]9[.]' \
|| die "Maven 3.9 is required for the Java SDK journey"

# 1. Scaffold under a stable name so the generated package and artifact are
# deterministic (`land.tx3.generated.demo.DemoClient`, `demo-client`).
mkdir demo && cd demo
run_cmd "trix init -y — scaffold a new project" "${TRIX}" init -y

# 2. Generate through trix's built-in plugin registration. tx3c renders the
# built-in java-client template; a download would violate released-channel
# hermeticity.
run_cmd "trix codegen --plugin java-client — generate bindings" \
"${TRIX}" codegen --plugin java-client
assert_output_contains "Added [[codegen]]" "plugin entry seeded into trix.toml"
assert_output_contains "Bindgen successful for 'demo'"
grep -qiF "Reading template from" "${LAST_OUTPUT_FILE}" \
&& die "built-in plugin downloaded templates instead of using tx3c's built-in template"
ok "built-in Java template rendered by tx3c, no template download"

GENERATED=".tx3/codegen/java-client/demo"
assert_exists "${GENERATED}/pom.xml" "generated Maven project exists"
assert_exists "${GENERATED}/src/main/java/land/tx3/generated/demo/DemoClient.java" \
"typed DemoClient source exists"
[[ -e ".tx3/codegen/java-client/pom.xml" ]] \
&& die "generated Maven project leaked outside the per-protocol subdir"

run_cmd "read the generated Java client" \
cat "${GENERATED}/src/main/java/land/tx3/generated/demo/DemoClient.java"
assert_output_contains 'PROTOCOL_NAME = "demo"' "protocol identity embedded"
assert_output_contains "TRANSFER_TIR" "transfer TIR envelope embedded"
assert_output_contains "class DemoClient" "typed Java client wrapper emitted"

# 3. Compile the generated project against the released SDK in a fresh local
# repository, then install only that generated artifact for the host fixture.
# An explicit override supports reviewed pre-publication snapshot validation.
M2_REPO="${TX3_JAVA_M2_REPO:-${PWD}/m2}"
SDK_VERSION="${TX3_JAVA_SDK_VERSION:-0.15.0}"
run_cmd "mvn verify — compile the generated Maven project" \
mvn -B -ntp -Dmaven.repo.local="${M2_REPO}" \
-Dtx3.sdk.version="${SDK_VERSION}" -f "${GENERATED}/pom.xml" verify
run_cmd "mvn install — stage generated client for a clean consumer" \
mvn -B -ntp -Dmaven.repo.local="${M2_REPO}" \
-Dtx3.sdk.version="${SDK_VERSION}" -DskipTests \
-f "${GENERATED}/pom.xml" install

mkdir app
cp "${JOURNEY_HOME}/pom.xml" app/
mkdir -p app/src/main/java/e2e
cp "${JOURNEY_HOME}/JavaSdkJourney.java" app/src/main/java/e2e/
run_cmd "mvn verify — compile the clean host consumer" \
mvn -B -ntp -Dmaven.repo.local="${M2_REPO}" \
-Dtx3.sdk.version="${SDK_VERSION}" -f app/pom.xml verify
run_cmd "mvn dependency:build-classpath — resolve the consumer runtime" \
mvn -B -ntp -Dmaven.repo.local="${M2_REPO}" \
-Dtx3.sdk.version="${SDK_VERSION}" -Dmdep.outputFile=target/classpath.txt \
-f app/pom.xml dependency:build-classpath

# 4. Fund the Java SDK's checksum-verified CIP-1852 test identity. trix's
# conventional wallets intentionally use a different root-key scheme, so this
# explicit fixture keeps signer/address binding honest while remaining local.
cp "${JOURNEY_HOME}/devnet.toml" devnet.toml
ALICE="addr_test1vq8ac7qqy0vtulyl7wntmsxc6wex80gvcyjy33qffrhm7ss9hjl0y"
BOB="$("${TRIX}" identities bob address-testnet 2>/dev/null | grep '^addr' | head -n1)"
[[ -n "${ALICE}" && -n "${BOB}" ]] || die "could not resolve alice/bob testnet addresses"

DEVNET_HOME="${PWD}/.tx3/dolos"
cleanup_devnet() {
# Match this journey's unique configuration path, including on startup failure.
pkill -f "dolos.*${DEVNET_HOME}/dolos[.]toml daemon" >/dev/null 2>&1 || true
}
trap cleanup_devnet EXIT
run_cmd "trix devnet --background — start a local devnet" "${TRIX}" devnet --background
assert_output_contains "devnet started in background"
for _ in $(seq 1 30); do
(exec 3<>/dev/tcp/127.0.0.1/8164) 2>/dev/null && { exec 3>&- 3<&-; break; }
sleep 1
done
sleep 3

CLASSPATH="app/target/classes:$(cat app/target/classpath.txt)"
run_cmd "JavaSdkJourney — resolve, sign, submit, and confirm through the generated client" \
java -cp "${CLASSPATH}" e2e.JavaSdkJourney \
"http://127.0.0.1:8164" "${ALICE}" "${BOB}"
assert_output_contains '"stage":"confirmed"' "submitted transaction confirmed"
assert_output_contains '"hash":' "confirmed transaction carries a hash"

journey_end
40 changes: 40 additions & 0 deletions journeys/12-java-sdk/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>land.tx3.e2e</groupId>
<artifactId>java-sdk-journey</artifactId>
<version>0.0.0-SNAPSHOT</version>

<properties>
<maven.compiler.release>21</maven.compiler.release>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tx3.sdk.version>0.15.0</tx3.sdk.version>
</properties>

<dependencies>
<dependency>
<groupId>land.tx3.generated</groupId>
<artifactId>demo-client</artifactId>
<version>0.0.0-SNAPSHOT</version>
</dependency>
<!-- Direct so the snapshot override also wins over the generated POM's release default. -->
<dependency>
<groupId>land.tx3</groupId>
<artifactId>tx3-sdk</artifactId>
<version>${tx3.sdk.version}</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.16.0</version>
</plugin>
</plugins>
</build>
</project>
Loading