Skip to content
Open
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
10 changes: 5 additions & 5 deletions .github/actions/kotlin-bindings/action.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name: Kotlin UniFFI bindings
description: >
Generates the wallet and Nym proxy shim Kotlin bindings into
Generates the wallet and mixnet proxy Kotlin bindings into
android/app/build/generated/source/uniffi/<variant>/java with
scripts/generate_kotlin_bindings.mjs. Builds the shim for the host.
scripts/generate_kotlin_bindings.mjs. Builds the proxy for the host.

inputs:
variants:
Expand All @@ -21,15 +21,15 @@ runs:
shell: bash
run: rustup default stable

- name: Cache the bindgen and shim builds
- name: Cache the bindgen and proxy builds
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
rust/target
rust/nym-proxy-ffi/target
key: kotlin-bindings-${{ runner.os }}-${{ hashFiles('rust/Cargo.lock', 'rust/nym-proxy-ffi/Cargo.lock') }}
rust/mixnet-proxy/target
key: kotlin-bindings-${{ runner.os }}-${{ hashFiles('rust/Cargo.lock', 'rust/mixnet-proxy/Cargo.lock') }}

- name: Generate Kotlin bindings
shell: bash
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/android-apk-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ jobs:
run: |
set -eu
test -f "android/app/src/main/jniLibs/${{ env.ABI }}/libuniffi_zingo.so"
test -f "android/app/src/main/jniLibs/${{ env.ABI }}/libzingo_nym_proxy_ffi.so"
test -f "android/app/src/main/jniLibs/${{ env.ABI }}/libmixnet_proxy.so"
test -f "android/app/build/generated/source/uniffi/release/java/uniffi/zingo/zingo.kt"
test -f "android/app/build/generated/source/uniffi/release/java/uniffi/zingo_nym_proxy_ffi/zingo_nym_proxy_ffi.kt"
test -f "android/app/build/generated/source/uniffi/release/java/uniffi/mixnet_proxy/mixnet_proxy.kt"

- name: Remove unnecessary directories to free up space
run: |
Expand Down
20 changes: 10 additions & 10 deletions .github/workflows/android-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -217,8 +217,8 @@ jobs:
working-directory: ./rust/target/${{ env.TARGET }}/release
run: mv ./libzingo.so ./libuniffi_zingo.so

- name: Cargo build nym proxy shim
working-directory: ./rust/nym-proxy-ffi
- name: Cargo build nym mixnet proxy
working-directory: ./rust/mixnet-proxy
run: |
cargo ndk \
--target ${{ env.TARGET }} build \
Expand All @@ -235,12 +235,12 @@ jobs:

# Library mode reads the UniFFI metadata from the symbol table, so this
# runs before the strip.
- name: Kotlin bindings for nym proxy shim
working-directory: ./rust/nym-proxy-ffi
- name: Kotlin bindings for nym mixnet proxy
working-directory: ./rust/mixnet-proxy
run: |
cargo run --release --locked --manifest-path ../Cargo.toml \
--package zingo-uniffi-bindgen --bin zingo-uniffi-bindgen -- \
generate --library target/${{ env.TARGET }}/release/libzingo_nym_proxy_ffi.so \
generate --library target/${{ env.TARGET }}/release/libmixnet_proxy.so \
--language kotlin --no-format --metadata-no-deps \
--out-dir ../../android/app/build/generated/source/uniffi/release/java

Expand All @@ -251,17 +251,17 @@ jobs:
path: android/app/build/generated/source/uniffi/release/java/uniffi
retention-days: 3

- name: LLVM Strip nym proxy shim
working-directory: ./rust/nym-proxy-ffi/target
- name: LLVM Strip nym mixnet proxy
working-directory: ./rust/mixnet-proxy/target
run: |
llvm-strip --strip-all ./${{ env.TARGET }}/release/libzingo_nym_proxy_ffi.so
llvm-objcopy --remove-section .comment ./${{ env.TARGET }}/release/libzingo_nym_proxy_ffi.so
llvm-strip --strip-all ./${{ env.TARGET }}/release/libmixnet_proxy.so
llvm-objcopy --remove-section .comment ./${{ env.TARGET }}/release/libmixnet_proxy.so

