Password protection
Custom UI flow
If you are building a custom UI implementation, you must check the wallet recovery state and unlock the wallet programmatically before performing any wallet operations. If you skip this step, Dynamic’s default password modal will appear, which defeats the purpose of a custom UI integration.
The required flow for custom UI implementations is:
- Check wallet state — Call
GetWalletRecoveryState to determine if the wallet is password-encrypted and currently locked.
- Unlock if needed — If the wallet is password-encrypted, collect the password in your own UI and call
UnlockWallet.
- Proceed with operations — Only after the wallet is unlocked should you perform signing, transactions, or other wallet operations.
public async void EnsureWalletUnlocked(string password)
{
// 1. Check if wallet is locked
var state = await DynamicSDK.Instance.Wallets.Waas.GetWalletRecoveryState(_wallet);
if (state.IsPasswordEncrypted)
{
// 2. Unlock with the user's password
await DynamicSDK.Instance.Wallets.Waas.UnlockWallet(_wallet, password);
}
// 3. Wallet is now ready for operations
}
Check wallet recovery state
var state = await DynamicSDK.Instance.Wallets.Waas.GetWalletRecoveryState(wallet);
bool isPasswordProtected = state.IsPasswordEncrypted;
Set password on a wallet
Set a password on a wallet that doesn’t have one:
await DynamicSDK.Instance.Wallets.Waas.SetPassword(wallet, "new_password");
Unlock a password-protected wallet
await DynamicSDK.Instance.Wallets.Waas.UnlockWallet(wallet, "password");
Update password
await DynamicSDK.Instance.Wallets.Waas.UpdatePassword(
wallet,
"old_password",
"new_password"
);
Complete example
using DynamicSDK.Core;
using UnityEngine;
using System.Linq;
public class EmbeddedWalletManager : MonoBehaviour
{
private BaseWallet _wallet;
private void Start()
{
_wallet = DynamicSDK.Instance.Wallets.UserWallets.FirstOrDefault();
}
public async void CheckPasswordStatus()
{
if (_wallet == null)
{
Debug.LogError("No wallet available");
return;
}
try
{
var state = await DynamicSDK.Instance.Wallets.Waas.GetWalletRecoveryState(_wallet);
if (state.IsPasswordEncrypted)
{
Debug.Log("Wallet is password protected");
}
else
{
Debug.Log("Wallet is not password protected");
}
}
catch (System.Exception ex)
{
Debug.LogError($"Failed to check password status: {ex.Message}");
}
}
public async void SetWalletPassword(string password)
{
if (_wallet == null)
{
Debug.LogError("No wallet available");
return;
}
try
{
await DynamicSDK.Instance.Wallets.Waas.SetPassword(_wallet, password);
Debug.Log("Password set successfully!");
}
catch (System.Exception ex)
{
Debug.LogError($"Failed to set password: {ex.Message}");
}
}
public async void UnlockWallet(string password)
{
if (_wallet == null)
{
Debug.LogError("No wallet available");
return;
}
try
{
await DynamicSDK.Instance.Wallets.Waas.UnlockWallet(_wallet, password);
Debug.Log("Wallet unlocked successfully!");
}
catch (System.Exception ex)
{
Debug.LogError($"Failed to unlock wallet: {ex.Message}");
}
}
public async void ChangePassword(string oldPassword, string newPassword)
{
if (_wallet == null)
{
Debug.LogError("No wallet available");
return;
}
try
{
await DynamicSDK.Instance.Wallets.Waas.UpdatePassword(
_wallet,
oldPassword,
newPassword
);
Debug.Log("Password updated successfully!");
}
catch (System.Exception ex)
{
Debug.LogError($"Failed to update password: {ex.Message}");
}
}
}
Next steps