Skip to main content

Wallet SDK (iOS)

Overview

The Wallet SDK for iOS enables secure identity verification and transaction authorization during checkout. It is optimized for native Swift apps and leverages multi-factor authentication (MFA) with passkeys.

This SDK allows your wallet app to:

  • Initiate an MFA session tied to a transaction.
  • Guide users through passkey authentication, passkey creation, or fallback login.
  • Streamline checkout flows directly within a native iOS experience.

Use this SDK when building wallet apps that require frictionless and secure checkout with passkeys.

Requirements

  • iOS 16+
  • XCode 16+
  • Swift 6+

Prerequisites

  • Create an application to obtain a base URL. The SDK uses this base URL to interact with the LoginID authentication service.
  • Create an API key with at least the external:verify scope. You’ll need this to request authorization tokens from your backend.

Configure apple-app-site-association File

In order for passkeys to work with your iOS application, you need to link your application with a website. You do this by creating an apple-app-site-association and hosting it on your domain website. More info here.

You Need an Apple Developer Account

An Apple Developer Account is a requirement as the Associated Domains capability is not available for free. Currently, an Apple Developer Account can be obtained from https://developer.apple.com/support/enrollment.

Obtain Team ID and Bundler ID

  • The team ID can be obtained on your developer account console at https://developer.apple.com/account.
  • The bundler ID can be obtained on your Signing & Capabilities section of your application.

Host apple-app-site-association JSON File on Your Website Directory

To host an apple-app-site-association file, you need to serve it as a static JSON file on your website. Note that the file must be named exactly apple-app-site-association without the .json extension and your server must be configured to serve it as JSON. The file should be located at <WEBSITE_DOMAIN>/.well-known/apple-app-site-association in the root directory of your website.

Here is an example of the minimum required fields in the file:

{
"webcredentials": {
"apps": ["<TEAM_ID>.<BUNDLER_ID>"]
}
}

Use the following example as a template and replace TEAM_ID and BUNDLER_ID with your values.

More information here.

Create an Associated Domains Capability on Your iOS App

To enable this capability

  1. You must have an Apple Developer Account
  2. Go to the Signing & Capabilities section of your application
  3. Add a capability by clicking the + Capability button
  4. Choose Associated Domains
  5. Enter the domain of your hosted website. Make sure to prefix it with webcredentials. Here's an example of what it should look like:
webcredentials:example.com

Setup SDK

Using the Swift Package Manager

  1. In Xcode, open your project.
  2. Go to File → Add Package Dependencies….
  3. In the search bar, paste:
https://github.com/loginid1/loginid-ios
  1. Select the target(s) where you want to add the SDK and click Add Package.

Import the class within your view models:

import LoginIDCheckoutMFA

@main
struct MyApp: App {
private let lid: LoginIDCheckoutMFA

init() {
let baseUrl = "<LOGINID_BASE_URL>"
LoginIDCheckoutMFA(baseUrl: baseUrl)

// Other setup code...
}
}
info

You can view the source code here.

Class LoginIDCheckoutMFA

A specialized authentication helper built on top of LoginID's MFA flow, designed for checkout scenarios where you need both authentication and identity trust. This helps orchestrate the MFA flow tied to a transaction (e.g., confirming a purchase) using passkeys.

constructor

Initializes a new instance of the LoginIDCheckoutMFA.

final public class LoginIDCheckoutMFA: Sendable

init(baseUrl: String)

Creates a new wallet authentication helper using a base URL. Use this initializer when you only have the environment base URL and want sensible defaults for the underlying SDK configuration.

ParameterTypeRequiredDescription
baseUrlStringYesThe LoginID environment base URL (e.g., from your environment configuration).

LoginIDCheckoutMFA

init(config: LoginIDConfig)

Creates a new wallet authentication helper with an explicit LoginIDConfig. Use this when you already have a fully-formed LoginIDConfig and want more control.

ParameterTypeRequiredDescription
configLoginIDConfigYesThe complete configuration used to initialize the underlying LoginID SDK.
config.baseUrlStringYesThe base URL of the LoginID service.

This value is used to resolve the App ID and make API calls.
config.useTrustIdBoolNoIf true, uses TrustID, a Crypto–derived device identifier, as a device possession factor. Defaults to false.
config.disableAnalyticsBoolNoIf true, disables sending analytics/events to LoginID. Defaults to false.

LoginIDCheckoutMFA

beginFlow

beginFlow(txPayload: String, username: String, options: BeginFlowOptions?)

Begins the MFA authentication flow for a checkout session. This starts an MFA session bound to a specific transaction payload and optional identifiers such as merchant checkoutId.

beginFlow(txPayload: String, username: String, options: BeginFlowOptions?)

