Skip to content

feat(ffi): refresh ant-ffi to current ant-core API + Swift xcframework pipeline - #150

Merged
Nic-dorman merged 2 commits into
mainfrom
feat/ffi-swift-pipeline
May 28, 2026
Merged

feat(ffi): refresh ant-ffi to current ant-core API + Swift xcframework pipeline#150
Nic-dorman merged 2 commits into
mainfrom
feat/ffi-swift-pipeline

Conversation

@Nic-dorman

@Nic-dorman Nic-dorman commented May 28, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Rewires ant-ffi against current ant-core HEAD (eliminates the evmlib 0.5.0/0.8.1 graph skew by routing wallet/network types through ant_core::data::{Wallet, EvmNetwork, CustomNetwork} re-exports — per ant-core/CLAUDE.md, "do not add direct evmlib deps")
  • Pins ant-core to a specific git rev for reproducible builds
  • Drops the broken external-signer surface for now (the new ExternalPaymentInfo WaveBatch/Merkle enum needs deliberate FFI redesign; wallet-backed uploads are the primary mobile path, external-signer comes back as a followup)
  • Removes #[uniffi::export] impl XError {} accessors (uniffi 0.29 doesn't allow it on Error enums)
  • Adds an in-crate uniffi-bindgen binary so the bindgen is always pinned to the same uniffi version as the lib (at src/uniffi-bindgen.rs not src/bin/ because the monorepo root .gitignore swallows any bin/ tree as a C# build output)
  • Adds ffi/scripts/build-swift.sh: cross-compiles for aarch64-apple-ios, aarch64-apple-ios-sim, aarch64-apple-darwin; runs uniffi-bindgen; assembles AntFfi.xcframework; produces a SHA256-checksummed zip
  • Ignores ffi/build/ output tree

Context

WithAutonomi/ant-swift v0.0.1 was hand-bootstrapped against the artifact this script produces and is consumed-verified end-to-end against a fresh URL-dep consumer. CI automation tracked in #149.

Test plan

  • cargo build --release -p ant-ffi (host)
  • cargo build --release -p ant-ffi --target aarch64-apple-ios
  • cargo build --release -p ant-ffi --target aarch64-apple-ios-sim
  • ./ffi/scripts/build-swift.sh produces a 112 MB AntFfi.xcframework.zip
  • swift build against the published v0.0.1 (URL dep) runs Client.connectLocal() cleanly on macOS
  • iOS Simulator smoke test (running now in a separate scratch project)

…k pipeline

The ant-ffi crate had drifted against ant-core / evmlib HEAD (PreparedUpload
shape, evmlib version skew via a direct dep, Url vs String types, etc.) and
the build path only produced a host dylib — no iOS slice, no xcframework, no
SPM-consumable package.

Changes:
- Re-route wallet/network types through ant_core::data re-exports
  (Wallet, EvmNetwork, CustomNetwork) so we follow ant-core/CLAUDE.md's
  "do not add direct evmlib deps" rule. Drops the direct evmlib pin and
  resolves the 0.5.0/0.8.1 graph skew.
- Pin ant-core to a specific git rev for reproducible builds.
- Drop the external-signer surface (prepare/finalize) for this iteration —
  ExternalPaymentInfo was restructured into a WaveBatch/Merkle enum; the
  new shape needs deliberate FFI redesign and isn't critical for mobile,
  where wallet-backed uploads are the primary path. To be re-added.
- Remove the `#[uniffi::export] impl XError {}` accessor blocks; uniffi
  0.29 doesn't permit exporting methods on Error enums.
- Add an in-crate `uniffi-bindgen` binary (cargo run --bin uniffi-bindgen)
  so the bindgen is always pinned to the same uniffi version as the lib.
  (Lives at src/uniffi-bindgen.rs not src/bin/ because the monorepo
  root .gitignore swallows any bin/ tree as a C# build output.)
- Add `ffi/scripts/build-swift.sh`: cross-compiles for aarch64-apple-ios,
  aarch64-apple-ios-sim, and aarch64-apple-darwin; runs uniffi-bindgen;
  assembles AntFfi.xcframework; produces a SHA256-checksummed zip ready
  for the GH release that ant-swift's Package.swift binaryTarget points at.
- Ignore ffi/build/ output tree.

ant-swift v0.0.1 has been hand-bootstrapped against the artifact this
script produces; CI automation tracked in #149.
@Nic-dorman

Copy link
Copy Markdown
Collaborator Author

iOS Simulator smoke test result (XCTest against published v0.0.1, URL dep):

Test Suite 'AntFfiSmokeTests' started at 2026-05-28 12:21:07.378.
Test Case '-[AntFfiSmokeTests.AntFfiSmokeTests testConnectLocalReturnsClient]' started.
AntFfi smoke: Client.connectLocal() succeeded on iOS Simulator
Test Case '-[AntFfiSmokeTests.AntFfiSmokeTests testConnectLocalReturnsClient]' passed (0.013 seconds).
Test Suite 'AntFfiSmokeTests' passed

Proves the whole chain: SPM resolves URL dep → xcframework downloaded + checksum verified → static lib links into iOS sim test bundle → tokio runtime spins up under Apple libdispatch → libp2p P2PNode initialises → Client returned. 13ms cold start.

Followup smoke v2 (with a live local devnet): tracked separately; the first version intentionally validates linking + runtime init without depending on external network setup.

A read-only constructor that reads the JSON manifest a running
LocalDevnet writes on startup (bootstrap peers, EVM RPC, funded wallet
key) and returns a Client wired up for chunk_put / chunk_get against
the devnet.

`allow_loopback(true)` and `local(true)` are required — saorsa-core
filters loopback addresses as non-routable by default, so a devnet
flow without those flags silently never connects and the first
write fails with "Found 0 peers, need 7".

The wait-for-peers poll bumps to 60×250ms (15s) and requires
≥7 peers (close-group size) before returning, matching what
chunk_put expects rather than the weaker "any peer" check.
Nic-dorman pushed a commit that referenced this pull request May 28, 2026
Mirrors the Swift pipeline added in #150 for the Android side:

- ffi/scripts/build-android.sh: cross-compiles ant-ffi for the 3
  Android ABIs Google Play covers (arm64-v8a + armeabi-v7a + x86_64;
  32-bit x86 skipped), runs uniffi-bindgen kotlin, drops the .so files
  into the Gradle project's jniLibs, then drives `gradle assembleRelease`
  to produce the AAR.
- ffi/android/: minimal Android Gradle library project. AGP 8.5.2,
  Kotlin 1.9.25, compileSdk 34, minSdk 24. Depends on JNA (uniffi's
  Kotlin runtime) and kotlinx-coroutines (for the `suspend fn` wrappers).
- Output: build/ant-android-release.aar (~27 MB across 3 ABIs).

ant-android v0.0.1 has been hand-bootstrapped against the artifact
this script produces and is live at:
  https://github.com/WithAutonomi/ant-android/releases/tag/v0.0.1

CI automation tracked alongside the Swift side in #149.
@Nic-dorman
Nic-dorman merged commit 91d4236 into main May 28, 2026
@Nic-dorman
Nic-dorman deleted the feat/ffi-swift-pipeline branch May 28, 2026 16:59
Nic-dorman added a commit that referenced this pull request May 28, 2026
* feat(ffi): refresh ant-ffi to current ant-core API + Swift xcframework pipeline

The ant-ffi crate had drifted against ant-core / evmlib HEAD (PreparedUpload
shape, evmlib version skew via a direct dep, Url vs String types, etc.) and
the build path only produced a host dylib — no iOS slice, no xcframework, no
SPM-consumable package.

Changes:
- Re-route wallet/network types through ant_core::data re-exports
  (Wallet, EvmNetwork, CustomNetwork) so we follow ant-core/CLAUDE.md's
  "do not add direct evmlib deps" rule. Drops the direct evmlib pin and
  resolves the 0.5.0/0.8.1 graph skew.
- Pin ant-core to a specific git rev for reproducible builds.
- Drop the external-signer surface (prepare/finalize) for this iteration —
  ExternalPaymentInfo was restructured into a WaveBatch/Merkle enum; the
  new shape needs deliberate FFI redesign and isn't critical for mobile,
  where wallet-backed uploads are the primary path. To be re-added.
- Remove the `#[uniffi::export] impl XError {}` accessor blocks; uniffi
  0.29 doesn't permit exporting methods on Error enums.
- Add an in-crate `uniffi-bindgen` binary (cargo run --bin uniffi-bindgen)
  so the bindgen is always pinned to the same uniffi version as the lib.
  (Lives at src/uniffi-bindgen.rs not src/bin/ because the monorepo
  root .gitignore swallows any bin/ tree as a C# build output.)
- Add `ffi/scripts/build-swift.sh`: cross-compiles for aarch64-apple-ios,
  aarch64-apple-ios-sim, and aarch64-apple-darwin; runs uniffi-bindgen;
  assembles AntFfi.xcframework; produces a SHA256-checksummed zip ready
  for the GH release that ant-swift's Package.swift binaryTarget points at.
- Ignore ffi/build/ output tree.

ant-swift v0.0.1 has been hand-bootstrapped against the artifact this
script produces; CI automation tracked in #149.

* feat(ffi): add Client.connectFromDevnetManifest for local devnet testing

A read-only constructor that reads the JSON manifest a running
LocalDevnet writes on startup (bootstrap peers, EVM RPC, funded wallet
key) and returns a Client wired up for chunk_put / chunk_get against
the devnet.

`allow_loopback(true)` and `local(true)` are required — saorsa-core
filters loopback addresses as non-routable by default, so a devnet
flow without those flags silently never connects and the first
write fails with "Found 0 peers, need 7".

The wait-for-peers poll bumps to 60×250ms (15s) and requires
≥7 peers (close-group size) before returning, matching what
chunk_put expects rather than the weaker "any peer" check.

* feat(ffi): add Android AAR build pipeline

Mirrors the Swift pipeline added in #150 for the Android side:

- ffi/scripts/build-android.sh: cross-compiles ant-ffi for the 3
  Android ABIs Google Play covers (arm64-v8a + armeabi-v7a + x86_64;
  32-bit x86 skipped), runs uniffi-bindgen kotlin, drops the .so files
  into the Gradle project's jniLibs, then drives `gradle assembleRelease`
  to produce the AAR.
- ffi/android/: minimal Android Gradle library project. AGP 8.5.2,
  Kotlin 1.9.25, compileSdk 34, minSdk 24. Depends on JNA (uniffi's
  Kotlin runtime) and kotlinx-coroutines (for the `suspend fn` wrappers).
- Output: build/ant-android-release.aar (~27 MB across 3 ABIs).

ant-android v0.0.1 has been hand-bootstrapped against the artifact
this script produces and is live at:
  https://github.com/WithAutonomi/ant-android/releases/tag/v0.0.1

CI automation tracked alongside the Swift side in #149.

---------

Co-authored-by: Nic <nic@unknown.home>
Nic-dorman added a commit that referenced this pull request May 28, 2026
Closes the gRPC parity gap with REST: external-signer (UploadService +
chunks PrepareChunk/FinalizeChunk) and WalletService are now reachable
over gRPC, plus stream-download stubs return honest UNIMPLEMENTED/501
instead of pretending. All 11 gRPC-capable SDKs follow with matching
fan-out.

## Additive (antd daemon)

- gRPC UploadService + chunks prepare/finalize — external-signer two-phase
  upload + single-chunk publish over gRPC, mirroring REST 1:1 (#140)
- gRPC WalletService — GetAddress / GetBalance / Approve, parity with
  REST /v1/wallet/* (#154)
- /v1/data/prepare now honors visibility for public DataMap chunk
  bundling via data_prepare_upload_with_visibility (#138)

## Fixes (antd daemon)

- Stream-download stubs (DataServiceStub.StreamDownload, REST
  /v1/data/stream/*) now return UNIMPLEMENTED / 501 honestly rather
  than empty success (#155)

## SDK fan-out — external-signer (gRPC prepare/finalize)

All 11 gRPC-capable SDKs replace their stub raises with real gRPC calls
to the new UploadService + ChunkService PrepareChunk/FinalizeChunk RPCs:

- antd-rust (#169), antd-go (#170), antd-py (#171), antd-java (#172),
  antd-kotlin (#173), antd-csharp (#174), antd-ruby (#175),
  antd-dart (#176), antd-swift (#177), antd-cpp (#178),
  antd-elixir (#179)

## SDK fan-out — WalletService

Same 11 SDKs gain walletAddress / walletBalance / walletApprove over gRPC:

- antd-rust (#180), antd-go (#181), antd-py (#182), antd-java (#183),
  antd-kotlin (#184), antd-csharp (#185), antd-ruby (#186),
  antd-dart (#187), antd-swift (#188), antd-cpp (#189),
  antd-elixir (#190)

## SDK examples + build fixes

- antd-ruby: payForQuotes tuple args as Hash for eth-0.5.13
  compatibility (#131)
- antd-go + ant-dev: add 03-chunks + 06-private-data examples;
  renumber 03-files to 04-files (#132)
- antd-java + antd-cpp: close async client surface gaps (#133)
- ant-dev: pull antd[rest,grpc] extras so 08_grpc example runs out
  of the box (#134)
- antd-js + antd-py + antd-go READMEs: surface external-signer
  methods + 07 example (#135)
- antd-elixir: 07_external_signer example via cast shell-out (#136)
- antd-swift: 07_external_signer example + fix FinalizeUploadDTO
  optional address (#137)
- antd-php: empty tx_hashes serializes as JSON object on finalize
  (#139)

## FFI

- ant-ffi refresh against current ant-core API + Swift xcframework
  build pipeline (#150)
- Android AAR build pipeline (#156)

## Infra

- CI: auto-tag Go submodules on umbrella release tag push (#129)
- Deploy: publish multi-arch withautonomi/antd image from ant-sdk
  release (#130)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant