Management API Reference

Embedded wallets

Create and recover signers

Create and manage embedded wallets for your users

Understanding embedded signers#

To create wallets for your users during the login flow, you need to configure the embedded signer. 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 signer. Learn more about how to check the embedded state.

Decide a recovery method#

Recovering the embedded signer is needed when a user logs into a new device or when the embedded signer is lost.

Openfort embedded signers have two core recovery modes: automatic recovery and user-based recovery. At a high-level, this setting modulates how the embedded signer'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 signer.
Shield configuration

Before configuring the automatic recovery, generate your project's publishable and secret shield keys and store the encryption share. Learn about the differrent API keys here.

  • User-based recovery: The recovery share is encrypted by user-provided entropy. When logging into a new device, users must enter in their password to recover the embedded signer on the new device. Once the embedded signer has been recovered on a device, users will not need to enter their password on that devices again.

Automatic recovery#

It is worth noting that while automatic recovery makes for smooth user UX (without needing to set up a recovery system upfront when logging in), it comes with tradeoffs. Notably, the root of trust with is in the user’s authentication token. This means access to the auth token grants access to the wallet. Accordingly, this token must be properly secured at all times.

When using automatic recovery, Shield generates a password that is used for the encryption of the recovery share. The full encryption key can only be accessed if the decryption request includes the user's auth token.

Encryption share

When using automatic recovery, its very important to ensure that the encryption share should not be available from the client side of the application.

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).

An encryption session is requested every time configureEmbeddedSigner is called. The encryption session is only valid for a single use.

For example, in a Next.js API route, you can create an endpoint like this:

protected-create-encryption-session.ts
openfortAdminConfig.ts

_11
import openfort from './openfortAdminConfig';
_11
_11
export default async function handler(
_11
req: NextApiRequest,
_11
res: NextApiResponse
_11
) {
_11
const session = await openfort.registerRecoverySession('YOUR_SHIELD_PUBLISHABLE_KEY', 'YOUR_SHIELD_SECRET_KEY', 'YOUR_SHIELD_ENCRYPTION_SHARE')
_11
res.status(200).send({
_11
session: session,
_11
});
_11
}

Once we've secured the backend we setup the client side:

openfortManager.cs
encryptionSession.cs

_45
using System;
_45
using System.Threading.Tasks;
_45
using UnityEngine;
_45
using UnityEngine.Networking;
_45
using Openfort.OpenfortSDK;
_45
using Openfort.OpenfortSDK.Model;
_45
using static Clients.Shield;
_45
_45
public class EmbeddedSignerManager : MonoBehaviour
_45
{
_45
private OpenfortSDK openfort;
_45
_45
// Setup with Openfort authentication
_45
public async Task SetupAutomaticRecoveryWithOpenfort(string email, string password)
_45
{
_45
try
_45
{
_45
// Sign up the user
_45
AuthResponse response = await openfort.SignUpWithEmailPassword(email, password);
_45
string token = response.Token;
_45
_45
// Get encryption session from your backend
_45
string encryptionSession = await GetEncryptionSession();
_45
_45
// Configure the signer
_45
int chainId = 80002; // Polygon Amoy testnet
_45
ShieldAuthentication shieldConfig = new ShieldAuthentication(
_45
ShieldAuthType.Openfort,
_45
token
_45
)
_45
{
_45
EncryptionSession = encryptionSession
_45
};
_45
_45
EmbeddedSignerRequest request = new EmbeddedSignerRequest(chainId, shieldConfig);
_45
await openfort.ConfigureEmbeddedSigner(request);
_45
_45
Debug.Log("Automatic recovery setup complete");
_45
}
_45
catch (Exception e)
_45
{
_45
Debug.LogError($"Error setting up automatic recovery: {e.Message}");
_45
}
_45
}
_45
}

We recommend enabling user-based recovery for users. This is especially important to enforce as the value of assets in a user's wallet grows.


User-based recovery#

Password recovery

Require that users set a password when the wallet is created, enforcing password-based recovery from the start.

If encrypted by user-provided entropy, only the user can decrypt the recovery share. Openfort never sees or the user's password. Therefore, if you're not planning to ever user the automatic recovery mode, you can use the encryption share in the client side of the application.


_15
using Openfort.OpenfortSDK;
_15
using Openfort.OpenfortSDK.Model;
_15
public class openfortManager: MonoBehaviour
_15
{
_15
private OpenfortSDK Openfort;
_15
private async void AuthAndSetPassordRecoveryMethod(string email, string password, string recoveryPassword)
_15
{
_15
AuthResponse response = await Openfort.SignUpWithEmailPassword(email, password);
_15
string token = response.Token;
_15
int chainId = 80002;
_15
ShieldAuthentication shieldConfig = new ShieldAuthentication(ShieldAuthType.Openfort, token);
_15
EmbeddedSignerRequest request = new EmbeddedSignerRequest(chainId, shieldConfig, recoveryPassword);
_15
await Openfort.ConfigureEmbeddedSigner(request);
_15
}
_15
}


Pregeneration#

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.