minimuxer is the lockdown muxer used by SideStore. It runs on device through em_proxy.
Sources/ ← Main Minimuxer Swift API
RustBridge/
src/ ← Low level rust bridge
MinimuxerBridge.swift ← Swift ↔ Rust FFI layer using @_silgen_name
lib/
RustBridge.xcframework ← Pre-built RustBridge xcframework used by MinimuxerBridge
Makefile ← Manually Build RustBridge and produce xcframework
cd RustBridge
make build # compile Rust bridge static libs for iOS, iOS Simulator, macOS
make xcframework # create RustBridge/lib/RustBridge.xcframework (contains all platforms)After creating the RustBridge.xcframework manually check-in if required
Any changes to files under RustBridge/src/** will require recreating the RustBridge.xcframework
After running make xcframework, confirm SPM package build works using the following
cd ..
swift buildWhile minimuxer is built to run on device, it is recommended to test from your computer through USB to speed up the development process. (Obviously, you should still test on device; see On device for more info)
cargo test <test function name> -- --nocaptureto run it. (-- --nocapture allows for logs to be shown, which are essential for debugging)
Filter to only minimuxer logs:
cargo test <test function name> -- --nocapture 2>&1 | grep -e minimuxer:: -e tests.rsAfter implementing your feature, you should also run
cargo clippy --no-depsto lint your code.
If you want some of the lints to auto fix, you can use
cargo clippy --no-deps --fixNote: tests currently don't automatically mount the developer disk image. You must do that yourself with
ideviceimagemounteror via SideStore on device.
MinimuxerBridge.swift exposes the Rust functions to Swift using @_silgen_name — no C headers or code generation required. When adding a new Rust function:
- Add the
#[no_mangle] pub extern "C"function inRustBridge/src/bridge.rs - Add the corresponding
@_silgen_namedeclaration + Swift wrapper inMinimuxerBridge.swift - Run
make xcframeworkand commit the updated xcframework
Unless otherwise stated, references to AltServer implementations are referring to AltServer/Devices/ALTDeviceManager.mm
Once you've made your function, added it to the tests and verified that it works, you can add it to swift-bridge/ffi to allow Swift to use it.
- Import your function in the
ffi importssection oflib.rs - In
mod ffi->extern "Rust", add your function to the section for the file you added it to.
When making your function, you might have something similar to this:
pub fn install_provisioning_profile(profile: &[u8]) -> Result<()> { ... }You can use crate::Res as a shorthand to Result<T, crate::Errors>. (Most files already use this)
When exposing your function to the ffi module, we unfortunately can't use the crate::Res type alias. Instead, do this:
Result<[the type your function returns. in the case of install_provisioning_profile, it is ()], Errors>
AltServer implementation: search installProvisioningProfiles and installProvisioningProfile:(