Authentication

Unity Authentication

This page explains OAuth sign-in and session handling for the Unity SDK.

Login provider

Choose provider with SDKConfig.LoginProvider:

var config = new SDKConfig
{
    ProjectId = "YOUR_PROJECT_ID",
    LoginProvider = SDKLoginProvider.Google // or Apple, or All (default)
    // ...
};

OAuth callback handling

After browser login, the callback URL is received via deep link (crossx-{ProjectId}://oauth-callback?...).

The SDK handles this internally through UnityDeepLinkAdapter, which subscribes to Application.deepLinkActivated. No manual forwarding is required in user code.

Editor testing

In the Unity Editor, deep links are not available. Use SimulateDeepLink for testing:

#if UNITY_EDITOR
EmbeddedWalletAuth.Instance.SimulateDeepLink(
    "crossx-YOUR_PROJECT_ID://oauth-callback?status=success&data=..."
);
#endif

Platform-specific OAuth adapters

PlatformAdapterImplementation
iOSiOSNativeOAuthAdapterASWebAuthenticationSession
AndroidAndroidNativeOAuthAdapterChrome Custom Tabs
OthersUnityOAuthAdapterApplication.OpenURL

The adapter is selected automatically based on the build target.

Session lifecycle

InitializeAsync()

Try restoring stored session on app start:

var restored = await sdk.InitializeAsync(); // AuthResult? (null if no session)

IsLoggedIn()

Fast local check only (no refresh call):

bool loggedIn = sdk.IsLoggedIn();

EnsureLoggedInAsync()

Ensures a usable session now (includes restore/refresh attempt):

bool ok = await sdk.EnsureLoggedInAsync();

Sign-in / Sign-out

// Open OAuth (platform-native browser)
var auth = await sdk.SignInAsync(SDKLoginProvider.Google);
// or let the user choose:
var auth = await sdk.SignInAsync();

// Sign in + wallet creation in one call
var authWithWallet = await sdk.SignInWithCreateAsync();

// Re-authenticate (e.g. after session expiry, reuses stored provider)
var reAuth = await sdk.SignInAgainAsync();

// Clear local session
await sdk.SignOutAsync();

After sign-in

Use SignInAsync() if you only need authentication; use SignInWithCreateAsync() if you need a wallet immediately.

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

  • exists — Reuses the existing wallet. If no wallet password is stored, the SDK shows the PIN input modal once and saves it.
  • migration_required — Either runs migration depending on migrateAutomatically, or throws CROSSxException with MigrationRequired.
  • not_found — Creates a new wallet and prompts for a password via internal PIN modal.
var auth = await sdk.SignInAsync();
var authWithWallet = await sdk.SignInWithCreateAsync();

var ok = await sdk.EnsureLoggedInAsync();
if (!ok) return;

var created = await sdk.CreateWalletAsync();
var createdManual = await sdk.CreateWalletAsync(migrateAutomatically: false);

var addresses = await sdk.GetAddressesAsync();

To control when migration runs, use CreateWalletAsync(migrateAutomatically: false) and handle CROSSxException with CROSSxErrorType.MigrationRequired.

If the user may not have a wallet right after login, use SignInAsync() and CreateWalletAsync() when needed. If a wallet must exist immediately after login, use SignInWithCreateAsync().

Session expiry handling

When access and refresh tokens both expire, the SDK shows a session expired modal with two options:

  • Sign in again — calls SignInAgainAsync() to re-authenticate
  • Sign out — calls SignOutAsync() and throws SessionExpiredException

This flow is handled automatically within WithAutoRefreshAsync for all authenticated API calls.

Recommended app flow

  1. App launch: call InitializeAsync()
  2. Enable confirmation UI: call EnableSignConfirmation(uiRoot)
  3. Before protected action: call EnsureLoggedInAsync()
  4. User login action: call SignInAsync()
  5. User logout action: call SignOutAsync()

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