Authentication

Android Authentication

OAuth sign-in and session handling.

Sign-in providers (hosted URL)

Choose the provider at runtime with signIn(...) / signInWithCreate(...).

val authWithSheet = sdk.signIn()
val authGoogle = sdk.signIn(SDKSignInProvider.Google)
val authApple = sdk.signIn(SDKSignInProvider.Apple)

val authWithWallet = sdk.signInWithCreate()
val authGoogleWithWallet = sdk.signInWithCreate(SDKSignInProvider.Google)
val authAppleWithWallet = sdk.signInWithCreate(SDKSignInProvider.Apple)

Behavior:

  1. SDKSignInProvider.All — Shows the provider selection sheet.
  2. SDKSignInProvider.Google — Starts Google sign-in without the sheet.
  3. SDKSignInProvider.Apple — Starts Apple sign-in without the sheet.

OAuth callback handling (required)

After login, redirect the returned URL to the SDK so signIn / signInWithCreate can complete.

override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    val url = intent.dataString ?: return
    sdk.handleUrl(url)
}

Without wiring the callback, the sign-in coroutine may hang or fail.

Session lifecycle

initialize()

Attempts to restore a stored session when the app starts.

val restored = sdk.initialize() // AuthResult? (null if restore fails)

isLoggedIn()

Checks only whether a local access token exists and is not expired (no network refresh).

val loggedIn = sdk.isLoggedIn()

ensureLoggedIn()

Ensures the current session is usable (includes restore / refresh attempts).

val ok = sdk.ensureLoggedIn()

Sign-in and sign-out

val auth = sdk.signIn()
val authWithWallet = sdk.signInWithCreate()

val googleAuth = sdk.signIn(SDKSignInProvider.Google)
val appleAuth = sdk.signIn(SDKSignInProvider.Apple)

sdk.signOut()

val newAccessToken = sdk.refreshToken()

After sign-in

Use signIn() if you only need authentication; use signInWithCreate() if you need a wallet immediately.

When aligning the wallet via signInWithCreate() or later createWallet(), the SDK checks wallet state and branches:

  • exists — Reuses the existing wallet. If no wallet password is stored in the app, the SDK prompts once and saves it.
  • migration_required — Either runs migration depending on migrateAutomatically, or throws MigrationRequired.
  • not_found — Creates a new wallet and prompts for a password.
val auth = sdk.signIn()
val authWithWallet = sdk.signInWithCreate()

val ok = sdk.ensureLoggedIn()
if (!ok) return

val created = sdk.createWallet()
val createdManual = sdk.createWallet(migrateAutomatically = false)

val addresses = sdk.getAddresses()

To control when migration runs, use createWallet(migrateAutomatically = false) and handle CROSSxError.MigrationRequired.

If the user may not have a wallet right after login, use signIn() and createWallet() when needed. If a wallet must exist immediately after login, use signInWithCreate().

Minimal example

class MainActivity : ComponentActivity() {
    private val sdk by lazy {
        CROSSxSDK(
            application = application,
            config = SDKConfig(
                context = application,
                projectId = BuildConfig.CROSSX_PROJECT_ID,
                appName = getString(R.string.app_name),
                callbackScheme = BuildConfig.CROSSX_CALLBACK_SCHEME
            )
        )
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleScope.launch {
            sdk.initialize()
        }
    }

    fun onSignInClicked() {
        lifecycleScope.launch {
            sdk.signIn()
        }
    }

    fun onSignInWithCreateClicked() {
        lifecycleScope.launch {
            sdk.signInWithCreate()
        }
    }

    fun onGoogleSignInClicked() {
        lifecycleScope.launch {
            sdk.signIn(SDKSignInProvider.Google)
        }
    }

    fun onProtectedActionClicked() {
        lifecycleScope.launch {
            val ok = sdk.ensureLoggedIn()
            if (!ok) return@launch

            sdk.createWallet()
        }
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        intent.dataString?.let(sdk::handleUrl)
    }
}

Recommended order:

  1. App launch: initialize()
  2. Before protected features: ensureLoggedIn()
  3. User sign-in: signIn() / signInWithCreate() (optionally specify provider)
  4. User sign-out: signOut()
  5. Callback URLs: always handleUrl(...)

© 2025 NEXUS Co., Ltd. All Rights Reserved.