From 1133ca5a6032c688d4720b2b983d2f1dd8300d0a Mon Sep 17 00:00:00 2001
From: jackpooleyml <186731786+jackpooleyml@users.noreply.github.com>
Date: Wed, 11 Dec 2024 12:17:59 +0100
Subject: [PATCH] feat(swiftsdk): swift sdk scaffolding
---
.../contents.xcworkspacedata | 7 +
.../xcshareddata/IDEWorkspaceChecks.plist | 8 +
.../xcshareddata/xcschemes/zksyncsso.xcscheme | 92 +++
.github/workflows/ci-swift.yml | 48 ++
.github/workflows/ci.yml | 1 -
.gitignore | 16 +
.../contents.xcworkspacedata | 7 +
platforms/shared/zksync-sso/Cargo.toml | 11 +
.../shared/zksync-sso/crates/cli/Cargo.toml | 9 +
.../shared/zksync-sso/crates/cli/src/main.rs | 3 +
.../shared/zksync-sso/crates/ffi/Cargo.toml | 16 +
.../crates/ffi/build-swift-framework.sh | 136 ++++
.../crates/ffi/src/bin/uniffi-bindgen.rs | 3 +
.../shared/zksync-sso/crates/ffi/src/lib.rs | 30 +
.../shared/zksync-sso/crates/sdk/Cargo.toml | 9 +
.../shared/zksync-sso/crates/sdk/src/lib.rs | 14 +
platforms/shared/zksync-sso/rustfmt.toml | 7 +
platforms/swift/ZKsyncSSO/.gitignore | 8 +
.../Example/Example.xcodeproj/project.pbxproj | 580 ++++++++++++++++++
.../contents.xcworkspacedata | 7 +
.../AccentColor.colorset/Contents.json | 11 +
.../AppIcon.appiconset/Contents.json | 35 ++
.../Example/Assets.xcassets/Contents.json | 6 +
.../Example/Example/ContentView.swift | 18 +
.../Examples/Example/Example/ExampleApp.swift | 10 +
.../Preview Assets.xcassets/Contents.json | 6 +
.../Example/ExampleTests/ExampleTests.swift | 10 +
.../ExampleUITests/ExampleUITests.swift | 36 ++
.../ExampleUITestsLaunchTests.swift | 26 +
platforms/swift/ZKsyncSSO/Package.swift | 29 +
.../Sources/ZKsyncSSO/ZKsyncSSO.swift | 9 +
.../ZKsyncSSO/Sources/ZKsyncSSOFFI/ffi.swift | 512 ++++++++++++++++
.../Tests/ZKsyncSSOTests/ZKsyncSSOTests.swift | 10 +
33 files changed, 1729 insertions(+), 1 deletion(-)
create mode 100644 .github/package.xcworkspace/contents.xcworkspacedata
create mode 100644 .github/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
create mode 100644 .github/package.xcworkspace/xcshareddata/xcschemes/zksyncsso.xcscheme
create mode 100644 .github/workflows/ci-swift.yml
create mode 100644 .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
create mode 100644 platforms/shared/zksync-sso/Cargo.toml
create mode 100644 platforms/shared/zksync-sso/crates/cli/Cargo.toml
create mode 100644 platforms/shared/zksync-sso/crates/cli/src/main.rs
create mode 100644 platforms/shared/zksync-sso/crates/ffi/Cargo.toml
create mode 100644 platforms/shared/zksync-sso/crates/ffi/build-swift-framework.sh
create mode 100644 platforms/shared/zksync-sso/crates/ffi/src/bin/uniffi-bindgen.rs
create mode 100644 platforms/shared/zksync-sso/crates/ffi/src/lib.rs
create mode 100644 platforms/shared/zksync-sso/crates/sdk/Cargo.toml
create mode 100644 platforms/shared/zksync-sso/crates/sdk/src/lib.rs
create mode 100644 platforms/shared/zksync-sso/rustfmt.toml
create mode 100644 platforms/swift/ZKsyncSSO/.gitignore
create mode 100644 platforms/swift/ZKsyncSSO/Examples/Example/Example.xcodeproj/project.pbxproj
create mode 100644 platforms/swift/ZKsyncSSO/Examples/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
create mode 100644 platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/AccentColor.colorset/Contents.json
create mode 100644 platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json
create mode 100644 platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/Contents.json
create mode 100644 platforms/swift/ZKsyncSSO/Examples/Example/Example/ContentView.swift
create mode 100644 platforms/swift/ZKsyncSSO/Examples/Example/Example/ExampleApp.swift
create mode 100644 platforms/swift/ZKsyncSSO/Examples/Example/Example/Preview Content/Preview Assets.xcassets/Contents.json
create mode 100644 platforms/swift/ZKsyncSSO/Examples/Example/ExampleTests/ExampleTests.swift
create mode 100644 platforms/swift/ZKsyncSSO/Examples/Example/ExampleUITests/ExampleUITests.swift
create mode 100644 platforms/swift/ZKsyncSSO/Examples/Example/ExampleUITests/ExampleUITestsLaunchTests.swift
create mode 100644 platforms/swift/ZKsyncSSO/Package.swift
create mode 100644 platforms/swift/ZKsyncSSO/Sources/ZKsyncSSO/ZKsyncSSO.swift
create mode 100644 platforms/swift/ZKsyncSSO/Sources/ZKsyncSSOFFI/ffi.swift
create mode 100644 platforms/swift/ZKsyncSSO/Tests/ZKsyncSSOTests/ZKsyncSSOTests.swift
diff --git a/.github/package.xcworkspace/contents.xcworkspacedata b/.github/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..7cb2e47
--- /dev/null
+++ b/.github/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/.github/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/.github/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/.github/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/.github/package.xcworkspace/xcshareddata/xcschemes/zksyncsso.xcscheme b/.github/package.xcworkspace/xcshareddata/xcschemes/zksyncsso.xcscheme
new file mode 100644
index 0000000..65f0108
--- /dev/null
+++ b/.github/package.xcworkspace/xcshareddata/xcschemes/zksyncsso.xcscheme
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.github/workflows/ci-swift.yml b/.github/workflows/ci-swift.yml
new file mode 100644
index 0000000..bdc5886
--- /dev/null
+++ b/.github/workflows/ci-swift.yml
@@ -0,0 +1,48 @@
+name: Swift CI
+
+on:
+ pull_request:
+ paths:
+ - 'platforms/**'
+ push:
+ paths:
+ - '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/sccache-action@v0.0.4
+ - 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 platforms/shared/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
\ No newline at end of file
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0225e7c..9ef5030 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -166,4 +166,3 @@ jobs:
- name: Run contract test
run: pnpm test
working-directory: packages/contracts
-
diff --git a/.gitignore b/.gitignore
index c8436fb..1411f3c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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/
\ No newline at end of file
diff --git a/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/platforms/shared/zksync-sso/Cargo.toml b/platforms/shared/zksync-sso/Cargo.toml
new file mode 100644
index 0000000..977d595
--- /dev/null
+++ b/platforms/shared/zksync-sso/Cargo.toml
@@ -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]
diff --git a/platforms/shared/zksync-sso/crates/cli/Cargo.toml b/platforms/shared/zksync-sso/crates/cli/Cargo.toml
new file mode 100644
index 0000000..a909783
--- /dev/null
+++ b/platforms/shared/zksync-sso/crates/cli/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "cli"
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+
+[dependencies]
+sdk = { path = "../sdk" }
diff --git a/platforms/shared/zksync-sso/crates/cli/src/main.rs b/platforms/shared/zksync-sso/crates/cli/src/main.rs
new file mode 100644
index 0000000..7d11134
--- /dev/null
+++ b/platforms/shared/zksync-sso/crates/cli/src/main.rs
@@ -0,0 +1,3 @@
+fn main() {
+ println!("{}", format!("{}", sdk::add(1, 1)));
+}
diff --git a/platforms/shared/zksync-sso/crates/ffi/Cargo.toml b/platforms/shared/zksync-sso/crates/ffi/Cargo.toml
new file mode 100644
index 0000000..bcba491
--- /dev/null
+++ b/platforms/shared/zksync-sso/crates/ffi/Cargo.toml
@@ -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"] }
diff --git a/platforms/shared/zksync-sso/crates/ffi/build-swift-framework.sh b/platforms/shared/zksync-sso/crates/ffi/build-swift-framework.sh
new file mode 100644
index 0000000..c52f3e8
--- /dev/null
+++ b/platforms/shared/zksync-sso/crates/ffi/build-swift-framework.sh
@@ -0,0 +1,136 @@
+#!/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 < $OUT_PATH/$FRAMEWORK_NAME/Modules/module.modulemap
+framework module $FRAMEWORK_LIBRARY_NAME {
+ umbrella header "$HEADER_NAME"
+
+ export *
+ module * { export * }
+}
+EOT
+
+cat < $OUT_PATH/$FRAMEWORK_NAME/Info.plist
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ $FRAMEWORK_LIBRARY_NAME
+ CFBundleIdentifier
+ $BUNDLE_IDENTIFIER
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $FRAMEWORK_LIBRARY_NAME
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ $VERSION
+ NSPrincipalClass
+
+ MinimumOSVersion
+ $MIN_IOS_VERSION
+
+
+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 < $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"
\ No newline at end of file
diff --git a/platforms/shared/zksync-sso/crates/ffi/src/bin/uniffi-bindgen.rs b/platforms/shared/zksync-sso/crates/ffi/src/bin/uniffi-bindgen.rs
new file mode 100644
index 0000000..f6cff6c
--- /dev/null
+++ b/platforms/shared/zksync-sso/crates/ffi/src/bin/uniffi-bindgen.rs
@@ -0,0 +1,3 @@
+fn main() {
+ uniffi::uniffi_bindgen_main()
+}
diff --git a/platforms/shared/zksync-sso/crates/ffi/src/lib.rs b/platforms/shared/zksync-sso/crates/ffi/src/lib.rs
new file mode 100644
index 0000000..c424cca
--- /dev/null
+++ b/platforms/shared/zksync-sso/crates/ffi/src/lib.rs
@@ -0,0 +1,30 @@
+use uniffi;
+
+uniffi::setup_scaffolding!();
+
+#[uniffi::export]
+fn greet(name: &str) -> String {
+ format!("Hello, {}", name)
+}
+
+#[uniffi::export]
+fn add(left: u64, right: u64) -> u64 {
+ sdk::add(left, right)
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn add_works() {
+ let result = add(2, 2);
+ assert_eq!(result, 4);
+ }
+
+ #[test]
+ fn greeting_works() {
+ let greeting = greet("Rust");
+ assert_eq!("Hello, Rust", greeting);
+ }
+}
diff --git a/platforms/shared/zksync-sso/crates/sdk/Cargo.toml b/platforms/shared/zksync-sso/crates/sdk/Cargo.toml
new file mode 100644
index 0000000..30a54bf
--- /dev/null
+++ b/platforms/shared/zksync-sso/crates/sdk/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "sdk"
+version.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+license.workspace = true
+
+[dependencies]
+alloy-zksync = { version = "0.5.0" }
diff --git a/platforms/shared/zksync-sso/crates/sdk/src/lib.rs b/platforms/shared/zksync-sso/crates/sdk/src/lib.rs
new file mode 100644
index 0000000..b801279
--- /dev/null
+++ b/platforms/shared/zksync-sso/crates/sdk/src/lib.rs
@@ -0,0 +1,14 @@
+pub fn add(left: u64, right: u64) -> u64 {
+ left + right
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn add_works() {
+ let result = add(2, 2);
+ assert_eq!(result, 4);
+ }
+}
diff --git a/platforms/shared/zksync-sso/rustfmt.toml b/platforms/shared/zksync-sso/rustfmt.toml
new file mode 100644
index 0000000..00d2e7e
--- /dev/null
+++ b/platforms/shared/zksync-sso/rustfmt.toml
@@ -0,0 +1,7 @@
+max_width = 80
+use_small_heuristics = "Max"
+comment_width = 100
+format_code_in_doc_comments = true
+doc_comment_code_block_width = 100
+group_imports = "One"
+imports_granularity = "One"
diff --git a/platforms/swift/ZKsyncSSO/.gitignore b/platforms/swift/ZKsyncSSO/.gitignore
new file mode 100644
index 0000000..0023a53
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/.gitignore
@@ -0,0 +1,8 @@
+.DS_Store
+/.build
+/Packages
+xcuserdata/
+DerivedData/
+.swiftpm/configuration/registries.json
+.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
+.netrc
diff --git a/platforms/swift/ZKsyncSSO/Examples/Example/Example.xcodeproj/project.pbxproj b/platforms/swift/ZKsyncSSO/Examples/Example/Example.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..c8f91e2
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Examples/Example/Example.xcodeproj/project.pbxproj
@@ -0,0 +1,580 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 77;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ D252DD3E2D099CD4006D9A43 /* ZKsyncSSO in Frameworks */ = {isa = PBXBuildFile; productRef = D252DD3D2D099CD4006D9A43 /* ZKsyncSSO */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ D252DD202D099C9C006D9A43 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = D252DD072D099C9A006D9A43 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = D252DD0E2D099C9A006D9A43;
+ remoteInfo = Example;
+ };
+ D252DD2A2D099C9C006D9A43 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = D252DD072D099C9A006D9A43 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = D252DD0E2D099C9A006D9A43;
+ remoteInfo = Example;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ D252DD0F2D099C9A006D9A43 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ D252DD1F2D099C9C006D9A43 /* ExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ D252DD292D099C9C006D9A43 /* ExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFileSystemSynchronizedRootGroup section */
+ D252DD112D099C9A006D9A43 /* Example */ = {
+ isa = PBXFileSystemSynchronizedRootGroup;
+ path = Example;
+ sourceTree = "";
+ };
+ D252DD222D099C9C006D9A43 /* ExampleTests */ = {
+ isa = PBXFileSystemSynchronizedRootGroup;
+ path = ExampleTests;
+ sourceTree = "";
+ };
+ D252DD2C2D099C9C006D9A43 /* ExampleUITests */ = {
+ isa = PBXFileSystemSynchronizedRootGroup;
+ path = ExampleUITests;
+ sourceTree = "";
+ };
+/* End PBXFileSystemSynchronizedRootGroup section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ D252DD0C2D099C9A006D9A43 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ D252DD3E2D099CD4006D9A43 /* ZKsyncSSO in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D252DD1C2D099C9C006D9A43 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D252DD262D099C9C006D9A43 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ D252DD062D099C9A006D9A43 = {
+ isa = PBXGroup;
+ children = (
+ D252DD112D099C9A006D9A43 /* Example */,
+ D252DD222D099C9C006D9A43 /* ExampleTests */,
+ D252DD2C2D099C9C006D9A43 /* ExampleUITests */,
+ D252DD102D099C9A006D9A43 /* Products */,
+ );
+ sourceTree = "";
+ };
+ D252DD102D099C9A006D9A43 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ D252DD0F2D099C9A006D9A43 /* Example.app */,
+ D252DD1F2D099C9C006D9A43 /* ExampleTests.xctest */,
+ D252DD292D099C9C006D9A43 /* ExampleUITests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ D252DD0E2D099C9A006D9A43 /* Example */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D252DD332D099C9C006D9A43 /* Build configuration list for PBXNativeTarget "Example" */;
+ buildPhases = (
+ D252DD0B2D099C9A006D9A43 /* Sources */,
+ D252DD0C2D099C9A006D9A43 /* Frameworks */,
+ D252DD0D2D099C9A006D9A43 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ fileSystemSynchronizedGroups = (
+ D252DD112D099C9A006D9A43 /* Example */,
+ );
+ name = Example;
+ packageProductDependencies = (
+ D252DD3D2D099CD4006D9A43 /* ZKsyncSSO */,
+ );
+ productName = Example;
+ productReference = D252DD0F2D099C9A006D9A43 /* Example.app */;
+ productType = "com.apple.product-type.application";
+ };
+ D252DD1E2D099C9C006D9A43 /* ExampleTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D252DD362D099C9C006D9A43 /* Build configuration list for PBXNativeTarget "ExampleTests" */;
+ buildPhases = (
+ D252DD1B2D099C9C006D9A43 /* Sources */,
+ D252DD1C2D099C9C006D9A43 /* Frameworks */,
+ D252DD1D2D099C9C006D9A43 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ D252DD212D099C9C006D9A43 /* PBXTargetDependency */,
+ );
+ fileSystemSynchronizedGroups = (
+ D252DD222D099C9C006D9A43 /* ExampleTests */,
+ );
+ name = ExampleTests;
+ packageProductDependencies = (
+ );
+ productName = ExampleTests;
+ productReference = D252DD1F2D099C9C006D9A43 /* ExampleTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ D252DD282D099C9C006D9A43 /* ExampleUITests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = D252DD392D099C9C006D9A43 /* Build configuration list for PBXNativeTarget "ExampleUITests" */;
+ buildPhases = (
+ D252DD252D099C9C006D9A43 /* Sources */,
+ D252DD262D099C9C006D9A43 /* Frameworks */,
+ D252DD272D099C9C006D9A43 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ D252DD2B2D099C9C006D9A43 /* PBXTargetDependency */,
+ );
+ fileSystemSynchronizedGroups = (
+ D252DD2C2D099C9C006D9A43 /* ExampleUITests */,
+ );
+ name = ExampleUITests;
+ packageProductDependencies = (
+ );
+ productName = ExampleUITests;
+ productReference = D252DD292D099C9C006D9A43 /* ExampleUITests.xctest */;
+ productType = "com.apple.product-type.bundle.ui-testing";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ D252DD072D099C9A006D9A43 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = 1;
+ LastSwiftUpdateCheck = 1610;
+ LastUpgradeCheck = 1610;
+ TargetAttributes = {
+ D252DD0E2D099C9A006D9A43 = {
+ CreatedOnToolsVersion = 16.1;
+ };
+ D252DD1E2D099C9C006D9A43 = {
+ CreatedOnToolsVersion = 16.1;
+ TestTargetID = D252DD0E2D099C9A006D9A43;
+ };
+ D252DD282D099C9C006D9A43 = {
+ CreatedOnToolsVersion = 16.1;
+ TestTargetID = D252DD0E2D099C9A006D9A43;
+ };
+ };
+ };
+ buildConfigurationList = D252DD0A2D099C9A006D9A43 /* Build configuration list for PBXProject "Example" */;
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = D252DD062D099C9A006D9A43;
+ minimizedProjectReferenceProxies = 1;
+ packageReferences = (
+ D252DD3C2D099CD4006D9A43 /* XCLocalSwiftPackageReference "../../../ZKsyncSSO" */,
+ );
+ preferredProjectObjectVersion = 77;
+ productRefGroup = D252DD102D099C9A006D9A43 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ D252DD0E2D099C9A006D9A43 /* Example */,
+ D252DD1E2D099C9C006D9A43 /* ExampleTests */,
+ D252DD282D099C9C006D9A43 /* ExampleUITests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ D252DD0D2D099C9A006D9A43 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D252DD1D2D099C9C006D9A43 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D252DD272D099C9C006D9A43 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ D252DD0B2D099C9A006D9A43 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D252DD1B2D099C9C006D9A43 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D252DD252D099C9C006D9A43 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ D252DD212D099C9C006D9A43 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = D252DD0E2D099C9A006D9A43 /* Example */;
+ targetProxy = D252DD202D099C9C006D9A43 /* PBXContainerItemProxy */;
+ };
+ D252DD2B2D099C9C006D9A43 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = D252DD0E2D099C9A006D9A43 /* Example */;
+ targetProxy = D252DD2A2D099C9C006D9A43 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+ D252DD312D099C9C006D9A43 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 18.1;
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
+ MTL_FAST_MATH = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ };
+ name = Debug;
+ };
+ D252DD322D099C9C006D9A43 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu17;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 18.1;
+ LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ MTL_FAST_MATH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ D252DD342D099C9C006D9A43 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_ASSET_PATHS = "\"Example/Preview Content\"";
+ ENABLE_PREVIEWS = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
+ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
+ INFOPLIST_KEY_UILaunchScreen_Generation = YES;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = dev.matterlabs.Example;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ D252DD352D099C9C006D9A43 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ DEVELOPMENT_ASSET_PATHS = "\"Example/Preview Content\"";
+ ENABLE_PREVIEWS = YES;
+ GENERATE_INFOPLIST_FILE = YES;
+ INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
+ INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
+ INFOPLIST_KEY_UILaunchScreen_Generation = YES;
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = dev.matterlabs.Example;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = YES;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Release;
+ };
+ D252DD372D099C9C006D9A43 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 18.1;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = dev.matterlabs.ExampleTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Example";
+ };
+ name = Debug;
+ };
+ D252DD382D099C9C006D9A43 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 18.1;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = dev.matterlabs.ExampleTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Example";
+ };
+ name = Release;
+ };
+ D252DD3A2D099C9C006D9A43 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = dev.matterlabs.ExampleUITests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_TARGET_NAME = Example;
+ };
+ name = Debug;
+ };
+ D252DD3B2D099C9C006D9A43 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = dev.matterlabs.ExampleUITests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_EMIT_LOC_STRINGS = NO;
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ TEST_TARGET_NAME = Example;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ D252DD0A2D099C9A006D9A43 /* Build configuration list for PBXProject "Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D252DD312D099C9C006D9A43 /* Debug */,
+ D252DD322D099C9C006D9A43 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D252DD332D099C9C006D9A43 /* Build configuration list for PBXNativeTarget "Example" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D252DD342D099C9C006D9A43 /* Debug */,
+ D252DD352D099C9C006D9A43 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D252DD362D099C9C006D9A43 /* Build configuration list for PBXNativeTarget "ExampleTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D252DD372D099C9C006D9A43 /* Debug */,
+ D252DD382D099C9C006D9A43 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ D252DD392D099C9C006D9A43 /* Build configuration list for PBXNativeTarget "ExampleUITests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ D252DD3A2D099C9C006D9A43 /* Debug */,
+ D252DD3B2D099C9C006D9A43 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+
+/* Begin XCLocalSwiftPackageReference section */
+ D252DD3C2D099CD4006D9A43 /* XCLocalSwiftPackageReference "../../../ZKsyncSSO" */ = {
+ isa = XCLocalSwiftPackageReference;
+ relativePath = ../../../ZKsyncSSO;
+ };
+/* End XCLocalSwiftPackageReference section */
+
+/* Begin XCSwiftPackageProductDependency section */
+ D252DD3D2D099CD4006D9A43 /* ZKsyncSSO */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = ZKsyncSSO;
+ };
+/* End XCSwiftPackageProductDependency section */
+ };
+ rootObject = D252DD072D099C9A006D9A43 /* Project object */;
+}
diff --git a/platforms/swift/ZKsyncSSO/Examples/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/platforms/swift/ZKsyncSSO/Examples/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..919434a
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Examples/Example/Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/AccentColor.colorset/Contents.json b/platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/AccentColor.colorset/Contents.json
new file mode 100644
index 0000000..eb87897
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/AccentColor.colorset/Contents.json
@@ -0,0 +1,11 @@
+{
+ "colors" : [
+ {
+ "idiom" : "universal"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json b/platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..2305880
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,35 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "dark"
+ }
+ ],
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ },
+ {
+ "appearances" : [
+ {
+ "appearance" : "luminosity",
+ "value" : "tinted"
+ }
+ ],
+ "idiom" : "universal",
+ "platform" : "ios",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/Contents.json b/platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Examples/Example/Example/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/platforms/swift/ZKsyncSSO/Examples/Example/Example/ContentView.swift b/platforms/swift/ZKsyncSSO/Examples/Example/Example/ContentView.swift
new file mode 100644
index 0000000..d60821e
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Examples/Example/Example/ContentView.swift
@@ -0,0 +1,18 @@
+import SwiftUI
+import ZKsyncSSO
+
+struct ContentView: View {
+ var body: some View {
+ VStack {
+ Image(systemName: "globe")
+ .imageScale(.large)
+ .foregroundStyle(.tint)
+ Text(greetRust(name: "Rust"))
+ }
+ .padding()
+ }
+}
+
+#Preview {
+ ContentView()
+}
diff --git a/platforms/swift/ZKsyncSSO/Examples/Example/Example/ExampleApp.swift b/platforms/swift/ZKsyncSSO/Examples/Example/Example/ExampleApp.swift
new file mode 100644
index 0000000..7e69ce8
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Examples/Example/Example/ExampleApp.swift
@@ -0,0 +1,10 @@
+import SwiftUI
+
+@main
+struct ExampleApp: App {
+ var body: some Scene {
+ WindowGroup {
+ ContentView()
+ }
+ }
+}
diff --git a/platforms/swift/ZKsyncSSO/Examples/Example/Example/Preview Content/Preview Assets.xcassets/Contents.json b/platforms/swift/ZKsyncSSO/Examples/Example/Example/Preview Content/Preview Assets.xcassets/Contents.json
new file mode 100644
index 0000000..73c0059
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Examples/Example/Example/Preview Content/Preview Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/platforms/swift/ZKsyncSSO/Examples/Example/ExampleTests/ExampleTests.swift b/platforms/swift/ZKsyncSSO/Examples/Example/ExampleTests/ExampleTests.swift
new file mode 100644
index 0000000..9498955
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Examples/Example/ExampleTests/ExampleTests.swift
@@ -0,0 +1,10 @@
+import Testing
+@testable import Example
+
+struct ExampleTests {
+
+ @Test func example() async throws {
+ // Write your test here and use APIs like `#expect(...)` to check expected conditions.
+ }
+
+}
diff --git a/platforms/swift/ZKsyncSSO/Examples/Example/ExampleUITests/ExampleUITests.swift b/platforms/swift/ZKsyncSSO/Examples/Example/ExampleUITests/ExampleUITests.swift
new file mode 100644
index 0000000..0b199fd
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Examples/Example/ExampleUITests/ExampleUITests.swift
@@ -0,0 +1,36 @@
+import XCTest
+
+final class ExampleUITests: XCTestCase {
+
+ override func setUpWithError() throws {
+ // Put setup code here. This method is called before the invocation of each test method in the class.
+
+ // In UI tests it is usually best to stop immediately when a failure occurs.
+ continueAfterFailure = false
+
+ // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
+ }
+
+ override func tearDownWithError() throws {
+ // Put teardown code here. This method is called after the invocation of each test method in the class.
+ }
+
+ @MainActor
+ func testExample() throws {
+ // UI tests must launch the application that they test.
+ let app = XCUIApplication()
+ app.launch()
+
+ // Use XCTAssert and related functions to verify your tests produce the correct results.
+ }
+
+ @MainActor
+ func testLaunchPerformance() throws {
+ if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) {
+ // This measures how long it takes to launch your application.
+ measure(metrics: [XCTApplicationLaunchMetric()]) {
+ XCUIApplication().launch()
+ }
+ }
+ }
+}
diff --git a/platforms/swift/ZKsyncSSO/Examples/Example/ExampleUITests/ExampleUITestsLaunchTests.swift b/platforms/swift/ZKsyncSSO/Examples/Example/ExampleUITests/ExampleUITestsLaunchTests.swift
new file mode 100644
index 0000000..2910808
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Examples/Example/ExampleUITests/ExampleUITestsLaunchTests.swift
@@ -0,0 +1,26 @@
+import XCTest
+
+final class ExampleUITestsLaunchTests: XCTestCase {
+
+ override class var runsForEachTargetApplicationUIConfiguration: Bool {
+ true
+ }
+
+ override func setUpWithError() throws {
+ continueAfterFailure = false
+ }
+
+ @MainActor
+ func testLaunch() throws {
+ let app = XCUIApplication()
+ app.launch()
+
+ // Insert steps here to perform after app launch but before taking a screenshot,
+ // such as logging into a test account or navigating somewhere in the app
+
+ let attachment = XCTAttachment(screenshot: app.screenshot())
+ attachment.name = "Launch Screen"
+ attachment.lifetime = .keepAlways
+ add(attachment)
+ }
+}
diff --git a/platforms/swift/ZKsyncSSO/Package.swift b/platforms/swift/ZKsyncSSO/Package.swift
new file mode 100644
index 0000000..8ea9060
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Package.swift
@@ -0,0 +1,29 @@
+// swift-tools-version: 6.0
+import PackageDescription
+
+let package = Package(
+ name: "ZKsyncSSO",
+ platforms: [
+ .iOS(.v18),
+ .macOS(.v15)
+ ],
+ products: [
+ .library(
+ name: "ZKsyncSSO",
+ targets: ["ZKsyncSSO"]),
+ ],
+ targets: [
+ .target(
+ name: "ZKsyncSSO",
+ dependencies: ["ZKsyncSSOFFI"]),
+ .target(
+ name: "ZKsyncSSOFFI",
+ dependencies: ["ffiFFI"]),
+ .binaryTarget(
+ name: "ffiFFI",
+ path: "../../shared/zksync-sso/crates/ffi/out/ffiFFI.xcframework"),
+ .testTarget(
+ name: "ZKsyncSSOTests",
+ dependencies: ["ZKsyncSSO"]),
+ ]
+)
diff --git a/platforms/swift/ZKsyncSSO/Sources/ZKsyncSSO/ZKsyncSSO.swift b/platforms/swift/ZKsyncSSO/Sources/ZKsyncSSO/ZKsyncSSO.swift
new file mode 100644
index 0000000..e11a6d0
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Sources/ZKsyncSSO/ZKsyncSSO.swift
@@ -0,0 +1,9 @@
+import ZKsyncSSOFFI
+
+public func greetRust(name: String) -> String {
+ greet(name: name)
+}
+
+public func addRust(left: UInt64, right: UInt64) -> UInt64 {
+ add(left: left, right: right)
+}
diff --git a/platforms/swift/ZKsyncSSO/Sources/ZKsyncSSOFFI/ffi.swift b/platforms/swift/ZKsyncSSO/Sources/ZKsyncSSOFFI/ffi.swift
new file mode 100644
index 0000000..2324a18
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Sources/ZKsyncSSOFFI/ffi.swift
@@ -0,0 +1,512 @@
+#if os(macOS)
+import SystemConfiguration
+#endif
+// This file was autogenerated by some hot garbage in the `uniffi` crate.
+// Trust me, you don't want to mess with it!
+
+// swiftlint:disable all
+import Foundation
+
+// Depending on the consumer's build setup, the low-level FFI code
+// might be in a separate module, or it might be compiled inline into
+// this module. This is a bit of light hackery to work with both.
+#if canImport(ffiFFI)
+ import ffiFFI
+#endif
+
+private extension RustBuffer {
+ // Allocate a new buffer, copying the contents of a `UInt8` array.
+ init(bytes: [UInt8]) {
+ let rbuf = bytes.withUnsafeBufferPointer { ptr in
+ RustBuffer.from(ptr)
+ }
+ self.init(capacity: rbuf.capacity, len: rbuf.len, data: rbuf.data)
+ }
+
+ static func empty() -> RustBuffer {
+ RustBuffer(capacity: 0, len: 0, data: nil)
+ }
+
+ static func from(_ ptr: UnsafeBufferPointer) -> RustBuffer {
+ try! rustCall { ffi_ffi_rustbuffer_from_bytes(ForeignBytes(bufferPointer: ptr), $0) }
+ }
+
+ // Frees the buffer in place.
+ // The buffer must not be used after this is called.
+ func deallocate() {
+ try! rustCall { ffi_ffi_rustbuffer_free(self, $0) }
+ }
+}
+
+private extension ForeignBytes {
+ init(bufferPointer: UnsafeBufferPointer) {
+ self.init(len: Int32(bufferPointer.count), data: bufferPointer.baseAddress)
+ }
+}
+
+// For every type used in the interface, we provide helper methods for conveniently
+// lifting and lowering that type from C-compatible data, and for reading and writing
+// values of that type in a buffer.
+
+// Helper classes/extensions that don't change.
+// Someday, this will be in a library of its own.
+
+private extension Data {
+ init(rustBuffer: RustBuffer) {
+ self.init(
+ bytesNoCopy: rustBuffer.data!,
+ count: Int(rustBuffer.len),
+ deallocator: .none
+ )
+ }
+}
+
+// Define reader functionality. Normally this would be defined in a class or
+// struct, but we use standalone functions instead in order to make external
+// types work.
+//
+// With external types, one swift source file needs to be able to call the read
+// method on another source file's FfiConverter, but then what visibility
+// should Reader have?
+// - If Reader is fileprivate, then this means the read() must also
+// be fileprivate, which doesn't work with external types.
+// - If Reader is internal/public, we'll get compile errors since both source
+// files will try define the same type.
+//
+// Instead, the read() method and these helper functions input a tuple of data
+
+private func createReader(data: Data) -> (data: Data, offset: Data.Index) {
+ (data: data, offset: 0)
+}
+
+// Reads an integer at the current offset, in big-endian order, and advances
+// the offset on success. Throws if reading the integer would move the
+// offset past the end of the buffer.
+private func readInt(_ reader: inout (data: Data, offset: Data.Index)) throws -> T {
+ let range = reader.offset ..< reader.offset + MemoryLayout.size
+ guard reader.data.count >= range.upperBound else {
+ throw UniffiInternalError.bufferOverflow
+ }
+ if T.self == UInt8.self {
+ let value = reader.data[reader.offset]
+ reader.offset += 1
+ return value as! T
+ }
+ var value: T = 0
+ let _ = withUnsafeMutableBytes(of: &value) { reader.data.copyBytes(to: $0, from: range) }
+ reader.offset = range.upperBound
+ return value.bigEndian
+}
+
+// Reads an arbitrary number of bytes, to be used to read
+// raw bytes, this is useful when lifting strings
+private func readBytes(_ reader: inout (data: Data, offset: Data.Index), count: Int) throws -> [UInt8] {
+ let range = reader.offset ..< (reader.offset + count)
+ guard reader.data.count >= range.upperBound else {
+ throw UniffiInternalError.bufferOverflow
+ }
+ var value = [UInt8](repeating: 0, count: count)
+ value.withUnsafeMutableBufferPointer { buffer in
+ reader.data.copyBytes(to: buffer, from: range)
+ }
+ reader.offset = range.upperBound
+ return value
+}
+
+// Reads a float at the current offset.
+private func readFloat(_ reader: inout (data: Data, offset: Data.Index)) throws -> Float {
+ return try Float(bitPattern: readInt(&reader))
+}
+
+// Reads a float at the current offset.
+private func readDouble(_ reader: inout (data: Data, offset: Data.Index)) throws -> Double {
+ return try Double(bitPattern: readInt(&reader))
+}
+
+// Indicates if the offset has reached the end of the buffer.
+private func hasRemaining(_ reader: (data: Data, offset: Data.Index)) -> Bool {
+ return reader.offset < reader.data.count
+}
+
+// Define writer functionality. Normally this would be defined in a class or
+// struct, but we use standalone functions instead in order to make external
+// types work. See the above discussion on Readers for details.
+
+private func createWriter() -> [UInt8] {
+ return []
+}
+
+private func writeBytes(_ writer: inout [UInt8], _ byteArr: S) where S: Sequence, S.Element == UInt8 {
+ writer.append(contentsOf: byteArr)
+}
+
+// Writes an integer in big-endian order.
+//
+// Warning: make sure what you are trying to write
+// is in the correct type!
+private func writeInt(_ writer: inout [UInt8], _ value: T) {
+ var value = value.bigEndian
+ withUnsafeBytes(of: &value) { writer.append(contentsOf: $0) }
+}
+
+private func writeFloat(_ writer: inout [UInt8], _ value: Float) {
+ writeInt(&writer, value.bitPattern)
+}
+
+private func writeDouble(_ writer: inout [UInt8], _ value: Double) {
+ writeInt(&writer, value.bitPattern)
+}
+
+// Protocol for types that transfer other types across the FFI. This is
+// analogous to the Rust trait of the same name.
+private protocol FfiConverter {
+ associatedtype FfiType
+ associatedtype SwiftType
+
+ static func lift(_ value: FfiType) throws -> SwiftType
+ static func lower(_ value: SwiftType) -> FfiType
+ static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType
+ static func write(_ value: SwiftType, into buf: inout [UInt8])
+}
+
+// Types conforming to `Primitive` pass themselves directly over the FFI.
+private protocol FfiConverterPrimitive: FfiConverter where FfiType == SwiftType {}
+
+extension FfiConverterPrimitive {
+ #if swift(>=5.8)
+ @_documentation(visibility: private)
+ #endif
+ public static func lift(_ value: FfiType) throws -> SwiftType {
+ return value
+ }
+
+ #if swift(>=5.8)
+ @_documentation(visibility: private)
+ #endif
+ public static func lower(_ value: SwiftType) -> FfiType {
+ return value
+ }
+}
+
+// Types conforming to `FfiConverterRustBuffer` lift and lower into a `RustBuffer`.
+// Used for complex types where it's hard to write a custom lift/lower.
+private protocol FfiConverterRustBuffer: FfiConverter where FfiType == RustBuffer {}
+
+extension FfiConverterRustBuffer {
+ #if swift(>=5.8)
+ @_documentation(visibility: private)
+ #endif
+ public static func lift(_ buf: RustBuffer) throws -> SwiftType {
+ var reader = createReader(data: Data(rustBuffer: buf))
+ let value = try read(from: &reader)
+ if hasRemaining(reader) {
+ throw UniffiInternalError.incompleteData
+ }
+ buf.deallocate()
+ return value
+ }
+
+ #if swift(>=5.8)
+ @_documentation(visibility: private)
+ #endif
+ public static func lower(_ value: SwiftType) -> RustBuffer {
+ var writer = createWriter()
+ write(value, into: &writer)
+ return RustBuffer(bytes: writer)
+ }
+}
+
+// An error type for FFI errors. These errors occur at the UniFFI level, not
+// the library level.
+private enum UniffiInternalError: LocalizedError {
+ case bufferOverflow
+ case incompleteData
+ case unexpectedOptionalTag
+ case unexpectedEnumCase
+ case unexpectedNullPointer
+ case unexpectedRustCallStatusCode
+ case unexpectedRustCallError
+ case unexpectedStaleHandle
+ case rustPanic(_ message: String)
+
+ public var errorDescription: String? {
+ switch self {
+ case .bufferOverflow: return "Reading the requested value would read past the end of the buffer"
+ case .incompleteData: return "The buffer still has data after lifting its containing value"
+ case .unexpectedOptionalTag: return "Unexpected optional tag; should be 0 or 1"
+ case .unexpectedEnumCase: return "Raw enum value doesn't match any cases"
+ case .unexpectedNullPointer: return "Raw pointer value was null"
+ case .unexpectedRustCallStatusCode: return "Unexpected RustCallStatus code"
+ case .unexpectedRustCallError: return "CALL_ERROR but no errorClass specified"
+ case .unexpectedStaleHandle: return "The object in the handle map has been dropped already"
+ case let .rustPanic(message): return message
+ }
+ }
+}
+
+private extension NSLock {
+ func withLock(f: () throws -> T) rethrows -> T {
+ lock()
+ defer { self.unlock() }
+ return try f()
+ }
+}
+
+private let CALL_SUCCESS: Int8 = 0
+private let CALL_ERROR: Int8 = 1
+private let CALL_UNEXPECTED_ERROR: Int8 = 2
+private let CALL_CANCELLED: Int8 = 3
+
+private extension RustCallStatus {
+ init() {
+ self.init(
+ code: CALL_SUCCESS,
+ errorBuf: RustBuffer(
+ capacity: 0,
+ len: 0,
+ data: nil
+ )
+ )
+ }
+}
+
+private func rustCall(_ callback: (UnsafeMutablePointer) -> T) throws -> T {
+ let neverThrow: ((RustBuffer) throws -> Never)? = nil
+ return try makeRustCall(callback, errorHandler: neverThrow)
+}
+
+private func rustCallWithError(
+ _ errorHandler: @escaping (RustBuffer) throws -> E,
+ _ callback: (UnsafeMutablePointer) -> T
+) throws -> T {
+ try makeRustCall(callback, errorHandler: errorHandler)
+}
+
+private func makeRustCall(
+ _ callback: (UnsafeMutablePointer) -> T,
+ errorHandler: ((RustBuffer) throws -> E)?
+) throws -> T {
+ uniffiEnsureInitialized()
+ var callStatus = RustCallStatus()
+ let returnedVal = callback(&callStatus)
+ try uniffiCheckCallStatus(callStatus: callStatus, errorHandler: errorHandler)
+ return returnedVal
+}
+
+private func uniffiCheckCallStatus(
+ callStatus: RustCallStatus,
+ errorHandler: ((RustBuffer) throws -> E)?
+) throws {
+ switch callStatus.code {
+ case CALL_SUCCESS:
+ return
+
+ case CALL_ERROR:
+ if let errorHandler = errorHandler {
+ throw try errorHandler(callStatus.errorBuf)
+ } else {
+ callStatus.errorBuf.deallocate()
+ throw UniffiInternalError.unexpectedRustCallError
+ }
+
+ case CALL_UNEXPECTED_ERROR:
+ // When the rust code sees a panic, it tries to construct a RustBuffer
+ // with the message. But if that code panics, then it just sends back
+ // an empty buffer.
+ if callStatus.errorBuf.len > 0 {
+ throw try UniffiInternalError.rustPanic(FfiConverterString.lift(callStatus.errorBuf))
+ } else {
+ callStatus.errorBuf.deallocate()
+ throw UniffiInternalError.rustPanic("Rust panic")
+ }
+
+ case CALL_CANCELLED:
+ fatalError("Cancellation not supported yet")
+
+ default:
+ throw UniffiInternalError.unexpectedRustCallStatusCode
+ }
+}
+
+private func uniffiTraitInterfaceCall(
+ callStatus: UnsafeMutablePointer,
+ makeCall: () throws -> T,
+ writeReturn: (T) -> Void
+) {
+ do {
+ try writeReturn(makeCall())
+ } catch {
+ callStatus.pointee.code = CALL_UNEXPECTED_ERROR
+ callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error))
+ }
+}
+
+private func uniffiTraitInterfaceCallWithError(
+ callStatus: UnsafeMutablePointer,
+ makeCall: () throws -> T,
+ writeReturn: (T) -> Void,
+ lowerError: (E) -> RustBuffer
+) {
+ do {
+ try writeReturn(makeCall())
+ } catch let error as E {
+ callStatus.pointee.code = CALL_ERROR
+ callStatus.pointee.errorBuf = lowerError(error)
+ } catch {
+ callStatus.pointee.code = CALL_UNEXPECTED_ERROR
+ callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error))
+ }
+}
+
+private class UniffiHandleMap {
+ private var map: [UInt64: T] = [:]
+ private let lock = NSLock()
+ private var currentHandle: UInt64 = 1
+
+ func insert(obj: T) -> UInt64 {
+ lock.withLock {
+ let handle = currentHandle
+ currentHandle += 1
+ map[handle] = obj
+ return handle
+ }
+ }
+
+ func get(handle: UInt64) throws -> T {
+ try lock.withLock {
+ guard let obj = map[handle] else {
+ throw UniffiInternalError.unexpectedStaleHandle
+ }
+ return obj
+ }
+ }
+
+ @discardableResult
+ func remove(handle: UInt64) throws -> T {
+ try lock.withLock {
+ guard let obj = map.removeValue(forKey: handle) else {
+ throw UniffiInternalError.unexpectedStaleHandle
+ }
+ return obj
+ }
+ }
+
+ var count: Int {
+ map.count
+ }
+}
+
+// Public interface members begin here.
+
+#if swift(>=5.8)
+ @_documentation(visibility: private)
+#endif
+private struct FfiConverterUInt64: FfiConverterPrimitive {
+ typealias FfiType = UInt64
+ typealias SwiftType = UInt64
+
+ public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt64 {
+ return try lift(readInt(&buf))
+ }
+
+ public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
+ writeInt(&buf, lower(value))
+ }
+}
+
+#if swift(>=5.8)
+ @_documentation(visibility: private)
+#endif
+private struct FfiConverterString: FfiConverter {
+ typealias SwiftType = String
+ typealias FfiType = RustBuffer
+
+ public static func lift(_ value: RustBuffer) throws -> String {
+ defer {
+ value.deallocate()
+ }
+ if value.data == nil {
+ return String()
+ }
+ let bytes = UnsafeBufferPointer(start: value.data!, count: Int(value.len))
+ return String(bytes: bytes, encoding: String.Encoding.utf8)!
+ }
+
+ public static func lower(_ value: String) -> RustBuffer {
+ return value.utf8CString.withUnsafeBufferPointer { ptr in
+ // The swift string gives us int8_t, we want uint8_t.
+ ptr.withMemoryRebound(to: UInt8.self) { ptr in
+ // The swift string gives us a trailing null byte, we don't want it.
+ let buf = UnsafeBufferPointer(rebasing: ptr.prefix(upTo: ptr.count - 1))
+ return RustBuffer.from(buf)
+ }
+ }
+ }
+
+ public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> String {
+ let len: Int32 = try readInt(&buf)
+ return try String(bytes: readBytes(&buf, count: Int(len)), encoding: String.Encoding.utf8)!
+ }
+
+ public static func write(_ value: String, into buf: inout [UInt8]) {
+ let len = Int32(value.utf8.count)
+ writeInt(&buf, len)
+ writeBytes(&buf, value.utf8)
+ }
+}
+
+public func add(left: UInt64, right: UInt64) -> UInt64 {
+ return try! FfiConverterUInt64.lift(try! rustCall {
+ uniffi_ffi_fn_func_add(
+ FfiConverterUInt64.lower(left),
+ FfiConverterUInt64.lower(right), $0
+ )
+ })
+}
+
+public func greet(name: String) -> String {
+ return try! FfiConverterString.lift(try! rustCall {
+ uniffi_ffi_fn_func_greet(
+ FfiConverterString.lower(name), $0
+ )
+ })
+}
+
+private enum InitializationResult {
+ case ok
+ case contractVersionMismatch
+ case apiChecksumMismatch
+}
+
+// Use a global variable to perform the versioning checks. Swift ensures that
+// the code inside is only computed once.
+private let initializationResult: InitializationResult = {
+ // Get the bindings contract version from our ComponentInterface
+ let bindings_contract_version = 26
+ // Get the scaffolding contract version by calling the into the dylib
+ let scaffolding_contract_version = ffi_ffi_uniffi_contract_version()
+ if bindings_contract_version != scaffolding_contract_version {
+ return InitializationResult.contractVersionMismatch
+ }
+ if uniffi_ffi_checksum_func_add() != 13861 {
+ return InitializationResult.apiChecksumMismatch
+ }
+ if uniffi_ffi_checksum_func_greet() != 9569 {
+ return InitializationResult.apiChecksumMismatch
+ }
+
+ return InitializationResult.ok
+}()
+
+private func uniffiEnsureInitialized() {
+ switch initializationResult {
+ case .ok:
+ break
+ case .contractVersionMismatch:
+ fatalError("UniFFI contract version mismatch: try cleaning and rebuilding your project")
+ case .apiChecksumMismatch:
+ fatalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project")
+ }
+}
+
+// swiftlint:enable all
diff --git a/platforms/swift/ZKsyncSSO/Tests/ZKsyncSSOTests/ZKsyncSSOTests.swift b/platforms/swift/ZKsyncSSO/Tests/ZKsyncSSOTests/ZKsyncSSOTests.swift
new file mode 100644
index 0000000..00c1413
--- /dev/null
+++ b/platforms/swift/ZKsyncSSO/Tests/ZKsyncSSOTests/ZKsyncSSOTests.swift
@@ -0,0 +1,10 @@
+import Testing
+@testable import ZKsyncSSO
+
+@Test func testGreetRust() async throws {
+ #expect(greetRust(name: "Rust") == "Hello, Rust")
+}
+
+@Test func testAddRust() async throws {
+ #expect(addRust(left: 2, right: 2) == 4)
+}