PortalAuth

Drives Portal's Client Auth APIs and resolves a PortalSession the host app passes to Portal.

PortalAuth and Portal share no object graph: this class never touches wallet, MPC or signing code, and nothing here constructs a Portal. The host app owns when authentication starts, all UI, deep-link registration and forwarding, and wallet creation.

A login survives the app being backgrounded or killed mid-flow: nothing about it is held between the redirect being sent and it coming back.

Hold one long-lived instance — on Application, or as a DI singleton. handleRedirect remembers the grant it last exchanged so a re-delivered redirect replays instead of failing, and that memory lives on the instance: one built per Activity is destroyed by the very configuration change the memory exists to survive.

val auth = PortalAuth(
authEnvironmentId = "fc00aa96-…",
redirectUrl = "portalexample://auth/callback",
magicLink = MagicLinkConfig(fromEmail = "login@example.com", templateId = "…"),
)

auth.sendMagicLink("user@example.com")

// later, in the host app's own deep-link handler:
when (val result = auth.handleRedirect(incomingUrl)) {
is AuthResult.Authenticated -> Portal(credentials = result.session, …)
// Hold `result.userJwt`, collect a code, then:
// val done = auth.verifyTotp(code, result.userJwt)
is AuthResult.TotpRequired -> showTotpPrompt(result)
null -> Unit // not ours — let another handler try
}

Constructors

Link copied to clipboard
constructor(authEnvironmentId: String, redirectUrl: String, apiHost: String = PortalAuthApi.DEFAULT_API_HOST, magicLink: MagicLinkConfig? = null, isAccountAbstracted: Boolean? = null)

Functions

Link copied to clipboard
suspend fun clearPersistedSession()

Removes the locally persisted token.

Link copied to clipboard

The auth methods enabled for this environment, plus whether it expects a wallet. Idempotent and side-effect free, so it is safe to retry.

Link copied to clipboard
suspend fun handleRedirect(url: String): AuthResult?

The single completion path for every flow.

Link copied to clipboard

The Apple authorize URL to open in a browser. See loginWithGoogle for how to open it and why the result must not be cached — the two are the same flow with a different provider key.

Link copied to clipboard

The Google authorize URL to open in a browser.

Link copied to clipboard

Rebuilds a session from the locally persisted token, or null if storage holds nothing usable.

Link copied to clipboard
suspend fun sendMagicLink(email: String)

Sends a magic-link email.

Link copied to clipboard
suspend fun verifyTotp(code: String, userJwt: String): AuthResult.Authenticated

Submits a TOTP code for a login that returned AuthResult.TotpRequired.