- name: Stage native libraries
run: |
mkdir -p rust/native-out
cp rust/target/${{ env.TARGET }}/release/libuniffi_zingo.so rust/native-out/
cp rust/nym-proxy-ffi/target/${{ env.TARGET }}/release/libzingo_nym_proxy_ffi.so rust/native-out/
cp rust/mixnet-proxy/target/${{ env.TARGET }}/release/libmixnet_proxy.so rust/native-out/

- name: Upload native rust
uses: actions/upload-artifact@v7
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ jobs:
with:
fail-all: true

nym-proxy-ffi-check:
uses: ./.github/workflows/nym-proxy-ffi-check.yaml
mixnet-proxy-check:
uses: ./.github/workflows/mixnet-proxy-check.yaml
with:
fail-all: true

Expand Down
12 changes: 6 additions & 6 deletions .github/workflows/ios-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ jobs:
path: |
ios/Zingolib.xcframework
ios/zingo.swift
ios/ZingoNymProxyFFI.xcframework
ios/zingo_nym_proxy_ffi.swift
ios/MixnetProxy.xcframework
ios/mixnet_proxy.swift
key: native-ios-xcframework-${{ env.CACHE-KEY }}
lookup-only: true

Expand Down Expand Up @@ -156,8 +156,8 @@ jobs:
path: |
ios/Zingolib.xcframework
ios/zingo.swift
ios/ZingoNymProxyFFI.xcframework
ios/zingo_nym_proxy_ffi.swift
ios/MixnetProxy.xcframework
ios/mixnet_proxy.swift
retention-days: 3

cache-native-ios-uniffi:
Expand Down Expand Up @@ -187,6 +187,6 @@ jobs:
path: |
ios/Zingolib.xcframework
ios/zingo.swift
ios/ZingoNymProxyFFI.xcframework
ios/zingo_nym_proxy_ffi.swift
ios/MixnetProxy.xcframework
ios/mixnet_proxy.swift
key: native-ios-xcframework-${{ env.CACHE-KEY }}
4 changes: 2 additions & 2 deletions .github/workflows/ios-integration-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ jobs:
path: |
ios/Zingolib.xcframework
ios/zingo.swift
ios/ZingoNymProxyFFI.xcframework
ios/zingo_nym_proxy_ffi.swift
ios/MixnetProxy.xcframework
ios/mixnet_proxy.swift
key: native-ios-xcframework-${{ env.CACHE-KEY }}
fail-on-cache-miss: true

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/maestro-nightly.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ jobs:
path: |
ios/Zingolib.xcframework
ios/zingo.swift
ios/ZingoNymProxyFFI.xcframework
ios/zingo_nym_proxy_ffi.swift
ios/MixnetProxy.xcframework
ios/mixnet_proxy.swift
key: native-ios-xcframework-${{ env.CACHE-KEY }}
fail-on-cache-miss: true

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Mixnet proxy shim checks
name: Mixnet proxy checks

on:
workflow_call:
Expand All @@ -11,8 +11,8 @@ on:
default: false

jobs:
nym-proxy-ffi-check:
name: shim check, clippy, fmt, tests
mixnet-proxy-check:
name: proxy check, clippy, fmt, tests
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
Expand All @@ -24,40 +24,40 @@ jobs:
- name: Install protobuf-compiler
run: sudo apt-get update && sudo apt-get install -y protobuf-compiler

# The shim is excluded from the main workspace (own lockfile, see
# The proxy is excluded from the main workspace (own lockfile, see
# rust/Cargo.toml), so workspace-wide jobs never touch it. This job
# is its only host-side verdict.
- name: Cache the shim build
- name: Cache the proxy build
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
rust/nym-proxy-ffi/target
key: nym-proxy-ffi-${{ runner.os }}-${{ hashFiles('rust/nym-proxy-ffi/Cargo.lock') }}
rust/mixnet-proxy/target
key: mixnet-proxy-${{ runner.os }}-${{ hashFiles('rust/mixnet-proxy/Cargo.lock') }}

- name: Install cargo-nextest
uses: taiki-e/install-action@v2
with:
tool: cargo-nextest@0.9.98

- name: Format check
working-directory: ./rust/nym-proxy-ffi
working-directory: ./rust/mixnet-proxy
run: cargo fmt --check

# --workspace covers the tls-init member; its JNI body is
# Android-gated, so the host lanes prove the workspace shape and the
# release cross-build proves the JNI code.
- name: Check
working-directory: ./rust/nym-proxy-ffi
working-directory: ./rust/mixnet-proxy
run: cargo check --locked --workspace --all-targets

