Create and recover wallets in Unity
Understanding embedded wallets
To create wallets for your users during the login flow, you need to configure the private key generation. The configuration depends on your chosen recovery method, so it's important to decide on your recovery strategy first.
Make sure to wait for the embedded state ready before using the embedded wallet. Learn more about how to check the embedded state.Decide a recovery method
Recovering the embedded wallet is needed when a user logs into a new device.
Openfort embedded wallets have two core recovery modes: automatic recovery and password recovery. At a high-level, this setting modulates how the embedded wallet's recovery share is encrypted and stored.
- Automatic recovery: The recovery share is encrypted with a combination of project entropy and Openfort's entropy. When logging into a new device, users can immediately access their embedded wallet.
- Password recovery: The recovery share is encrypted by user-provided password. When logging into a new device, users must enter in their password to recover the embedded wallet on the new device. Once the private key has been recovered on a device, users will not need to enter their password on that devices again.
Methods
ConfigureEmbeddedWallet
Configure the embedded wallet with either automatic or password recovery.
Method Signature:public async UniTask ConfigureEmbeddedWallet(ConfigureEmbeddedWalletRequest request)
ConfigureEmbeddedWalletRequest request
- Wallet configuration request
UniTask
- Completes when wallet is configured
public class ConfigureEmbeddedWalletRequest
{
public RecoveryParams RecoveryParams { get; set; }
public int? ChainId { get; set; }
public ChainType? ChainType { get; set; }
public AccountType? AccountType { get; set; }
}
public abstract class RecoveryParams
{
public RecoveryMethod RecoveryMethod { get; set; }
}
public class AutomaticRecoveryParams : RecoveryParams
{
public string EncryptionSession { get; set; }
}
public class PasswordRecoveryParams : RecoveryParams
{
public string Password { get; set; }
}
Recovery Methods
Automatic Recovery
From your backend, you should have an endpoint that generates an encryption session for the user. This endpoint should be protected and only accessible by the user who is requesting the encryption session (i.e. the user who is logging in). Learn how to set up this endpoint and request an encryption session in our automatic recovery session guide.
Example:using System;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
using Cysharp.Threading.Tasks;
using Openfort.OpenfortSDK;
using Openfort.OpenfortSDK.Model;
using Newtonsoft.Json;
public class EmbeddedSignerManager : MonoBehaviour
{
private OpenfortSDK openfort;
private const string BACKEND_URL = "https://your-api-endpoint.com";
private string authToken; // Your auth token from login
private async void Start()
{
try
{
// Initialize Openfort SDK
openfort = await OpenfortSDK.Init(
"YOUR_OPENFORT_PUBLISHABLE_KEY",
"YOUR_SHIELD_PUBLISHABLE_KEY"
);
}
catch (Exception e)
{
Debug.LogError(quot;Failed to initialize Openfort: {e.Message}");
}
}
// Setup automatic recovery with Openfort authentication
public async UniTask SetupAutomaticRecoveryWithOpenfort(string email, string password)
{
try
{
// Step 1: Sign up the user
var authResponse = await openfort.SignUpWithEmailPassword(email, password);
authToken = authResponse.Token; // Store the auth token
Debug.Log(quot;User signed up: {authResponse.Player.Id}");
// Step 2: Get encryption session from your backend
string encryptionSession = await GetEncryptionSession();
// Step 3: Configure the embedded wallet with automatic recovery
int chainId = 80002; // Polygon Amoy testnet
var recoveryParams = new AutomaticRecoveryParams(encryptionSession);
var request = new ConfigureEmbeddedWalletRequest(
recoveryParams: recoveryParams,
chainId: chainId
);
await openfort.ConfigureEmbeddedWallet(request);
Debug.Log("Automatic recovery wallet configured successfully");
}
catch (OpenfortException e)
{
Debug.LogError(quot;Openfort error: {e.Message}, Type: {e.ErrorType}");
}
catch (Exception e)
{
Debug.LogError(quot;Error setting up automatic recovery: {e.Message}");
}
}
private async UniTask<string> GetEncryptionSession()
{
string url = quot;{BACKEND_URL}/api/protected-create-encryption-session";
using (UnityWebRequest webRequest = UnityWebRequest.Post(url, "{}"))
{
webRequest.SetRequestHeader("Content-Type", "application/json");
webRequest.SetRequestHeader("Authorization", quot;Bearer {authToken}");
await webRequest.SendWebRequest();
if (webRequest.result != UnityWebRequest.Result.Success)
{
throw new Exception(quot;Failed to create encryption session: {webRequest.error}");
}
string jsonResponse = webRequest.downloadHandler.text;
var response = JsonConvert.DeserializeObject<EncryptionSessionResponse>(jsonResponse);
return response.session;
}
}
}
// Response model for the encryption session
[Serializable]
public class EncryptionSessionResponse
{
public string session { get; set; }
}
Password recovery
Require that users set a password when the wallet is created, enforcing password-based recovery from the start.
using System;
using UnityEngine;
using Cysharp.Threading.Tasks;
using Openfort.OpenfortSDK;
using Openfort.OpenfortSDK.Model;
public class PasswordRecoveryManager : MonoBehaviour
{
private OpenfortSDK openfort;
private async void Start()
{
try
{
// Initialize SDK (Shield key optional for password recovery)
openfort = await OpenfortSDK.Init(
"YOUR_OPENFORT_PUBLISHABLE_KEY"
);
}
catch (Exception e)
{
Debug.LogError(quot;Failed to initialize Openfort: {e.Message}");
}
}
public async UniTask SetupPasswordRecovery(string email, string password, string recoveryPassword)
{
try
{
// Step 1: Sign up or log in the user
var authResponse = await openfort.SignUpWithEmailPassword(email, password);
Debug.Log(quot;User authenticated: {authResponse.Player.Id}");
// Step 2: Configure embedded wallet with password recovery
int chainId = 80002; // Polygon Amoy testnet
var recoveryParams = new PasswordRecoveryParams(recoveryPassword);
var request = new ConfigureEmbeddedWalletRequest(
recoveryParams: recoveryParams,
chainId: chainId
);
await openfort.ConfigureEmbeddedWallet(request);
Debug.Log("Password recovery wallet configured successfully");
// The user will need to enter this recovery password when
// accessing their wallet from a new device
}
catch (OpenfortException e)
{
Debug.LogError(quot;Openfort error: {e.Message}, Type: {e.ErrorType}");
}
catch (Exception e)
{
Debug.LogError(quot;Error setting up password recovery: {e.Message}");
}
}
// Method to recover wallet on a new device
public async UniTask RecoverWalletWithPassword(string email, string loginPassword, string recoveryPassword)
{
try
{
// Step 1: Log in the user
var authResponse = await openfort.LogInWithEmailPassword(email, loginPassword);
Debug.Log(quot;User logged in: {authResponse.Player.Id}");
// Step 2: Recover the wallet with the recovery password
var recoveryParams = new PasswordRecoveryParams(recoveryPassword);
var request = new ConfigureEmbeddedWalletRequest(
recoveryParams: recoveryParams,
chainId: 80002
);
await openfort.ConfigureEmbeddedWallet(request);
Debug.Log("Wallet recovered successfully with password");
}
catch (Exception e)
{
Debug.LogError(quot;Error recovering wallet: {e.Message}");
}
}
}
Wallet Pre-generation
Openfort also allows you to pregenerate embedded wallets for your users, even before they first login to your game. Please see our pregeneration guide for more.