Skip to content

Releases: tkhq/swift-sdk

Release: v3.2.0

04 Dec 22:17
91a68f3

Choose a tag to compare

What's Changed

✨ New Functionality

  • add ClientSignature support for OTP authentication flows

Release: v3.1.0

13 Nov 13:17
3f96634

Choose a tag to compare

Release notes

Summary

  • Added config-driven Stamper initializers for API keys, passkeys, Secure Enclave, and Secure Storage; supports automatic on-device keypair creation and exposes publicKeyHex.
  • Introduced Stamper.sign(payload:format:) with .der (default) and .raw 64-byte outputs; passkey mode intentionally unsupported for generic sign.
  • Added delegated access/session conveniences to TurnkeyContext: raw/message/transaction signing via the active session, session helpers, and policy/user utility functions.
  • Introduced TurnkeyKeyManager module with EnclaveManager and SecureStorageManager for secure key lifecycle and signing.
  • Added tests for TurnkeyStamper and updated README/examples.

What changed

TurnkeyStamper

  • New public config models: ApiKeyStamperConfig, PasskeyStamperConfig, SecureEnclaveStamperConfig, SecureStorageStamperConfig, and StamperConfiguration.
  • New convenience initializers including on-device keypair creation and selection (.auto, .secureEnclave, .secureStorage).
  • New publicKeyHex surface; SignatureFormat .der | .raw; sign(payload:format:) returning hex.
  • Secure Storage stamping now passes stored config at stamp time to scope Keychain/auth prompts; DER conversion updated.

TurnkeyContext

  • Signing: signRawPayload(...), signMessage(...), signTransaction(...) using the selected session.
  • Session helpers: createKeyPair(), storeSession(...) with optional auto-refresh TTL, setActiveSession(...), refreshSession(...), getActiveSession(), and signWithSession(message:).
  • Delegated access utilities: fetchOrCreateP256ApiKeyUser(...), fetchOrCreatePolicies(...).
  • OTP result rename: VerifyOtpResult(verificationToken: String).

New module TurnkeyKeyManager

  • EnclaveManager: create/bind/list/delete P-256 keys in Secure Enclave; sign messages (DER output).
  • SecureStorageManager: create/import/list/delete keys in Keychain with configurable access control, prompts, reuse window, access group; retrieve private keys when permitted.

TurnkeyClient

  • Additional initializers to use on-device keys or passkeys, and combinations with Auth Proxy.

API compatibility

  • Additive for Stamper and TurnkeyClient initializers and sign(...).
  • OTP struct field rename to verificationToken; update call sites accordingly.

Full Changelog: v3.0.0...v3.1.0

Release: v3.0.0

05 Nov 22:11
d2bf98a

Choose a tag to compare

What's Changed

✨ New Functionality

Auth Proxy Integration

  • Added Auth Proxy support
    - Added loginWithPasskey(), signUpWithPasskey() for direct passkey authentication
    - Added initOtp(), verifyOtp(), loginWithOtp(), signUpWithOtp(), completeOtp() for email/SMS authentication
    - Added loginWithOAuth(), signUpWithOAuth(), completeOAuth() for OAuth flows
    - Added convenience handlers handleGoogleOAuth(), handleAppleOAuth(), handleDiscordOAuth(), handleXOauth() for specific OAuth providers

Secure Key Storage

  • TurnkeySwift session keys now stored in Secure Enclave by default (with Keychain fallback)
  • Added SecureEnclaveStamper for hardware-backed key storage (keys never leave Secure Enclave)
  • Added SecureStorageStamper for Keychain-backed key storage as fallback

State Management

  • Added @Published properties for session, user, and wallets that automatically update throughout the application lifecycle
  • State automatically refreshed after authentication and relevant operations
  • Observable in SwiftUI via @EnvironmentObject

Type System & Client

  • New TurnkeyTypes package with smarter, easier-to-use types generated from Turnkey API
  • Updated TurnkeyHttp client to use the new type system for improved type safety and developer experience

Release: v2.2.0

27 Jun 21:06
c108fe5

Choose a tag to compare

What's Changed

✨ New Functionality

  • Added authState to TurnkeyContext for synchronously tracking authentication state and determining the appropriate screen on app load.
  • Added refreshSession() to manually refresh the session. Defaults to the selected session but accepts an optional sessionKey.
  • Added updateUserEmail(email:verificationToken:) and updateUserPhoneNumber(phone:verificationToken:) for updating user contact details. These methods support optional verification tokens to mark the fields as verified, and allow deletion by passing an empty string.
  • Added support for automatically refreshing sessions before expiry when the app is active by passing the optional refreshedSessionTTLSeconds parameter to createSession(). This controls the duration of refreshed sessions and must be at least 30 seconds.

