# Guest Mode

:::note
User data and embedded wallets from guest sessions cannot be merged into an existing user account — guest accounts can only be upgraded into a new user account. If a guest user wants to log in with an existing account, you must delete the guest user session first.
:::

## Methods

### SignUpGuest

Create a guest account without requiring email or password authentication.

**Method Signature:**

```csharp
public async UniTask<AuthResponse> SignUpGuest()
```

**Parameters:**

* None

**Returns:**

* `UniTask<AuthResponse>` - Authentication response with guest user info and session

**Example:**

```csharp
using System;
using UnityEngine;
using Cysharp.Threading.Tasks;
using Openfort.OpenfortSDK;
using Openfort.OpenfortSDK.Model;

public class GuestAuthManager : MonoBehaviour
{
    private OpenfortSDK openfort;

    private async void Start()
    {
        try
        {
            openfort = await OpenfortSDK.Init("YOUR_OPENFORT_PUBLISHABLE_KEY");
        }
        catch (Exception e)
        {
            Debug.LogError($"Failed to initialize Openfort: {e.Message}");
        }
    }

    public async UniTask<AuthResponse> SignUpAsGuest()
    {
        try
        {
            var response = await openfort.SignUpGuest();

            Debug.Log($"Guest account created: {response.User.Id}");
            Debug.Log($"Is Anonymous: {response.User.IsAnonymous}");

            return response;
        }
        catch (OpenfortException e)
        {
            Debug.LogError($"Guest signup failed: {e.Message}, Type: {e.Type}");
            throw;
        }
    }
}
```

### AddEmail

Add an email address to a guest account to upgrade it to a permanent account.

**Method Signature:**

```csharp
public async UniTask<User> AddEmail(AddEmailRequest request)
```

**Parameters:**

* `AddEmailRequest request` - Request containing email and callback URL

**Returns:**

* `UniTask<User>` - Updated user information with email added

**AddEmailRequest Structure:**

```csharp
public class AddEmailRequest
{
    public string email;       // Email address to add
    public string callbackURL; // URL for verification callback

    public AddEmailRequest(string email, string callbackURL = null)
    {
        this.email = email;
        this.callbackURL = callbackURL;
    }
}
```

**Example:**

```csharp
public async UniTask<User> UpgradeGuestWithEmail(string email, string callbackUrl)
{
    try
    {
        var request = new AddEmailRequest(email, callbackUrl);

        var user = await openfort.AddEmail(request);

        Debug.Log($"Email added to account: {user.Id}");
        Debug.Log($"Email: {user.Email}");
        Debug.Log($"Is Anonymous: {user.IsAnonymous}"); // Should now be false

        return user;
    }
    catch (Exception e)
    {
        Debug.LogError($"Failed to add email: {e.Message}");
        throw;
    }
}
```

## Complete example

Here's a complete example showing guest account creation and upgrade flow:

```csharp
using System;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Cysharp.Threading.Tasks;
using Openfort.OpenfortSDK;
using Openfort.OpenfortSDK.Model;

public class GuestAuthUI : MonoBehaviour
{
    [Header("UI References")]
    [SerializeField] private Button playAsGuestButton;
    [SerializeField] private Button upgradeAccountButton;
    [SerializeField] private TMP_InputField emailInput;
    [SerializeField] private TMP_Text statusText;
    [SerializeField] private GameObject upgradePanel;

    private OpenfortSDK openfort;
    private bool isGuest = false;

    private async void Start()
    {
        openfort = await OpenfortSDK.Init(
            "YOUR_OPENFORT_PUBLISHABLE_KEY",
            "YOUR_SHIELD_PUBLISHABLE_KEY"
        );

        playAsGuestButton.onClick.AddListener(() => PlayAsGuest().Forget());
        upgradeAccountButton.onClick.AddListener(() => UpgradeAccount().Forget());

        upgradePanel.SetActive(false);
    }

    private async UniTaskVoid PlayAsGuest()
    {
        statusText.text = "Creating guest account...";

        try
        {
            var response = await openfort.SignUpGuest();

            isGuest = response.User.IsAnonymous ?? true;
            statusText.text = $"Playing as guest: {response.User.Id.Substring(0, 8)}...";

            // Show upgrade option for guest users
            upgradePanel.SetActive(isGuest);

            // Continue to game
            Debug.Log("Guest account ready, starting game...");
        }
        catch (Exception e)
        {
            statusText.text = $"Failed: {e.Message}";
        }
    }

    private async UniTaskVoid UpgradeAccount()
    {
        if (!isGuest)
        {
            statusText.text = "Account is already permanent";
            return;
        }

        string email = emailInput.text;
        if (string.IsNullOrEmpty(email))
        {
            statusText.text = "Please enter an email address";
            return;
        }

        statusText.text = "Upgrading account...";

        try
        {
            var request = new AddEmailRequest(email, "https://your-game.com/verify");

            var user = await openfort.AddEmail(request);

            isGuest = user.IsAnonymous ?? false;
            statusText.text = $"Account upgraded! Check {email} for verification.";

            // Hide upgrade panel since account is now permanent
            upgradePanel.SetActive(false);
        }
        catch (Exception e)
        {
            statusText.text = $"Upgrade failed: {e.Message}";
        }
    }
}
```

## Best practices

1. **Save guest session**: Store tokens locally so guests can return to their session
2. **Prompt for upgrade**: Remind guest users to upgrade before important milestones
3. **Preserve progress**: Ensure game progress is linked to the user account
4. **Handle session expiry**: Check session validity and prompt re-authentication when needed
