Step-by-step guide for integrating the Para Swift SDK into your iOS application
The Para Swift SDK enables you to integrate secure wallet features including creation, passkey-based authentication, and transaction signing into your iOS applications. This guide covers all necessary steps from installation to implementing authentication flows.
Provide your Team ID + Bundle ID to Para, e.g. A1B2C3D4E5.com.example.yourapp
Without properly registering your domain with Para, passkey authentication flows will fail. Contact Para support if you encounter issues with passkey registration.
Beta Testing Credentials In the BETA Environment, you can use any email ending in @test.getpara.com (like
dev@test.getpara.com) or US phone numbers (+1) in the format (area code)-555-xxxx (like (425)-555-1234). Any OTP
code will work for verification with these test credentials. These credentials are for beta testing only. You can
delete test users anytime in the beta developer console to free up user slots.
Para uses a streamlined authentication flow centered around the AuthState object. The SDK automatically determines whether a user is new or existing and guides you through the appropriate flow.
Email authentication verifies users via a one-time password (OTP) sent to their email address and then sets up a biometric-enabled passkey for future logins.
1
Initiate Authentication Flow
Start the authentication process with an email:
Copy
Ask AI
let authState = try await paraManager.initiateAuthFlow(auth: .email(userEmail))
This returns an AuthState object indicating the next step based on whether the user exists.
2
Handle the Authentication State
Process the returned AuthState based on its stage:
Copy
Ask AI
switch authState.stage {case .verify: // New user - needs email verification // Show verification code input UI breakcase .login: // Existing user - proceed with login try await paraManager.handleLogin( authState: authState, authorizationController: authorizationController, webAuthenticationSession: webAuthenticationSession ) // User is now logged in breakcase .signup: // Shouldn't happen directly from initiateAuthFlow break}
3
For New Users: Handle Verification
If the user is new (.verify stage), handle the verification code:
Copy
Ask AI
// User enters verification code from their emaillet verificationCode = "123456" // Replace with actual code from UI input// Submit the verification codelet verifiedState = try await paraManager.handleVerificationCode( verificationCode: verificationCode)// verifiedState.stage should now be .signup
4
Complete Signup
After verification, complete the signup process:
Copy
Ask AI
// Check available signup methodslet passkeyAvailable = paraManager.isSignupMethodAvailable( method: .passkey, authState: verifiedState)// Choose signup method (passkey preferred)let method: ParaManager.SignupMethod = passkeyAvailable ? .passkey : .password// Complete signup with chosen methodtry await paraManager.handleSignup( authState: verifiedState, method: method, authorizationController: authorizationController, webAuthenticationSession: webAuthenticationSession)// User is now signed up and logged in with a wallet created
Email authentication verifies users via a one-time password (OTP) sent to their email address and then sets up a biometric-enabled passkey for future logins.
1
Initiate Authentication Flow
Start the authentication process with an email:
Copy
Ask AI
let authState = try await paraManager.initiateAuthFlow(auth: .email(userEmail))
This returns an AuthState object indicating the next step based on whether the user exists.
2
Handle the Authentication State
Process the returned AuthState based on its stage:
Copy
Ask AI
switch authState.stage {case .verify: // New user - needs email verification // Show verification code input UI breakcase .login: // Existing user - proceed with login try await paraManager.handleLogin( authState: authState, authorizationController: authorizationController, webAuthenticationSession: webAuthenticationSession ) // User is now logged in breakcase .signup: // Shouldn't happen directly from initiateAuthFlow break}
3
For New Users: Handle Verification
If the user is new (.verify stage), handle the verification code:
Copy
Ask AI
// User enters verification code from their emaillet verificationCode = "123456" // Replace with actual code from UI input// Submit the verification codelet verifiedState = try await paraManager.handleVerificationCode( verificationCode: verificationCode)// verifiedState.stage should now be .signup
4
Complete Signup
After verification, complete the signup process:
Copy
Ask AI
// Check available signup methodslet passkeyAvailable = paraManager.isSignupMethodAvailable( method: .passkey, authState: verifiedState)// Choose signup method (passkey preferred)let method: ParaManager.SignupMethod = passkeyAvailable ? .passkey : .password// Complete signup with chosen methodtry await paraManager.handleSignup( authState: verifiedState, method: method, authorizationController: authorizationController, webAuthenticationSession: webAuthenticationSession)// User is now signed up and logged in with a wallet created
Phone authentication verifies users via SMS OTP and sets up a biometric-enabled passkey for future logins.
1
Initiate Authentication Flow
Start the authentication process with a phone number (including country code):
Copy
Ask AI
let phoneNumber = "+15551234567" // Full phone number with country codelet authState = try await paraManager.initiateAuthFlow(auth: .phone(phoneNumber))
This returns an AuthState object indicating the next step.
2
Handle the Authentication State
Process the returned AuthState based on its stage:
Copy
Ask AI
switch authState.stage {case .verify: // New user - needs SMS verification // Show verification code input UI breakcase .login: // Existing user - proceed with login try await paraManager.handleLogin( authState: authState, authorizationController: authorizationController, webAuthenticationSession: webAuthenticationSession ) // User is now logged in breakcase .signup: // Shouldn't happen directly from initiateAuthFlow break}
3
For New Users: Handle Verification
If the user is new (.verify stage), handle the verification code:
Copy
Ask AI
// User enters verification code from SMSlet verificationCode = "123456" // Replace with actual code from UI input// Submit the verification codelet verifiedState = try await paraManager.handleVerificationCode( verificationCode: verificationCode)// verifiedState.stage should now be .signup
4
Complete Signup
After verification, complete the signup process:
Copy
Ask AI
// Check available signup methodslet passkeyAvailable = paraManager.isSignupMethodAvailable( method: .passkey, authState: verifiedState)// Choose signup method (passkey preferred)let method: ParaManager.SignupMethod = passkeyAvailable ? .passkey : .password// Complete signup with chosen methodtry await paraManager.handleSignup( authState: verifiedState, method: method, authorizationController: authorizationController, webAuthenticationSession: webAuthenticationSession)// User is now signed up and logged in with a wallet created
After initial setup, users can log in using their email or phone with the same authentication flow:
Copy
Ask AI
// Login with emaillet authState = try await paraManager.initiateAuthFlow(auth: .email(userEmail))// Since the user exists, authState.stage will be .loginif authState.stage == .login { try await paraManager.handleLogin( authState: authState, authorizationController: authorizationController, webAuthenticationSession: webAuthenticationSession ) // User is now logged in}
Alternatively, you can use direct passkey login if you know the user has set up passkeys:
Copy
Ask AI
// Direct passkey login (will show all available passkeys if email/phone not provided)try await paraManager.loginWithPasskey( authorizationController: authorizationController, email: userEmail, // Optional - helps filter passkeys phone: nil)
This will prompt the user for Face ID or Touch ID verification before granting access to their wallets.
let isLoggedIn = await paraManager.isFullyLoggedIn()if isLoggedIn { // User is authenticated, proceed to main app flow} else { // Show login/signup UI}