Authentication
Core SDK — Authentication
This page explains OAuth sign-in and session handling for the JavaScript SDK.
Login provider
Choose a specific provider or let the user pick from a selector modal:
// Provider selector modal
const result = await sdk.signIn()
// Direct Google login
const result = await sdk.signIn({ provider: 'google' })
// Direct Apple login
const result = await sdk.signIn({ provider: 'apple' })Session lifecycle
initialize()
initialize()Try restoring a stored session on page load:
const restored = await sdk.initialize() // AuthResult | null
// Or specify which wallet to use on restore
const restored = await sdk.initialize({ preferredWalletIndex: 1 })isAuthenticated() / isLoggedIn()
isAuthenticated() / isLoggedIn()Fast local check only (no refresh call):
const loggedIn = sdk.isAuthenticated() // boolean
const loggedIn = sdk.isLoggedIn() // aliasensureLoggedIn()
ensureLoggedIn()Ensures a usable session now (includes restore/refresh attempt):
const ok = await sdk.ensureLoggedIn() // booleanIf the session is expired but a refresh token is valid, it is restored automatically. Returns false if login is required.
Sign-in / Sign-out
// Open OAuth (popup)
const auth = await sdk.signIn()
if (auth.success) {
console.log('Address:', auth.address)
console.log('User:', auth.user)
}
// Clear local session
await sdk.signOut()User info
const userInfo = await sdk.getUserInfo()
console.log(userInfo.id) // JWT sub
console.log(userInfo.email) // email (if available)
console.log(userInfo.loginType) // 'google' | 'apple'
console.log(userInfo.addresses) // wallet address arraySign in + wallet creation (one-step)
signInWithCreate() performs sign-in, wallet creation, and migration in a single call. It returns the full address list along with the AuthResult.
const result = await sdk.signInWithCreate()
if (result.success) {
console.log('Address:', result.address)
console.log('All addresses:', result.addresses)
// result.addresses → [{ address: '0x...', index: 0 }]
}If the user has no wallet yet, one is created automatically. If a CROSSx wallet backup is detected, migration is triggered internally.
Automatic wallet selection (2+ wallets)
When the user has two or more wallets, signInWithCreate() automatically displays the wallet selector modal after sign-in. The selected wallet is returned as result.address.
| Wallet count | Behavior |
|---|---|
| 0 | Creates a new wallet, no selector shown |
| 1 | Returns the wallet directly, no selector shown |
| 2+ | Shows selectWallet() modal → selected wallet becomes result.address |
If the user cancels the selector, the default wallet (index 0) is used.
const result = await sdk.signInWithCreate()
if (result.success) {
// result.address — the wallet selected by the user (or default if only one)
// result.addresses — full wallet list regardless of selection
console.log('Selected wallet:', result.address)
console.log('All wallets:', result.addresses.length)
}The SDK updates
currentAddressand emitsaddressChangedwhen a wallet is selected duringsignInWithCreate(). This differs from standaloneselectWallet(), which does not update SDK state.
JWT authentication
For apps with their own backend authentication, you can sign in using a pre-obtained JWT token:
// Sign in with JWT from your backend
const auth = await sdk.signInWithJWT(accessToken, refreshToken)
if (auth.success) {
console.log('Address:', auth.address)
}| Parameter | Type | Required | Description |
|---|---|---|---|
accessToken | string | Yes | JWT access token from your backend |
refreshToken | string? | No | Optional refresh token |
This is useful when you handle OAuth on the server side and pass the resulting JWT to the SDK.
Migration handling
When a CROSSx wallet backup is detected during sign-in, the SDK automatically triggers a migration flow:
const result = await sdk.signIn()
if (result.needsMigration) {
// Call createWallet() to trigger migration UI
await sdk.createWallet()
}
// Or use signInWithCreate() to handle this automatically
const result = await sdk.signInWithCreate()Event-driven auth state
The SDK emits events when auth state changes. This is useful for reactive frameworks:
const unsub = sdk.on('authChanged', (event) => {
console.log('Authenticated:', event.isAuthenticated)
console.log('Address:', event.address)
console.log('User ID:', event.userId)
})
// Cleanup
unsub()Recommended app flow
- Page load: call
initialize() - Before protected action: call
ensureLoggedIn() - User login action: call
signIn()orsignInWithCreate() - User logout action: call
signOut()
Updated 11 days ago