diff --git a/.gitignore b/.gitignore index b650a86..7474eca 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ build/ android/src/main/jniLibs/ /macos/frostdart.xcframework/ +/ios/libfrostdart.a diff --git a/ios/frostdart.podspec b/ios/frostdart.podspec index 4f55a5f..c9a8c73 100644 --- a/ios/frostdart.podspec +++ b/ios/frostdart.podspec @@ -4,14 +4,16 @@ # Pod::Spec.new do |s| s.name = 'frostdart' - s.version = '0.0.1' - s.summary = 'A new Flutter project.' + s.version = '0.2.0' + s.summary = 'Flutter FFI plugin for FROST threshold signing.' s.description = <<-DESC -A new Flutter project. +Flutter FFI plugin wrapping the Rust HRF (FROST) crate from +kayabaNerve/serai (a fork of serai-dex/serai) for threshold-signed +Bitcoin wallets. DESC - s.homepage = 'http://example.com' + s.homepage = 'https://github.com/cypherstack/frostdart' s.license = { :file => '../LICENSE' } - s.author = { 'Your Company' => 'email@example.com' } + s.author = { 'Cypher Stack' => 'heyo@cypherstack.com' } # This will ensure the source files in Classes/ are included in the native # builds of apps using this FFI plugin. Podspec does not support relative @@ -20,20 +22,19 @@ A new Flutter project. s.source = { :path => '.' } s.source_files = 'Classes/**/*' - s.script_phase = { - :name => 'Build Rust library', - # First argument is relative path to the `rust` folder, second is name of rust library - :script => 'sh "$PODS_TARGET_SRCROOT/../cargokit/build_pod.sh" ../src/serai/hrf frostdart', - :execution_position => :before_compile, - :input_files => ['${BUILT_PRODUCTS_DIR}/cargokit_phony'], - # Let XCode know that the static library referenced in -force_load below is - # created by this build step. - :output_files => ["${BUILT_PRODUCTS_DIR}/libfrostdart.a"], - } + # libfrostdart.a is produced by scripts/ios/download.sh (release artifact) + # or scripts/ios/build_all.sh (build from source). Both drop it next to this + # podspec. Consumers must run one of those before `pod install`. + s.vendored_libraries = 'libfrostdart.a' + + s.dependency 'Flutter' + s.platform = :ios, '15.0' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', # Flutter.framework does not contain a i386 slice. 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386', - 'OTHER_LDFLAGS' => '-force_load ${BUILT_PRODUCTS_DIR}/libfrostdart.a', + 'OTHER_LDFLAGS' => '-force_load ${PODS_TARGET_SRCROOT}/libfrostdart.a', } + s.swift_version = '5.0' end diff --git a/macos/frostdart.podspec b/macos/frostdart.podspec index 90dd93d..7197578 100644 --- a/macos/frostdart.podspec +++ b/macos/frostdart.podspec @@ -4,14 +4,16 @@ # Pod::Spec.new do |s| s.name = 'frostdart' - s.version = '0.0.1' - s.summary = 'A new Flutter project.' + s.version = '0.2.0' + s.summary = 'Flutter FFI plugin for FROST threshold signing.' s.description = <<-DESC -A new Flutter project. +Flutter FFI plugin wrapping the Rust HRF (FROST) crate from +kayabaNerve/serai (a fork of serai-dex/serai) for threshold-signed +Bitcoin wallets. DESC - s.homepage = 'http://example.com' + s.homepage = 'https://github.com/cypherstack/frostdart' s.license = { :file => '../LICENSE' } - s.author = { 'Your Company' => 'email@example.com' } + s.author = { 'Cypher Stack' => 'heyo@cypherstack.com' } s.source = { :path => '.' } s.vendored_frameworks = 'frostdart.xcframework' diff --git a/pubspec.yaml b/pubspec.yaml index e5b067e..56e5696 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: frostdart -description: A new Flutter project. -version: 0.0.1 -homepage: +description: Flutter FFI plugin wrapping the Rust HRF (FROST) crate from kayabaNerve/serai (a fork of serai-dex/serai) for threshold-signed Bitcoin wallets. +version: 0.2.0 +homepage: https://github.com/cypherstack/frostdart environment: sdk: '>=3.0.5 <4.0.0' diff --git a/scripts/ios/build_all.sh b/scripts/ios/build_all.sh index 2414e18..c766012 100755 --- a/scripts/ios/build_all.sh +++ b/scripts/ios/build_all.sh @@ -1,12 +1,19 @@ #!/bin/bash +set -e -ROOT_DIR="$(pwd)/../.." +LIB_ROOT=../.. -mkdir -p build +cd "$LIB_ROOT/src/serai/hrf" || exit -rm -rf "$ROOT_DIR"/src/serai/target +# cargokit's artifact search uses the Cargo package name verbatim, but cargo +# normalizes dashes to underscores in the emitted filename. Rename so cargo's +# output ("libfrostdart.a") and the podspec's vendored_libraries entry agree. +# BSD sed (macOS) syntax; idempotent. +sed -i '' 's/^name = "hrf-api"$/name = "frostdart"/' Cargo.toml -cd "$ROOT_DIR"/src/serai/hrf || exit +export IPHONEOS_DEPLOYMENT_TARGET=15.0 +export RUSTFLAGS="-C link-arg=-mios-version-min=15.0" +cargo build --target aarch64-apple-ios --release --lib -# Build is handled by cargokit which requires the rust crate be named the same -sed -i .bak 's/hrf-api/frostdart/' cargo.toml \ No newline at end of file +cp ../target/aarch64-apple-ios/release/libfrostdart.a \ + "$LIB_ROOT/ios/libfrostdart.a" diff --git a/scripts/ios/download.sh b/scripts/ios/download.sh new file mode 100755 index 0000000..8479eb0 --- /dev/null +++ b/scripts/ios/download.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -e + +LIB_ROOT=../.. +REPO="cypherstack/frostdart" +BASE_URL="https://github.com/${REPO}/releases/download" + +TAG=$(git -C "$LIB_ROOT" describe --tags --exact-match HEAD 2>/dev/null) || { + echo "Error: frostdart is not at a tagged commit." + echo "Pin the submodule to a release tag to use download mode." + echo "Current commit: $(git -C "$LIB_ROOT" rev-parse HEAD)" + exit 1 +} + +TMPDIR=$(mktemp -d) +trap 'rm -rf "$TMPDIR"' EXIT + +curl -fSL "${BASE_URL}/${TAG}/checksums.txt" -o "$TMPDIR/checksums.txt" + +download_and_verify() { + local asset="$1" + curl -fSL "${BASE_URL}/${TAG}/${asset}" -o "$TMPDIR/${asset}" + grep "^[0-9a-f]* ${asset}$" "$TMPDIR/checksums.txt" | (cd "$TMPDIR" && shasum -a 256 -c) +} + +download_and_verify "frostdart-ios-aarch64.a" + +cp "$TMPDIR/frostdart-ios-aarch64.a" "$LIB_ROOT/ios/libfrostdart.a"