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=..."
);
#endifPlatform-specific OAuth adapters
| Platform | Adapter | Implementation |
|---|---|---|
| iOS | iOSNativeOAuthAdapter | ASWebAuthenticationSession |
| Android | AndroidNativeOAuthAdapter | Chrome Custom Tabs |
| Others | UnityOAuthAdapter | Application.OpenURL |
The adapter is selected automatically based on the build target.
Session lifecycle
InitializeAsync()
InitializeAsync()Try restoring stored session on app start:
var restored = await sdk.InitializeAsync(); // AuthResult? (null if no session)IsLoggedIn()
IsLoggedIn()Fast local check only (no refresh call):
bool loggedIn = sdk.IsLoggedIn();EnsureLoggedInAsync()
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 onmigrateAutomatically, or throwsCROSSxExceptionwithMigrationRequired.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 throwsSessionExpiredException
This flow is handled automatically within WithAutoRefreshAsync for all authenticated API calls.
Recommended app flow
- App launch: call
InitializeAsync() - Enable confirmation UI: call
EnableSignConfirmation(uiRoot) - Before protected action: call
EnsureLoggedInAsync() - User login action: call
SignInAsync() - User logout action: call
SignOutAsync()
Updated about 18 hours ago