🛠 Fixes

  • Fixed a scheduling issue where expiry timers were not firing correctly while the app was active in the foreground.

Release: v2.1.1

16 Jun 19:15
7eea9fa

Choose a tag to compare

What's Changed

🐛 Bug Fixes

  • Fixed an issue where active sessions were being cleared due to stale pending keys not being removed after session creation.
  • Pending keys are now correctly removed once a session is established.

Release: v2.1.0

11 Jun 20:45
6555f78

Choose a tag to compare

What's Changed

✨ New Functionality

Added startGoogleOAuthFlow() to TurnkeySwift.

  • This method uses ASWebAuthenticationSession to launch Google OAuth in a system browser and return an OIDC token, simplifying OAuth integration.

Release: v2.0.0

02 Jun 13:33
26a96fc

Choose a tag to compare

What's Changed

⚠️ Breaking

The SDK has been fully refactored into modular packages:

  • TurnkeyCrypto
  • TurnkeyPasskeys
  • TurnkeyStamper
  • TurnkeyEncoding
  • TurnkeyHttp
  • TurnkeySwift

TurnkeyPasskeys

  • Now uses async/await instead of notification-based observers.
  • Simplified API for passkey creation and assertion workflows.

TurnkeyHttp

  • Provides low-level request construction using fully typed, OpenAPI-generated interfaces.
  • Fixed an issue where undocumented errors were thrown without context. Errors are now structured and consistently surfaced.

TurnkeySwift

Introduced as the high-level abstraction layer, providing:

  • Session management (JWT-backed)
  • Simplified workflows for stamping, wallet creation, and user flows

Release: v1.2.1

28 Nov 11:54
35a3f20

Choose a tag to compare

What's Changed

  • Fixed missing return in guard statement ( #9 )

Full Changelog: 1.2.0...1.2.1

Release: v1.2.0

27 Nov 23:41
fe5e60f

Choose a tag to compare

What's Changed

Challenge format ( #1 )

The backend expects the challenge in hex format, and SHA256Digest returns only the raw format.
Now the challenge is properly encoded/formated.

ProxyMiddleware ( #5 ) - ⚠️ Minor Breaking

The ProxyMiddleware header for the forwarded Turnkey API request has been renamed:

Old New
X-Forwarded-For X-Turnkey-Request-Url

Ensure your backend is updated to support the new header name if you are using the latest version.

New Contributors

Full Changelog: 1.1.0...1.2.0

Release: v1.1.0

13 Nov 00:22
bd8993b

Choose a tag to compare

Version: 1.1.0

What's Changed

Oauth

Support for OAuth endpoints has been added:

  • getOauthProviders()
  • createOauthProviders()
  • deleteOauthProviders()

Sessions

Support for Session endpoints has been added:

  • createReadOnlySession()
  • createReadWriteSession()

Non-breaking

  • emailAuth(): Added an optional invalidateExisting parameter to emailAuth for API key invalidation.
  • updateUser(): updateUser now supports updating the userPhoneNumber field.

⚠️ Breaking

  • createApiKeys():
  • createSubOrganization:
    • Now uses RootUserParamsV4, which introduces the following changes:
      • New required oauthProviders field: Must be provided as a list of OAuth provider parameters.
      • New optional userPhoneNumber field: Represents the user's phone number in E.164 format.
      • Updated apiKeys type: Now requires ApiKeyParamsV2 instead of ApiKeyParams.

Migration Guide: createSubOrganization()

let rootUsers: [Components.Schemas.RootUserParamsV4] = [
  .init(
    userName: "user1",
    userEmail: "[email protected]",
    apiKeys: [
      .init(
        apiKeyName: "turnkey-demo",
        publicKey: apiPublicKey!,
        curveType: .API_KEY_CURVE_P256 // New required field
      )
    ],
    authenticators: [],
    oauthProviders: [] // New required field
  )
]

let output = try await client.createSubOrganization(
  organizationId: organizationId!,
  subOrganizationName: subOrganizationName,
  rootUsers: rootUsers,
  rootQuorumThreshold: rootQuorumThreshold,
  wallet: wallet,
  disableEmailRecovery: disableEmailRecovery,
  disableEmailAuth: disableEmailAuth,
  disableSmsAuth: false, // New optional parameter
  disableOtpEmailAuth: false // New optional parameter
)

Full Changelog: 1.0.0...1.1.0