Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(swiftsdk): swift sdk scaffolding #38

Merged
merged 1 commit into from
Dec 13, 2024
Merged
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
7 changes: 7 additions & 0 deletions .github/package.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ZKsyncSSO"
BuildableName = "ZKsyncSSO"
BlueprintName = "ZKsyncSSO"
ReferencedContainer = "container:../packages/sdk-platforms/swift/ZKsyncSSO">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ZKsyncSSOTests"
BuildableName = "ZKsyncSSOTests"
BlueprintName = "ZKsyncSSOTests"
ReferencedContainer = "container:../packages/sdk-platforms/swift/ZKsyncSSO">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ZKsyncSSOTests"
BuildableName = "ZKsyncSSOTests"
BlueprintName = "ZKsyncSSOTests"
ReferencedContainer = "container:../packages/sdk-platforms/swift/ZKsyncSSO">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "ZKsyncSSO"
BuildableName = "ZKsyncSSO"
BlueprintName = "ZKsyncSSO"
ReferencedContainer = "container:../packages/sdk-platforms/swift/ZKsyncSSO">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
45 changes: 45 additions & 0 deletions .github/workflows/ci-swift.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Swift CI

on:
push:
paths:
- 'packages/sdk-platforms/**'

jobs:
swift-sdk:
name: Swift Package - latest
runs-on: macos-15
strategy:
matrix:
config:
- debug
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Run sccache-cache
uses: mozilla-actions/[email protected]
- run: rustup update stable && rustup default stable
- name: Select Xcode 16.1
run: sudo xcode-select -s /Applications/Xcode_16.1.app
- name: Select Simulator
run: |
UDID=$(xcrun simctl list devices | awk '/-- iOS 18.1 --/{flag=1; next} /--/{flag=0} flag' | grep "iPhone 16 Pro" | awk -F '[()]' '{print $2}' | head -1)
if [ -z "$UDID" ]; then
echo "Simulator not found!" >&2
exit 1
fi
echo "Simulator UDID: $UDID"
echo "SIMULATOR_UDID=$UDID" >> $GITHUB_ENV
- name: Install swiftformat
run: brew install swiftformat
- name: Build bindings
run: sh packages/sdk-platforms/rust/zksync-sso/crates/ffi/build-swift-framework.sh
- name: Build & test Swift SDK
run: |
xcodebuild test \
-skipMacroValidation \
-configuration debug \
-workspace .github/package.xcworkspace \
-scheme zksyncsso \
-destination "platform=iOS Simulator,id=${{ env.SIMULATOR_UDID }}" || exit 1
3 changes: 2 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ name: CI

on:
pull_request:
paths-ignore:
- 'packages/sdk-platforms/**'
workflow_dispatch:

jobs:
Expand Down Expand Up @@ -166,4 +168,3 @@ jobs:
- name: Run contract test
run: pnpm test
working-directory: packages/contracts

16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,19 @@ playwright/.cache/
.DS_Store

dist

# Rust
debug/
target/
Cargo.lock

