Skip to main content
Function Signature
A PortalAuth method. Completes a sign-in that handleRedirect or signInWith* left at .totpRequired. On success the session is saved to the Keychain before it is returned. Parameters
  • code: The six-digit code from the user’s authenticator app. Posted exactly as given, with no trimming or length check, so validate the input before submitting.
  • userJwt: The userJwt from the TotpRequiredResult, passed back verbatim. Short-lived (ten minutes) and never persisted by the SDK.
Returns
  • AuthenticatedResult: Contains the following:
    • session: PortalSession, already persisted. Pass it to Portal(credentials:).
    • clientId: String?, the Portal Client this session belongs to.
    • isAccountAbstracted: Bool?, whether that client uses gas sponsorship.
Throws
  • PortalAuthError.invalidUserJwt(detail:): userJwt cannot be read (for example it is blank or carries no endUserId). Raised before the network call, so a bad JWT never costs the user a live code. Restart the sign-in.
  • PortalRequestsError.unauthorized: The code was wrong, or the userJwt has expired or already been used. The SDK cannot tell which. A wrong code does not consume the JWT, so let the user try again with the same TotpRequiredResult; if that keeps failing, start a new sign-in.
  • PortalAuthError.malformedResponse(path:missing:): The response carried no clientSessionToken.
  • PortalAuthError.sessionStorageFailure(message:): The code was accepted but the session could not be saved to the Keychain. Call verifyTotp again with the same userJwt: the SDK finishes the write and returns the session without a network call.
  • Other transport errors unchanged.
Enrollment helpers On a user’s first sign-in, TotpRequiredResult.totpLink carries an otpauth:// URI the user needs to enroll an authenticator app. The SDK provides:
totpSecret is nil, and qrCodeImage throws PortalAuthError.totpQrUnavailable, when totpLink is missing, is not an otpauth:// URI, or carries no valid secret. totpLink is nil for a user who is already enrolled. Notes
  • Nothing is persisted until verifyTotp succeeds. If the JWT expires or the app is killed first, the user signs in again from the beginning.
  • The endUserId of the resulting session is read from the userJwt; the TOTP endpoint does not return it.
  • After success, a redirect re-delivered for the same grant replays as this .authenticated result rather than the TOTP step.
  • Never log or persist userJwt, totpLink or totpSecret; totpLink embeds the TOTP secret. TotpRequiredResult redacts both from description and dump, so printing the value itself is safe. If you offer a “Copy key” button, use UIPasteboard.general.setItems(_:options:) with .localOnly: true and a short .expirationDate.
  • A user who loses their authenticator can be reset from the dashboard; see End users.
  • Available starting from SDK version 8.0.0.
Example Usage
Related Documentation