ParameterTypeRequiredDescription
txPayloadStringYesThe transaction payload to be confirmed/authorized.
usernameStringNoThe username of the user initiating MFA. Defaults to an empty string.
optionsBeginFlowOptions?NoOptional parameters for beginning the flow. If options.txPayload is provided, it takes precedence over the txPayload parameter.
options.displayNameString?NoA human-palatable name for the user account, intended only for display on your passkeys and modals.
options.usernameTypeUsernameTypeNoThe type of username validation to be used.

Defaults to .other and is omitted from the payload when .other.
options.txPayloadString?NoA string representing transaction details for confirmation during MFA.

This can be plain text or a JSON-formatted string for structured details.
options.merchantTrustIdString?NoMerchant-generated identifier for the current checkout session.

Used as a key to retrieve associated trust information and link the session with wallet-issued identity data.
options.traceIdString?NoA unique identifier used to trace and correlate all events associated with a single MFA interaction.

If you don’t provide this, the server may generate one automatically.
options.deviceIdString?NoAn identifier for the device used in the authentication process. This property helps determine if supported authentications can be proceeded, allowing future authentications to identify the device correctly.

Overrides the stored device identifier. If not provided, the SDK uses the stored value.

struct MFASessionResult {
let flow: MfaNext.Flow?
let username: String?
let isComplete: Bool
let session: String?
let idToken: String?
let accessToken: String?
let refreshToken: String?
let payloadSignature: String?
let merchantTrustId: String?
let walletTrustId: String?
let passkeyInfo: PasskeyInfo?
let nextAction: ActionName?
}

performAction

performAction(action: ActionName, options: PerformActionOptions?)

Performs an MFA action using the provided factor and optional payload. In a checkout context, this method commonly covers:

  • Passkey Registration (.passkeyReg): Register a new passkey (e.g., WebAuthn) during account creation.
  • Passkey Authentication (.passkeyAuth): signin into a wallet account using a passkey.
  • Passkey Transaction Confirmation (.passkeyTx): Confirm a specific transaction using a passkey.
  • External Authentication (.external): Signin with a third-party authentication (e.g. bank login).
performAction(action: ActionName, options: PerformActionOptions?)

ParameterTypeRequiredDescription
action.passkeyReg
.passkeyAuth
.passkeyTx
.otpEmail
.otpSms
.otpVerify
.external
YesThe MFA factor/action to execute.
optionsPerformActionOptions?YesAction options such as:
options.sessionString?NoThe MFA state session.

This should be obtained from a previous MFA request or initiation step.
options.payloadString?NoThe payload required for completing the authentication factor.

This typically contains user input or challenge-response data.
options.autoFillBool?NoEnables passkey support in browser autofill suggestions (conditional UI), if supported.
options.displayNameString?NoA human-palatable name for the user account, intended only for display on your passkeys.
options.txPayloadString?NoAn updated transaction payload generated by the merchant to represent the purchase or operation being confirmed. This updates the initial txPayload used in the beginFlow method.

struct MFASessionResult {
let flow: MfaNext.Flow?
let username: String?
let isComplete: Bool
let session: String?
let idToken: String?
let accessToken: String?
let refreshToken: String?
let payloadSignature: String?
let merchantTrustId: String?
let walletTrustId: String?
let passkeyInfo: PasskeyInfo?
let nextAction: ActionName?
}

performAction(action: ActionName)

Performs an MFA action using the provided factor and optional payload. In a checkout context, this method commonly covers:

  • Passkey Registration (.passkeyReg): Register a new passkey (e.g., WebAuthn) during account creation.
  • Passkey Authentication (.passkeyAuth): signin into a wallet account using a passkey.
  • Passkey Transaction Confirmation (.passkeyTx): Confirm a specific transaction using a passkey.
  • External Authentication (.external): Signin with a third-party authentication (e.g. bank login).
performAction(action: ActionName)

ParameterTypeRequiredDescription
action.passkeyReg
.passkeyAuth
.passkeyTx
.otpEmail
.otpSms
.otpVerify
.external
YesThe MFA factor/action to execute.

struct MFASessionResult {
let flow: MfaNext.Flow?
let username: String?
let isComplete: Bool
let session: String?
let idToken: String?
let accessToken: String?
let refreshToken: String?
let payloadSignature: String?
let merchantTrustId: String?
let walletTrustId: String?
let passkeyInfo: PasskeyInfo?
let nextAction: ActionName?
}

Errors

LoginIDError

Can occur during the authentication process. It is designed to encapsulate detailed information about login-related errors, making it easier to handle and debug issues related to user authentication.

FieldTypeDetails
msgstringThe error code associated with the login error.
msgCodestringThe detailed message or description of the error.
messagestringThe detailed message or description of the error. (alias of msgCode)

Here is an example:


...
...

} catch let error as LoginIDError {
print("Failed with error: \(error.message)")
print("Failed with error code: \(error.msgCode)")
}