app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit d2b1df8c80fd5ddad2cdb9101ad8f519c5ca2612
parent 05e1f3408b692c7d09de788cecae067cb7c82f33
Author: triesap <tyson@radroots.org>
Date:   Fri, 10 Apr 2026 17:27:51 +0000

app: update crate metadata

Diffstat:
MCargo.lock | 104++++++++++++++++++++++++++++++++++++++++----------------------------------------
MCargo.toml | 14+++++++-------
Mcrates/android/Cargo.toml | 10+++++-----
Mcrates/apple/security/Cargo.toml | 4++--
Acrates/apple/security/build.rs | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mcrates/core/Cargo.toml | 2+-
Mcrates/desktop/Cargo.toml | 8++++----
Mcrates/ios/Cargo.toml | 8++++----
Mcrates/remote-signer/Cargo.toml | 8++++----
Mcrates/test-support/Cargo.toml | 2+-
Mcrates/web/Cargo.toml | 2+-
11 files changed, 222 insertions(+), 81 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -3057,11 +3057,11 @@ dependencies = [ "radroots-app-core", "radroots-app-remote-signer", "radroots-app-test-support", - "radroots-geocoder", - "radroots-identity", - "radroots-nostr-accounts", - "radroots-runtime-paths", - "radroots-secret-vault", + "radroots_geocoder", + "radroots_identity", + "radroots_nostr_accounts", + "radroots_runtime_paths", + "radroots_secret_vault", "wgpu", "winit", "zeroize", @@ -3071,8 +3071,8 @@ dependencies = [ name = "radroots-app-apple-security" version = "0.1.0" dependencies = [ - "radroots-nostr-accounts", - "radroots-secret-vault", + "radroots_nostr_accounts", + "radroots_secret_vault", "zeroize", ] @@ -3083,7 +3083,7 @@ dependencies = [ "eframe", "egui", "radroots-app-test-support", - "radroots-runtime-paths", + "radroots_runtime_paths", "zeroize", ] @@ -3100,10 +3100,10 @@ dependencies = [ "radroots-app-core", "radroots-app-remote-signer", "radroots-app-test-support", - "radroots-geocoder", - "radroots-identity", - "radroots-nostr-accounts", - "radroots-runtime-paths", + "radroots_geocoder", + "radroots_identity", + "radroots_nostr_accounts", + "radroots_runtime_paths", "wgpu", "zeroize", ] @@ -3118,10 +3118,10 @@ dependencies = [ "radroots-app-core", "radroots-app-remote-signer", "radroots-app-test-support", - "radroots-geocoder", - "radroots-identity", - "radroots-nostr-accounts", - "radroots-runtime-paths", + "radroots_geocoder", + "radroots_identity", + "radroots_nostr_accounts", + "radroots_runtime_paths", "wgpu", "zeroize", ] @@ -3132,10 +3132,10 @@ version = "0.1.0" dependencies = [ "nostr", "radroots-app-test-support", - "radroots-identity", - "radroots-nostr", - "radroots-nostr-accounts", - "radroots-nostr-connect", + "radroots_identity", + "radroots_nostr", + "radroots_nostr_accounts", + "radroots_nostr_connect", "serde", "serde_json", "tempfile", @@ -3147,7 +3147,7 @@ dependencies = [ name = "radroots-app-test-support" version = "0.1.0" dependencies = [ - "radroots-identity", + "radroots_identity", ] [[package]] @@ -3160,14 +3160,14 @@ dependencies = [ "nostr", "nostr-browser-signer", "radroots-app-core", - "radroots-geocoder", + "radroots_geocoder", "wasm-bindgen-futures", "web-sys", "wgpu", ] [[package]] -name = "radroots-core" +name = "radroots_core" version = "0.1.0-alpha.1" dependencies = [ "rust_decimal", @@ -3176,15 +3176,15 @@ dependencies = [ ] [[package]] -name = "radroots-events" +name = "radroots_events" version = "0.1.0-alpha.1" dependencies = [ - "radroots-core", + "radroots_core", "serde", ] [[package]] -name = "radroots-geocoder" +name = "radroots_geocoder" version = "0.1.0-alpha.1" dependencies = [ "rusqlite", @@ -3193,13 +3193,13 @@ dependencies = [ ] [[package]] -name = "radroots-identity" +name = "radroots_identity" version = "0.1.0-alpha.1" dependencies = [ "nostr", - "radroots-events", - "radroots-runtime", - "radroots-runtime-paths", + "radroots_events", + "radroots_runtime", + "radroots_runtime_paths", "serde", "serde_json", "thiserror 1.0.69", @@ -3207,7 +3207,7 @@ dependencies = [ ] [[package]] -name = "radroots-log" +name = "radroots_log" version = "0.1.0-alpha.1" dependencies = [ "chrono", @@ -3218,25 +3218,25 @@ dependencies = [ ] [[package]] -name = "radroots-nostr" +name = "radroots_nostr" version = "0.1.0-alpha.1" dependencies = [ "nostr", "nostr-sdk", - "radroots-identity", + "radroots_identity", "serde", "serde_json", "thiserror 1.0.69", ] [[package]] -name = "radroots-nostr-accounts" +name = "radroots_nostr_accounts" version = "0.1.0-alpha.1" dependencies = [ - "radroots-identity", - "radroots-nostr-signer", - "radroots-runtime", - "radroots-secret-vault", + "radroots_identity", + "radroots_nostr_signer", + "radroots_runtime", + "radroots_secret_vault", "serde", "serde_json", "thiserror 1.0.69", @@ -3244,7 +3244,7 @@ dependencies = [ ] [[package]] -name = "radroots-nostr-connect" +name = "radroots_nostr_connect" version = "0.1.0-alpha.1" dependencies = [ "nostr", @@ -3255,14 +3255,14 @@ dependencies = [ ] [[package]] -name = "radroots-nostr-signer" +name = "radroots_nostr_signer" version = "0.1.0-alpha.1" dependencies = [ "hex", "nostr", - "radroots-identity", - "radroots-nostr-connect", - "radroots-runtime", + "radroots_identity", + "radroots_nostr_connect", + "radroots_runtime", "serde", "serde_json", "sha2", @@ -3272,29 +3272,29 @@ dependencies = [ ] [[package]] -name = "radroots-protected-store" +name = "radroots_protected_store" version = "0.1.0-alpha.1" dependencies = [ "chacha20poly1305", "getrandom 0.2.17", - "radroots-secret-vault", + "radroots_secret_vault", "serde", "serde_json", "zeroize", ] [[package]] -name = "radroots-runtime" +name = "radroots_runtime" version = "0.1.0-alpha.1" dependencies = [ "anyhow", "chacha20poly1305", "config", "getrandom 0.2.17", - "radroots-log", - "radroots-protected-store", - "radroots-runtime-paths", - "radroots-secret-vault", + "radroots_log", + "radroots_protected_store", + "radroots_runtime_paths", + "radroots_secret_vault", "serde", "serde_json", "tempfile", @@ -3306,14 +3306,14 @@ dependencies = [ ] [[package]] -name = "radroots-runtime-paths" +name = "radroots_runtime_paths" version = "0.1.0-alpha.1" dependencies = [ "thiserror 1.0.69", ] [[package]] -name = "radroots-secret-vault" +name = "radroots_secret_vault" version = "0.1.0-alpha.1" dependencies = [ "keyring", diff --git a/Cargo.toml b/Cargo.toml @@ -33,13 +33,13 @@ nostr = { version = "0.44.1", default-features = false, features = ["std"] } nostr-browser-signer = "0.44.1" objc2-foundation = { version = "0.3.2", default-features = false, features = ["std"] } radroots-app-apple-security = { path = "crates/apple/security" } -radroots-geocoder = { path = "../lib/crates/geocoder" } -radroots-identity = { path = "../lib/crates/identity", default-features = false, features = ["std", "nip49"] } -radroots-nostr = { path = "../lib/crates/nostr", default-features = false, features = ["std", "client"] } -radroots-nostr-accounts = { path = "../lib/crates/nostr-accounts", default-features = false, features = ["std", "file-store", "os-keyring"] } -radroots-nostr-connect = { path = "../lib/crates/nostr-connect" } -radroots-runtime-paths = { path = "../lib/crates/runtime-paths" } -radroots-secret-vault = { path = "../lib/crates/secret-vault", default-features = false, features = ["std"] } +radroots_geocoder = { path = "../lib/crates/geocoder" } +radroots_identity = { path = "../lib/crates/identity", default-features = false, features = ["std", "nip49"] } +radroots_nostr = { path = "../lib/crates/nostr", default-features = false, features = ["std", "client"] } +radroots_nostr_accounts = { path = "../lib/crates/nostr_accounts", default-features = false, features = ["std", "file-store", "os-keyring"] } +radroots_nostr_connect = { path = "../lib/crates/nostr_connect" } +radroots_runtime_paths = { path = "../lib/crates/runtime_paths" } +radroots_secret_vault = { path = "../lib/crates/secret_vault", default-features = false, features = ["std"] } serde = { version = "1.0.228", features = ["derive"] } serde_json = "1.0.145" tokio = { version = "1.48.0", features = ["rt", "sync", "time"] } diff --git a/crates/android/Cargo.toml b/crates/android/Cargo.toml @@ -19,11 +19,11 @@ eframe = { workspace = true, features = ["android-game-activity", "glow"] } log.workspace = true radroots-app-core = { path = "../core" } radroots-app-remote-signer = { path = "../remote-signer" } -radroots-geocoder.workspace = true -radroots-identity.workspace = true -radroots-nostr-accounts = { workspace = true, features = ["memory-vault"] } -radroots-runtime-paths.workspace = true -radroots-secret-vault.workspace = true +radroots_geocoder.workspace = true +radroots_identity.workspace = true +radroots_nostr_accounts = { workspace = true, features = ["memory-vault"] } +radroots_runtime_paths.workspace = true +radroots_secret_vault.workspace = true zeroize.workspace = true [target.'cfg(target_os = "android")'.dependencies] diff --git a/crates/apple/security/Cargo.toml b/crates/apple/security/Cargo.toml @@ -11,8 +11,8 @@ description = "Rad Roots Apple security bridge" publish = false [dependencies] -radroots-nostr-accounts.workspace = true -radroots-secret-vault.workspace = true +radroots_nostr_accounts.workspace = true +radroots_secret_vault.workspace = true zeroize.workspace = true [lints.rust] diff --git a/crates/apple/security/build.rs b/crates/apple/security/build.rs @@ -0,0 +1,141 @@ +use std::env; +use std::path::{Path, PathBuf}; +use std::process::Command; + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default(); + if target_os != "macos" && target_os != "ios" { + return; + } + + let package_dir = swift_package_dir(); + println!( + "cargo:rerun-if-changed={}", + package_dir.join("Package.swift").display() + ); + println!( + "cargo:rerun-if-changed={}", + package_dir.join("Sources").display() + ); + println!( + "cargo:rerun-if-changed={}", + package_dir.join("Tests").display() + ); + + let ffi_library = "libRadRootsAppleSecurityFFIDynamic.dylib"; + run_swift_build(package_dir.as_path(), "RadRootsAppleSecurityFFIDynamic"); + + let build_dir = find_library_dir(package_dir.join(".build"), ffi_library) + .expect("swift ffi library dir"); + let swift_runtime_dir = swift_runtime_dir(target_os.as_str()); + println!("cargo:rustc-link-search=native={}", build_dir.display()); + println!( + "cargo:rustc-link-search=native={}", + swift_runtime_dir.display() + ); + println!("cargo:rustc-link-arg=-Wl,-rpath,{}", build_dir.display()); + println!( + "cargo:rustc-link-arg=-Wl,-rpath,{}", + swift_runtime_dir.display() + ); + println!("cargo:rustc-link-lib=dylib=RadRootsAppleSecurityFFIDynamic"); + println!("cargo:rustc-link-lib=framework=CoreFoundation"); + println!("cargo:rustc-link-lib=framework=Foundation"); + println!("cargo:rustc-link-lib=framework=LocalAuthentication"); + println!("cargo:rustc-link-lib=framework=Security"); + println!("cargo:rustc-link-lib=dylib=objc"); +} + +fn swift_package_dir() -> PathBuf { + PathBuf::from(env::var("CARGO_MANIFEST_DIR").expect("manifest dir")) + .join("../../../native/apple/swift/RadRootsAppleSecurity") +} + +fn swift_runtime_dir(target_os: &str) -> PathBuf { + let swift_bin = run_stdout(Command::new("xcrun").arg("--toolchain").arg("swift").arg("--find").arg("swift")); + let swift_bin = PathBuf::from(swift_bin.trim()); + let toolchain_dir = swift_bin + .parent() + .and_then(Path::parent) + .and_then(Path::parent) + .expect("swift toolchain dir"); + find_swift_runtime_dir(toolchain_dir.join("usr/lib"), target_os).expect("swift runtime dir") +} + +fn find_swift_runtime_dir(root: PathBuf, target_os: &str) -> Option<PathBuf> { + let platform_dir = match target_os { + "macos" => "macosx", + "ios" => "iphoneos", + other => other, + }; + let mut stack = vec![root]; + while let Some(dir) = stack.pop() { + let entries = std::fs::read_dir(&dir).ok()?; + for entry in entries.flatten() { + let path = entry.path(); + if path.is_dir() { + stack.push(path); + continue; + } + if path.file_name().is_some_and(|name| name == "libswift_Concurrency.dylib") + && path + .components() + .any(|component| component.as_os_str() == platform_dir) + { + return path.parent().map(Path::to_path_buf); + } + } + } + None +} + +fn find_library_dir(root: PathBuf, library_name: &str) -> Option<PathBuf> { + let mut stack = vec![root]; + while let Some(dir) = stack.pop() { + let entries = std::fs::read_dir(&dir).ok()?; + for entry in entries.flatten() { + let path = entry.path(); + if path.is_dir() { + stack.push(path); + continue; + } + if path.file_name().is_some_and(|name| name == library_name) { + return path.parent().map(Path::to_path_buf); + } + } + } + None +} + +fn run_swift_build(package_dir: &Path, product: &str) { + let output = Command::new("swift") + .arg("build") + .arg("--product") + .arg(product) + .current_dir(package_dir) + .output() + .expect("failed to run swift build"); + + if output.status.success() { + return; + } + + let stdout = String::from_utf8_lossy(&output.stdout); + let stderr = String::from_utf8_lossy(&output.stderr); + panic!( + "swift build --product {product} failed in {}:\nstdout:\n{stdout}\nstderr:\n{stderr}", + package_dir.display() + ); +} + +fn run_stdout(command: &mut Command) -> String { + let output = command.output().expect("failed to run command"); + if output.status.success() { + return String::from_utf8(output.stdout).expect("utf-8 stdout"); + } + + let stderr = String::from_utf8_lossy(&output.stderr); + panic!("command failed: {command:?}\nstderr:\n{stderr}"); +} diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml @@ -16,7 +16,7 @@ workspace = true [dependencies] eframe.workspace = true egui.workspace = true -radroots-runtime-paths.workspace = true +radroots_runtime_paths.workspace = true zeroize.workspace = true [dev-dependencies] diff --git a/crates/desktop/Cargo.toml b/crates/desktop/Cargo.toml @@ -21,9 +21,9 @@ image.workspace = true log.workspace = true radroots-app-core = { path = "../core" } radroots-app-remote-signer = { path = "../remote-signer" } -radroots-geocoder.workspace = true -radroots-nostr-accounts = { workspace = true, features = ["memory-vault"] } -radroots-runtime-paths.workspace = true +radroots_geocoder.workspace = true +radroots_nostr_accounts = { workspace = true, features = ["memory-vault"] } +radroots_runtime_paths.workspace = true zeroize.workspace = true [target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies] @@ -32,7 +32,7 @@ wgpu = { workspace = true, features = ["metal", "wgsl"] } [target.'cfg(target_os = "macos")'.dependencies] objc2-foundation = { workspace = true, features = ["NSProcessInfo", "NSString"] } radroots-app-apple-security.workspace = true -radroots-identity.workspace = true +radroots_identity.workspace = true [target.'cfg(target_os = "windows")'.dependencies] wgpu = { workspace = true, features = ["dx12", "wgsl"] } diff --git a/crates/ios/Cargo.toml b/crates/ios/Cargo.toml @@ -20,10 +20,10 @@ log.workspace = true radroots-app-apple-security.workspace = true radroots-app-core = { path = "../core" } radroots-app-remote-signer = { path = "../remote-signer" } -radroots-geocoder.workspace = true -radroots-identity.workspace = true -radroots-nostr-accounts = { workspace = true, features = ["memory-vault"] } -radroots-runtime-paths.workspace = true +radroots_geocoder.workspace = true +radroots_identity.workspace = true +radroots_nostr_accounts = { workspace = true, features = ["memory-vault"] } +radroots_runtime_paths.workspace = true zeroize.workspace = true [target.'cfg(target_os = "ios")'.dependencies] diff --git a/crates/remote-signer/Cargo.toml b/crates/remote-signer/Cargo.toml @@ -15,10 +15,10 @@ workspace = true [dependencies] nostr = { workspace = true, features = ["nip44"] } -radroots-identity.workspace = true -radroots-nostr-accounts = { workspace = true, features = ["memory-vault"] } -radroots-nostr.workspace = true -radroots-nostr-connect.workspace = true +radroots_identity.workspace = true +radroots_nostr_accounts = { workspace = true, features = ["memory-vault"] } +radroots_nostr.workspace = true +radroots_nostr_connect.workspace = true serde.workspace = true serde_json.workspace = true tokio.workspace = true diff --git a/crates/test-support/Cargo.toml b/crates/test-support/Cargo.toml @@ -14,4 +14,4 @@ publish = false workspace = true [dependencies] -radroots-identity.workspace = true +radroots_identity.workspace = true diff --git a/crates/web/Cargo.toml b/crates/web/Cargo.toml @@ -19,7 +19,7 @@ eframe = { workspace = true, features = ["wgpu"] } js-sys = "0.3.91" log.workspace = true radroots-app-core = { path = "../core" } -radroots-geocoder.workspace = true +radroots_geocoder.workspace = true wasm-bindgen-futures.workspace = true web-sys = { workspace = true, features = ["Document", "Element", "HtmlCanvasElement", "Response", "Window"] }