Skip to main content

Overview

The Dynamic Swift SDK provides a comprehensive API for building Web3-enabled iOS applications. This reference documents all the modules, functions, and types available in the SDK.

Requirements

  • iOS 15.0+
  • Xcode 14.0+
  • Swift 5.9+

Installation

// Package.swift
dependencies: [
    .package(url: "https://github.com/dynamic-labs/swift-sdk-and-sample-app.git", from: "1.0.2")
]

SDK Architecture

The SDK uses a singleton pattern with modular access to different functionalities:
import DynamicSDKSwift

// Initialize at app launch
_ = DynamicSDK.initialize(props: ClientProps(...))

// Access SDK instance
let sdk = DynamicSDK.instance()

// Access modules
sdk.auth       // Authentication
sdk.wallets    // Wallet management
sdk.evm        // EVM chain operations
sdk.solana     // Solana operations
sdk.networks   // Available networks
sdk.mfa        // Multi-factor authentication
sdk.passkeys   // Passkey management
sdk.ui         // Built-in UI components

Core Modules

Initialization

// Initialize SDK (call once at app launch)
DynamicSDK.initialize(
    props: ClientProps(
        environmentId: "YOUR_ENV_ID",
        appLogoUrl: "https://example.com/logo.png",
        appName: "Your App",
        redirectUrl: "yourapp://",
        appOrigin: "https://example.com",
        logLevel: .debug,                           // Optional
        debug: ClientDebugProps(webview: true)      // Optional
    )
)

// Get SDK instance
let sdk = DynamicSDK.instance()

Authentication (sdk.auth)

// Current user
let user = sdk.auth.authenticatedUser

// Auth token
let token = sdk.auth.token

// Reactive publishers (Combine)
sdk.auth.authenticatedUserChanges  // Publisher<UserProfile?, Never>
sdk.auth.tokenChanges              // Publisher<String?, Never>

// Logout
try await sdk.auth.logout()

// Email OTP
try await sdk.auth.email.sendOTP(email: "user@example.com")
try await sdk.auth.email.verifyOTP(token: "123456")
try await sdk.auth.email.resendOTP()

// SMS OTP
let phoneData = PhoneData(dialCode: "+1", iso2: "US", phone: "5551234567")
try await sdk.auth.sms.sendOTP(phoneData: phoneData)
try await sdk.auth.sms.verifyOTP(token: "123456")
try await sdk.auth.sms.resendOTP()

// Social authentication
try await sdk.auth.social.connect(provider: .google)   // .apple, .farcaster

// Passkey authentication
try await sdk.auth.passkey.signIn()

// External JWT
try await sdk.auth.externalAuth.signInWithExternalJwt(
    props: SignInWithExternalJwtParams(jwt: "your-jwt")
)

Wallets (sdk.wallets)

// Current wallets
let wallets = sdk.wallets.userWallets  // [BaseWallet]

// Reactive publisher (Combine)
sdk.wallets.userWalletsChanges  // Publisher<[BaseWallet], Never>

// Get balance
let balance = try await sdk.wallets.getBalance(wallet: wallet)

// Get current network
let network = try await sdk.wallets.getNetwork(wallet: wallet)

// Switch network
try await sdk.wallets.switchNetwork(wallet: wallet, network: targetNetwork)

// Set primary wallet
try await sdk.wallets.setPrimary(walletId: walletId)

// Sign message
let signature = try await sdk.wallets.signMessage(wallet: wallet, message: "Hello")

// Sign typed data (EIP-712)
let signature = try await sdk.wallets.signTypedData(wallet: wallet, typedDataJson: jsonString)

EVM Operations (sdk.evm)

// Create public client for chain
let client = try await sdk.evm.createPublicClient(chainId: 1)

// Get gas price
let gasPrice = try await client.getGasPrice()

// Send transaction
let transaction = EthereumTransaction(
    to: "0x...",
    value: 1000000000000000,  // Wei
    gasLimit: 21000,
    maxFeePerGas: gasPrice,
    maxPriorityFeePerGas: gasPrice
)
let txHash = try await sdk.evm.sendTransaction(transaction: transaction, wallet: wallet)

// Sign transaction (without sending)
let signedTx = try await sdk.evm.signTransaction(transaction: transaction, wallet: wallet)

// Write to contract
let input = WriteContractInput(
    contractAddress: "0x...",
    functionName: "transfer",
    args: [recipient, amount],
    abi: Erc20.abi
)
let txHash = try await sdk.evm.writeContract(wallet: wallet, input: input)

Solana Operations (sdk.solana)

// Create connection
let connection = try await sdk.solana.createConnection()

// Get latest blockhash
let blockhash = try await connection.getLatestBlockhash()

// Create signer
let signer = try await sdk.solana.createSigner(wallet: wallet)

// Sign message
let signature = try await signer.signMessage(message: "Hello")

// Sign transaction
let signedTx = try await signer.signEncodedTransaction(base64Transaction: base64Tx)