- name: Clippy
working-directory: ./rust/nym-proxy-ffi
working-directory: ./rust/mixnet-proxy
run: cargo clippy --locked --workspace --all-targets -- -D warnings

- name: Tests
working-directory: ./rust/nym-proxy-ffi
working-directory: ./rust/mixnet-proxy
run: cargo nextest run --locked --workspace

- name: Cancel the run on failure (fail-all)
Expand All @@ -73,9 +73,9 @@ jobs:

# Starts the real proxy against the mixnet, handshakes its SOCKS5 listener,
# and stops it. Not part of the fail-all job above.
nym-proxy-ffi-live:
mixnet-proxy-live:
name: live mixnet start
needs: nym-proxy-ffi-check
needs: mixnet-proxy-check
runs-on: ubuntu-24.04
steps:
- name: Checkout repository
Expand All @@ -84,20 +84,20 @@ jobs:
- name: Install protobuf-compiler
run: sudo apt-get update && sudo apt-get install -y protobuf-compiler

- name: Cache the shim build
- name: Cache the proxy build
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
rust/nym-proxy-ffi/target
key: nym-proxy-ffi-${{ runner.os }}-${{ hashFiles('rust/nym-proxy-ffi/Cargo.lock') }}
rust/mixnet-proxy/target
key: mixnet-proxy-${{ runner.os }}-${{ hashFiles('rust/mixnet-proxy/Cargo.lock') }}

- name: Install cargo-nextest
uses: taiki-e/install-action@v2
with:
tool: cargo-nextest@0.9.98

- name: Live mixnet start
working-directory: ./rust/nym-proxy-ffi
working-directory: ./rust/mixnet-proxy
run: cargo nextest run --locked --features live-mixnet --test live_mixnet
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ android/app/beta/release/
*.aab
*.apk
ios/Zingolib.xcframework/
ios/ZingoNymProxyFFI.xcframework/
ios/MixnetProxy.xcframework/
ios/NymHost.xcframework/
ios/zingo.swift
ios/zingo_nym_proxy_ffi.swift
ios/mixnet_proxy.swift
rust/lib/Generated/zingo.swift
rust/lib/Generated/zingoFFI.h
rust/nym-proxy-ffi/Generated/
rust/mixnet-proxy/Generated/
rust/lib/Generated/zingoFFI.modulemap

