Build 53: Windows + Android support with a per-platform Nym sidecar
Ship the bundled nym-socks5-client on Windows and Android, not just Linux: - sidecar.rs resolves the binary per platform — nym-socks5-client.exe on Windows; on Android the sidecar rides in the APK jniLibs as libnym_socks5_client.so and is launched from the native-library dir (the one exec-allowed path), located via NATIVE_LIBS_DIR. - Restore a vendored, statically-linked OpenSSL. Upstream Grim got this from arti's static feature; dropping arti for Nym took it with it, which broke Android/cross builds (no system OpenSSL for the target) and left desktop dynamically linked to libssl. Inert on Windows/macOS (SChannel/Security.fw). - android.sh bundles the sidecar into jniLibs per ABI; scripts/nym-android.sh cross-builds it. Onboarding copy: Tor -> the Nym mixnet. Verified end to end on an x86_64 emulator: the sidecar extracts, launches, initialises, and opens the mixnet SOCKS5 proxy on 127.0.0.1:1080.
This commit is contained in:
Generated
+11
@@ -3265,6 +3265,7 @@ dependencies = [
|
||||
"nostr-relay-pool",
|
||||
"nostr-sdk",
|
||||
"num-bigint 0.4.6",
|
||||
"openssl",
|
||||
"parking_lot 0.12.5",
|
||||
"pin-project",
|
||||
"qrcode",
|
||||
@@ -6118,6 +6119,15 @@ version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-src"
|
||||
version = "300.6.1+3.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46eb8fb9fb3b61ce1c0f8a026c4c1a0714d3a9e138e7fbde78753ce2babc3846"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.111"
|
||||
@@ -6126,6 +6136,7 @@ checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"openssl-src",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
@@ -87,6 +87,13 @@ bytes = "1.11.0"
|
||||
hyper-socks2 = "0.9.1"
|
||||
hyper-proxy2 = "0.1.0"
|
||||
hyper-tls = "0.6.0"
|
||||
## native-tls (via hyper-tls) uses OpenSSL on Linux/Android. Upstream Grim got a
|
||||
## vendored, statically-linked OpenSSL for free through arti's `static` feature;
|
||||
## dropping arti for Nym took that with it, breaking Android/cross builds (no
|
||||
## system OpenSSL for the target) and leaving desktop dynamically linked to
|
||||
## libssl. Restore the vendored build so every target is self-contained. Inert on
|
||||
## Windows/macOS, which use SChannel / Security.framework instead of OpenSSL.
|
||||
openssl = { version = "0.10", features = ["vendored"] }
|
||||
async-std = "1.13.2"
|
||||
uuid = { version = "0.8.2", features = ["v4"] }
|
||||
num-bigint = "0.4.6"
|
||||
|
||||
@@ -48,6 +48,22 @@ function build_lib() {
|
||||
|
||||
sed -i -e 's/"cdylib","rlib"]/"rlib"]/g' Cargo.toml
|
||||
rm -f Cargo.toml-e
|
||||
|
||||
# Bundle the Nym SOCKS5 sidecar beside libgrim.so. Named lib*.so so Android
|
||||
# ships it in the APK's jniLibs and extracts it to the native-library dir —
|
||||
# the only exec-allowed location for a child process (manifest needs
|
||||
# extractNativeLibs=true). Built from the Nym workspace; see scripts/nym-android.sh.
|
||||
[[ $1 == "v7" ]] && nym_target=armv7-linux-androideabi
|
||||
[[ $1 == "v8" ]] && nym_target=aarch64-linux-android
|
||||
[[ $1 == "x86" ]] && nym_target=x86_64-linux-android
|
||||
nym_bin="${NYM_DIR:-../nym/target}/${nym_target}/release/nym-socks5-client"
|
||||
if [ -f "${nym_bin}" ]; then
|
||||
cp "${nym_bin}" "android/app/src/main/jniLibs/${arch}/libnym_socks5_client.so"
|
||||
echo "bundled Nym sidecar: jniLibs/${arch}/libnym_socks5_client.so"
|
||||
else
|
||||
echo "WARN: Nym sidecar missing at ${nym_bin} — APK will have NO mixnet sidecar"
|
||||
success=0
|
||||
fi
|
||||
}
|
||||
|
||||
### Build application
|
||||
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
# Cross-compile the bundled Nym SOCKS5 sidecar (nym-socks5-client) for Android.
|
||||
# scripts/android.sh copies the result into the APK's jniLibs as
|
||||
# libnym_socks5_client.so so Goblin can launch the mixnet client on-device.
|
||||
#
|
||||
# Usage: NYM_SRC=../nym scripts/nym-android.sh [v7|v8|x86|all]
|
||||
# NYM_SRC path to the Nym workspace checkout (default: ../nym)
|
||||
# Requires: ANDROID_NDK_HOME, rustup android targets, cargo-ndk.
|
||||
#
|
||||
# Note: the sidecar is patched to use preconfigured webpki roots on Android
|
||||
# (common/http-api-client/src/registry.rs) — the default rustls platform
|
||||
# verifier needs the app's JNI context, which a standalone process lacks.
|
||||
set -e
|
||||
|
||||
NYM_SRC="${NYM_SRC:-../nym}"
|
||||
WHICH="${1:-all}"
|
||||
|
||||
build() {
|
||||
local abi="$1"
|
||||
echo ">> building nym-socks5-client for ${abi}"
|
||||
( cd "${NYM_SRC}" && cargo ndk -t "${abi}" build --release -p nym-socks5-client )
|
||||
}
|
||||
|
||||
case "${WHICH}" in
|
||||
v7) build armeabi-v7a ;;
|
||||
v8) build arm64-v8a ;;
|
||||
x86) build x86_64 ;;
|
||||
all) build arm64-v8a; build x86_64; build armeabi-v7a ;;
|
||||
*) echo "usage: $0 [v7|v8|x86|all]"; exit 1 ;;
|
||||
esac
|
||||
echo "done — sidecars in ${NYM_SRC}/target/<triple>/release/nym-socks5-client"
|
||||
@@ -194,8 +194,8 @@ impl OnboardingContent {
|
||||
(
|
||||
"Send like a message",
|
||||
"Pay a @username or npub and it arrives as an end-to-end \
|
||||
encrypted message over nostr and Tor — no one in between can \
|
||||
see the amount or who's involved.",
|
||||
encrypted message over nostr and the Nym mixnet — no one in \
|
||||
between can see the amount or who's involved.",
|
||||
),
|
||||
(
|
||||
"Yours alone",
|
||||
|
||||
+21
-1
@@ -31,7 +31,16 @@ use log::{error, info, warn};
|
||||
|
||||
use super::{SOCKS5_HOST, SOCKS5_PORT};
|
||||
|
||||
/// Bundled SOCKS5 client binary name.
|
||||
/// Bundled SOCKS5 client binary name. Windows release archives ship the `.exe`;
|
||||
/// `Command`/`current_exe().parent().join(..)` need the suffix to find it. On
|
||||
/// Android the sidecar is shipped inside the APK's `jniLibs` as a `lib*.so` (the
|
||||
/// only files extracted to the exec-allowed native-library dir) — same trick
|
||||
/// upstream Grim used for Tor's webtunnel binary.
|
||||
#[cfg(target_os = "windows")]
|
||||
const BIN_NAME: &str = "nym-socks5-client.exe";
|
||||
#[cfg(target_os = "android")]
|
||||
const BIN_NAME: &str = "libnym_socks5_client.so";
|
||||
#[cfg(not(any(target_os = "windows", target_os = "android")))]
|
||||
const BIN_NAME: &str = "nym-socks5-client";
|
||||
|
||||
/// Per-app client id; namespaces the config/keys under the Nym data root.
|
||||
@@ -84,6 +93,17 @@ fn binary_path() -> PathBuf {
|
||||
return PathBuf::from(p);
|
||||
}
|
||||
}
|
||||
// Android: `current_exe()` is the zygote/app_process, not us — the sidecar
|
||||
// rides in the APK's jniLibs and is extracted to the native-library dir
|
||||
// (the one exec-allowed location). MainActivity exports it as
|
||||
// `NATIVE_LIBS_DIR` (see android/.../MainActivity.java).
|
||||
#[cfg(target_os = "android")]
|
||||
if let Ok(dir) = std::env::var("NATIVE_LIBS_DIR") {
|
||||
let p = PathBuf::from(dir).join(BIN_NAME);
|
||||
if p.exists() {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
if let Ok(exe) = std::env::current_exe() {
|
||||
if let Some(dir) = exe.parent() {
|
||||
let sibling = dir.join(BIN_NAME);
|
||||
|
||||
Reference in New Issue
Block a user