// Sign and send transaction
let signature = try await signer.signAndSendEncodedTransaction(base64Transaction: base64Tx)

Networks (sdk.networks)

// Available EVM networks
let evmNetworks = sdk.networks.evm  // [GenericNetwork]

// Available Solana networks
let solanaNetworks = sdk.networks.solana  // [GenericNetwork]

// Network properties
network.name        // String
network.chainId     // For EVM
network.networkId   // For Solana

MFA (sdk.mfa)

// Get user devices
let devices = try await sdk.mfa.getUserDevices()

// Add TOTP device
let device = try await sdk.mfa.addDevice(type: .totp)

// Verify device
try await sdk.mfa.verifyDevice(code: "123456", type: .totp)

// Create MFA token
let token = try await sdk.mfa.createMfaToken(singleUse: true)

// Delete device
try await sdk.mfa.deleteUserDevice(deviceId: deviceId, mfaAuthToken: token)

// Recovery codes
let codes = try await sdk.mfa.getRecoveryCodes(generateNewCodes: false)
try await sdk.mfa.authenticateRecoveryCode(code: recoveryCode)

Passkeys (sdk.passkeys)

// Get user's passkeys
let passkeys = try await sdk.passkeys.getPasskeys()

// Register new passkey
try await sdk.passkeys.registerPasskey()

// Delete passkey
try await sdk.passkeys.deletePasskey(
    DeletePasskeyRequest(passkeyPublicKeyId: passkeyId)
)

Built-in UI (sdk.ui)

// Show authentication UI
sdk.ui.showAuth()

// Show user profile
sdk.ui.showUserProfile()

Data Types

ClientProps

ClientProps(
    environmentId: String,      // Required
    appLogoUrl: String,         // Required
    appName: String,            // Required
    redirectUrl: String,        // Required
    appOrigin: String,          // Required
    logLevel: LogLevel?,        // Optional: .debug, .info, .warn, .error
    debug: ClientDebugProps?    // Optional
)

BaseWallet

wallet.address      // String - Wallet address
wallet.chain        // String - "EVM" or "SOL"
wallet.walletName   // String? - Wallet name
wallet.id           // String? - Wallet ID for API operations

UserProfile

user.userId         // String
user.email          // String?
user.phoneNumber    // String?
// Additional properties available

PhoneData

PhoneData(
    dialCode: String,   // e.g., "+1"
    iso2: String,       // e.g., "US"
    phone: String       // Phone number without country code
)

EthereumTransaction

EthereumTransaction(
    to: String,                     // Recipient address
    value: Int,                     // Amount in Wei
    gasLimit: Int,                  // Gas limit
    maxFeePerGas: Int,              // Max fee per gas
    maxPriorityFeePerGas: Int,      // Priority fee
    data: String?                   // Optional contract data
)

WriteContractInput

WriteContractInput(
    contractAddress: String,
    functionName: String,
    args: [Any],
    abi: String
)

GenericNetwork

network.name            // String
network.chainId         // For EVM networks
network.networkId       // For Solana networks

Error Handling

All async functions can throw errors. Use Swift’s native error handling:
do {
    let result = try await sdk.auth.email.verifyOTP(token: code)
} catch {
    print("Error: \(error.localizedDescription)")
}

Quick Reference Example

import DynamicSDKSwift
import SwiftUI
import Combine

@main
struct MyApp: App {
    init() {
        _ = DynamicSDK.initialize(
            props: ClientProps(
                environmentId: "YOUR_ENV_ID",
                appLogoUrl: "https://example.com/logo.png",
                appName: "My App",
                redirectUrl: "myapp://",
                appOrigin: "https://example.com"
            )
        )
    }
    
    var body: some Scene {
        WindowGroup { ContentView() }
    }
}

struct ContentView: View {
    @State private var isAuthenticated = false
    @State private var cancellables = Set<AnyCancellable>()
    
    private let sdk = DynamicSDK.instance()
    
    var body: some View {
        Group {
            if isAuthenticated {
                HomeView()
            } else {
                LoginView()
            }
        }
        .onAppear {
            isAuthenticated = sdk.auth.authenticatedUser != nil
            
            sdk.auth.authenticatedUserChanges
                .receive(on: DispatchQueue.main)
                .sink { user in
                    isAuthenticated = user != nil
                }
                .store(in: &cancellables)
        }
    }
}

struct LoginView: View {
    var body: some View {
        Button("Sign In") {
            DynamicSDK.instance().ui.showAuth()
        }
    }
}

struct HomeView: View {
    private let sdk = DynamicSDK.instance()
    
    var body: some View {
        VStack {
            Text("Welcome!")
            
            Button("View Profile") {
                sdk.ui.showUserProfile()
            }
            
            Button("Logout") {
                Task {
                    try await sdk.auth.logout()
                }
            }
        }
    }
}
Complete Example App: For a fully functional iOS app demonstrating all SDK features, check out our Swift SDK Repository.