# Android/IntelliJ
Expand Down
4 changes: 2 additions & 2 deletions __tests__/walletBackend.mixnetCoordinator.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ describe('MixnetCoordinator', () => {
it('a transport-start failure publishes the failure view and offers re-enable, never clearnet', async () => {
const startTransport = jest
.fn()
.mockRejectedValue(new Error('shim missing'));
.mockRejectedValue(new Error('proxy missing'));
const published: MixnetView[] = [];
const coordinator = new MixnetCoordinator(startTransport, noopStop, view =>
published.push(view),
Expand Down Expand Up @@ -258,7 +258,7 @@ describe('MixnetCoordinator', () => {
it('keeps sends blocked when the first poll after a transport failure reports off (#1226)', async () => {
const startTransport = jest
.fn()
.mockRejectedValue(new Error('shim missing'));
.mockRejectedValue(new Error('proxy missing'));
const published: MixnetView[] = [];
const coordinator = new MixnetCoordinator(startTransport, noopStop, view =>
published.push(view),
Expand Down
6 changes: 3 additions & 3 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,9 @@ android {

sourceSets {
getByName("test") {
// The nym proxy shim's Kotlin wire-contract test, read from the
// The nym mixnet proxy's Kotlin wire-contract test, read from the
// crate itself. No copy lives under src/test.
java.srcDir("../../rust/nym-proxy-ffi/contract-tests/kotlin")
java.srcDir("../../rust/mixnet-proxy/contract-tests/kotlin")
}
}

Expand All @@ -259,7 +259,7 @@ android {
it.systemProperty(
"zingo.golden.dir",
layout.projectDirectory
.dir("../../rust/nym-proxy-ffi/test-data/golden")
.dir("../../rust/mixnet-proxy/test-data/golden")
.asFile.absolutePath
)
}
Expand Down
2 changes: 1 addition & 1 deletion android/app/lint.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
three NewApi errors. Scoped to this generated file so NewApi stays
enforced everywhere we write Kotlin by hand. -->
<issue id="NewApi">
<ignore path="src/main/java/uniffi/zingo_nym_proxy_ffi/zingo_nym_proxy_ffi.kt" />
<ignore path="src/main/java/uniffi/mixnet_proxy/mixnet_proxy.kt" />
</issue>
</lint>
20 changes: 10 additions & 10 deletions android/app/src/main/java/org/ZingoLabs/Zingo/NymTransportModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import uniffi.zingo_nym_proxy_ffi.MixnetProxyHandle
import uniffi.zingo_nym_proxy_ffi.ProxyDeathObserver
import uniffi.zingo_nym_proxy_ffi.ProxyDeathReason
import uniffi.mixnet_proxy.MixnetProxyHandle
import uniffi.mixnet_proxy.ProxyDeathObserver
import uniffi.mixnet_proxy.ProxyDeathReason

/**
* The platform half of Mixnet Mode on Android (send-over-nym step 3,
* zingolib#2513): hosts the UniFFI proxy shim (`uniffi.zingo_nym_proxy_ffi`)
* zingolib#2513): hosts the mixnet proxy (`uniffi.mixnet_proxy`)
* inside the app process and offers its local SOCKS5 endpoint to the app
* layer, which hands it to the wallet's `attach_mixnet` seam. The shim is a
* layer, which hands it to the wallet's `attach_mixnet` seam. The proxy is a
* UniFFI component distinct from the wallet's (`uniffi.zingo`) by ratified
* decision — the loopback socket, not a shared compile unit, is the boundary
* between the two lockfile-incompatible stacks.
Expand All @@ -22,14 +22,14 @@ import uniffi.zingo_nym_proxy_ffi.ProxyDeathReason
* binding — the `host:port` endpoint and the Exit Node it bound, both of
* which the wallet's attach seam requires; `stopMixnetTransport` is the
* deliberate teardown.
* A proxy that dies on its own is observed by the shim's liveness monitor;
* A proxy that dies on its own is observed by the proxy's liveness monitor;
* the observer clears the stored handle so a later re-enable starts afresh,
* while the wallet's own probe surfaces the `died` mode the app polls.
*
* Failures settle out of band in the error channel (zingo-mobile ADRs 0002
* and 0003): the promise rejects under this module's name, never prose in
* the data payload. JVM `Error`s from shim linkage are converted to
* exceptions at this boundary because a build whose APK carries no shim
* the data payload. JVM `Error`s from proxy linkage are converted to
* exceptions at this boundary because a build whose APK carries no proxy
* library must degrade fail-closed — an `UnsatisfiedLinkError` becomes a
* rejected start, sends stay blocked, and the app survives to offer
* re-enable or the clearnet consent path.
Expand Down Expand Up @@ -98,14 +98,14 @@ class NymTransportModule internal constructor(reactContext: ReactApplicationCont
}

/**
* Runs `call`, converting JVM `Error`s (a missing or mismatched shim
* Runs `call`, converting JVM `Error`s (a missing or mismatched proxy
* library) into exceptions so [FfiOutcome] settles them as rejections
* instead of the process dying.
*/
private fun <T> guardingLinkage(call: () -> T): T = try {
call()
} catch (error: Error) {
throw IllegalStateException("the nym proxy shim is unavailable", error)
throw IllegalStateException("the nym mixnet proxy is unavailable", error)
}

@ReactMethod
Expand Down
2 changes: 1 addition & 1 deletion app/walletBackend/config/WalletBackendConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export type WalletBackendConfig = {
/** Called with each new screen-facing Mixnet Mode projection. */
onMixnetViewChanged: (view: MixnetView) => void;
/**
* Starts the platform-hosted mixnet transport (the UniFFI proxy shim on
* Starts the platform-hosted mixnet transport (the mixnet proxy on
* Android) and yields its local SOCKS5 address. Injected because the
* platform owns the transport; tests supply a stub.
*/
Expand Down
2 changes: 1 addition & 1 deletion app/walletBackend/modules/MixnetCoordinator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* and only a deliberate disable stops the reconnect loop.
*
* The transport start is an injected seam (`StartMixnetTransport`) because
* the platform owns it: on Android the UniFFI proxy shim (step 3 of the
* the platform owns it: on Android the mixnet proxy (step 3 of the
* critical path) supplies it; tests supply a stub. This coordinator owns
* cadence and policy only — every payload decision lives in the pure
* transforms, and every screen projection in the pure presenter.
Expand Down
Loading
Loading