# Swift
xcuserdata/
*.hmap
*.ipa
*.dSYM.zip
*.dSYM
timeline.xctimeline
playground.xcworkspace
.build/
out/
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@ deployments-zk
**/*.tsx
**/*.mjs
**/*.cjs

# Ignore Swift/Rust files
packages/sdk-platforms/*
3 changes: 2 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"**/test-results/**",
"**/playwright-report/**",
"**/blob-report/**",
"**/playwright/.cache/**"
"**/playwright/.cache/**",
"packages/sdk-platforms/**"
],
"caseSensitive": true,
"dictionaries": [
Expand Down
11 changes: 11 additions & 0 deletions packages/sdk-platforms/rust/zksync-sso/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[workspace]
members = ["crates/*"]
resolver = "2"

[workspace.package]
version = "0.1.0"
edition = "2021"
rust-version = "1.83"
license = "Apache-2.0"

[workspace.dependencies]
9 changes: 9 additions & 0 deletions packages/sdk-platforms/rust/zksync-sso/crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "cli"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true

[dependencies]
sdk = { path = "../sdk" }
3 changes: 3 additions & 0 deletions packages/sdk-platforms/rust/zksync-sso/crates/cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("{}", format!("{}", sdk::add(1, 1)));
}
16 changes: 16 additions & 0 deletions packages/sdk-platforms/rust/zksync-sso/crates/ffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "ffi"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true

[lib]
crate-type = ["staticlib"]

[dependencies]
uniffi = { version = "0.28.3", features = ["cli"] }
sdk = { path = "../sdk" }

[build-dependencies]
uniffi = { version = "0.28.3", features = ["build", "cli"] }
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#!/bin/sh

set -eo pipefail

pushd `dirname $0`
trap popd EXIT

NAME="ffi"
VERSION=${1:-"1.0"} # first arg or "1.0"
REVERSE_DOMAIN="dev.matterlabs"
BUNDLE_IDENTIFIER="$REVERSE_DOMAIN.$NAME"
LIBRARY_NAME="lib$NAME.a"
FRAMEWORK_LIBRARY_NAME=${NAME}FFI
FRAMEWORK_NAME="$FRAMEWORK_LIBRARY_NAME.framework"
XC_FRAMEWORK_NAME="$FRAMEWORK_LIBRARY_NAME.xcframework"
HEADER_NAME="${NAME}FFI.h"
OUT_PATH="out"
MIN_IOS_VERSION="18.0"
WRAPPER_PATH="../../../../swift/ZKsyncSSO/Sources/ZKsyncSSOFFI"
TARGET_PATH="../../target"
BUILD_TYPE="debug" # use debug during development

AARCH64_APPLE_IOS_PATH="$TARGET_PATH/aarch64-apple-ios/$BUILD_TYPE"
AARCH64_APPLE_IOS_SIM_PATH="$TARGET_PATH/aarch64-apple-ios-sim/$BUILD_TYPE"
X86_64_APPLE_IOS_PATH="$TARGET_PATH/x86_64-apple-ios/$BUILD_TYPE"
AARCH64_APPLE_DARWIN_PATH="$TARGET_PATH/aarch64-apple-darwin/$BUILD_TYPE"
X86_64_APPLE_DARWIN_PATH="$TARGET_PATH/x86_64-apple-darwin/$BUILD_TYPE"

targets=("aarch64-apple-ios" "aarch64-apple-ios-sim" "x86_64-apple-ios" "aarch64-apple-darwin" "x86_64-apple-darwin")

# Build for all targets
for target in "${targets[@]}"; do
echo "Building for $target..."
rustup target add $target

if [ "$BUILD_TYPE" = "debug" ]; then
echo "Building debug for $target"
cargo build --target $target
else
echo "Building release for $target"
cargo build --release --target $target
fi
done

# Generate swift wrapper
echo "Generating swift wrapper..."
mkdir -p $OUT_PATH
mkdir -p $WRAPPER_PATH
CURRENT_ARCH=$(rustc --version --verbose | grep host | cut -f2 -d' ')
cargo run --features=uniffi/cli --bin uniffi-bindgen generate --library $TARGET_PATH/$CURRENT_ARCH/$BUILD_TYPE/$LIBRARY_NAME --language swift --out-dir $OUT_PATH

# Merge libraries with lipo
echo "Merging libraries with lipo..."
lipo -create $AARCH64_APPLE_IOS_SIM_PATH/$LIBRARY_NAME \
$X86_64_APPLE_IOS_PATH/$LIBRARY_NAME \
-output $OUT_PATH/sim-$LIBRARY_NAME
lipo -create $AARCH64_APPLE_DARWIN_PATH/$LIBRARY_NAME \
$X86_64_APPLE_DARWIN_PATH/$LIBRARY_NAME \
-output $OUT_PATH/macos-$LIBRARY_NAME

# Create framework template
rm -rf $OUT_PATH/$FRAMEWORK_NAME
mkdir -p $OUT_PATH/$FRAMEWORK_NAME/Headers
mkdir -p $OUT_PATH/$FRAMEWORK_NAME/Modules
cp $OUT_PATH/$HEADER_NAME $OUT_PATH/$FRAMEWORK_NAME/Headers
cat <<EOT > $OUT_PATH/$FRAMEWORK_NAME/Modules/module.modulemap
framework module $FRAMEWORK_LIBRARY_NAME {
umbrella header "$HEADER_NAME"

export *
module * { export * }
}
EOT

cat <<EOT > $OUT_PATH/$FRAMEWORK_NAME/Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$FRAMEWORK_LIBRARY_NAME</string>
<key>CFBundleIdentifier</key>
<string>$BUNDLE_IDENTIFIER</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$FRAMEWORK_LIBRARY_NAME</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>$VERSION</string>
<key>NSPrincipalClass</key>
<string></string>
<key>MinimumOSVersion</key>
<string>$MIN_IOS_VERSION</string>
</dict>
</plist>
EOT

# Prepare frameworks for each platform
rm -rf $OUT_PATH/frameworks
mkdir -p $OUT_PATH/frameworks/sim
mkdir -p $OUT_PATH/frameworks/ios
mkdir -p $OUT_PATH/frameworks/macos
cp -r $OUT_PATH/$FRAMEWORK_NAME $OUT_PATH/frameworks/sim/
cp -r $OUT_PATH/$FRAMEWORK_NAME $OUT_PATH/frameworks/ios/
cp -r $OUT_PATH/$FRAMEWORK_NAME $OUT_PATH/frameworks/macos/
mv $OUT_PATH/sim-$LIBRARY_NAME $OUT_PATH/frameworks/sim/$FRAMEWORK_NAME/$FRAMEWORK_LIBRARY_NAME
mv $OUT_PATH/macos-$LIBRARY_NAME $OUT_PATH/frameworks/macos/$FRAMEWORK_NAME/$FRAMEWORK_LIBRARY_NAME
cp $AARCH64_APPLE_IOS_PATH/$LIBRARY_NAME $OUT_PATH/frameworks/ios/$FRAMEWORK_NAME/$FRAMEWORK_LIBRARY_NAME

# Create xcframework
echo "Creating xcframework..."
rm -rf $OUT_PATH/$XC_FRAMEWORK_NAME
xcodebuild -create-xcframework \
-framework $OUT_PATH/frameworks/sim/$FRAMEWORK_NAME \
-framework $OUT_PATH/frameworks/ios/$FRAMEWORK_NAME \
-framework $OUT_PATH/frameworks/macos/$FRAMEWORK_NAME \
-output $OUT_PATH/$XC_FRAMEWORK_NAME

# Copy swift wrapper
# Need some temporary workarounds to compile swift wrapper
# https://github.com/rust-lang/cargo/issues/11953
cat <<EOT > $OUT_PATH/import.txt
#if os(macOS)
import SystemConfiguration
#endif
EOT
cat $OUT_PATH/import.txt $OUT_PATH/$NAME.swift > $WRAPPER_PATH/$NAME.swift

# Fix initializationResult compilation error
sed -i '' 's/private var initializationResult: InitializationResult = {/private let initializationResult: InitializationResult = {/' "$WRAPPER_PATH/$NAME.swift"

# Don't format ffi.swift with swift-format
echo "// swift-format-ignore-file" | cat - "$WRAPPER_PATH/$NAME.swift" > temp && mv temp "$WRAPPER_PATH/$NAME.swift"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
uniffi::uniffi_bindgen_main()
}
Loading
Loading