Skip to content

Autoconnect Feature #224

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Assets/Thirdweb/Editor/ThirdwebManagerEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class ThirdwebManagerEditor : UnityEditor.Editor
private SerializedProperty initializeOnAwakeProp;
private SerializedProperty showDebugLogsProp;
private SerializedProperty optOutUsageAnalyticsProp;
private SerializedProperty autoConnectLastWallet;
private SerializedProperty supportedChainsProp;
private SerializedProperty includedWalletIdsProp;
private SerializedProperty redirectPageHtmlOverrideProp;
Expand All @@ -33,6 +34,7 @@ private void OnEnable()
initializeOnAwakeProp = FindProperty("InitializeOnAwake");
showDebugLogsProp = FindProperty("ShowDebugLogs");
optOutUsageAnalyticsProp = FindProperty("OptOutUsageAnalytics");
autoConnectLastWallet = FindProperty("AutoConnectLastWallet");
supportedChainsProp = FindProperty("SupportedChains");
includedWalletIdsProp = FindProperty("IncludedWalletIds");
redirectPageHtmlOverrideProp = FindProperty("RedirectPageHtmlOverride");
Expand Down Expand Up @@ -158,6 +160,11 @@ private void DrawPreferencesTab()
DrawProperty(initializeOnAwakeProp, "Initialize On Awake", "If enabled, Thirdweb will initialize on Awake. If disabled, you must call ThirdwebManager.Instance.Initialize() manually.");
DrawProperty(showDebugLogsProp, "Show Debug Logs", "If enabled, Thirdweb will log debug messages to the console.");
DrawProperty(optOutUsageAnalyticsProp, "Opt-Out of Usage Analytics", "If enabled, you may see inconsistent stats in your Thirdweb Dashboard.");
DrawProperty(
autoConnectLastWallet,
"Auto-Connect Last Wallet",
"If enabled, Thirdweb will automatically connect to the last connected wallet on initialization (this behavior does not apply to the WalletConnectWallet provider option)."
);
}

private void DrawMiscTab()
Expand Down
129 changes: 114 additions & 15 deletions Assets/Thirdweb/Runtime/Unity/ThirdwebManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
using System.Linq;
using System;
using System.IO;
using Newtonsoft.Json;

namespace Thirdweb.Unity
{
[Serializable]
public enum WalletProvider
{
PrivateKeyWallet,
Expand All @@ -17,6 +19,7 @@ public enum WalletProvider
EcosystemWallet
}

[Serializable]
public class InAppWalletOptions : EcosystemWalletOptions
{
public InAppWalletOptions(
Expand All @@ -39,16 +42,34 @@ public InAppWalletOptions(
) { }
}

[Serializable]
public class EcosystemWalletOptions
{
[JsonProperty("ecosystemId")]
public string EcosystemId;

[JsonProperty("ecosystemPartnerId")]
public string EcosystemPartnerId;

[JsonProperty("email")]
public string Email;

[JsonProperty("phoneNumber")]
public string PhoneNumber;

[JsonProperty("authProvider")]
public AuthProvider AuthProvider;

[JsonProperty("jwtOrPayload")]
public string JwtOrPayload;

[JsonProperty("storageDirectoryPath")]
public string StorageDirectoryPath;

[JsonProperty("siweSigner")]
public IThirdwebWallet SiweSigner;

[JsonProperty("legacyEncryptionKey")]
public string LegacyEncryptionKey;

public EcosystemWalletOptions(
Expand All @@ -75,14 +96,28 @@ public EcosystemWalletOptions(
}
}

[Serializable]
public class SmartWalletOptions
{
[JsonProperty("sponsorGas")]
public bool SponsorGas;

[JsonProperty("factoryAddress")]
public string FactoryAddress;

[JsonProperty("accountAddressOverride")]
public string AccountAddressOverride;

[JsonProperty("entryPoint")]
public string EntryPoint;

[JsonProperty("bundlerUrl")]
public string BundlerUrl;

[JsonProperty("paymasterUrl")]
public string PaymasterUrl;

[JsonProperty("tokenPaymaster")]
public TokenPaymaster TokenPaymaster;

public SmartWalletOptions(
Expand All @@ -105,12 +140,22 @@ public SmartWalletOptions(
}
}

[Serializable]
public class WalletOptions
{
[JsonProperty("provider")]
public WalletProvider Provider;

[JsonProperty("chainId")]
public BigInteger ChainId;

[JsonProperty("inAppWalletOptions")]
public InAppWalletOptions InAppWalletOptions;

[JsonProperty("ecosystemWalletOptions", NullValueHandling = NullValueHandling.Ignore)]
public EcosystemWalletOptions EcosystemWalletOptions;

[JsonProperty("smartWalletOptions", NullValueHandling = NullValueHandling.Ignore)]
public SmartWalletOptions SmartWalletOptions;

public WalletOptions(
Expand Down Expand Up @@ -154,6 +199,9 @@ public class ThirdwebManager : MonoBehaviour
[field: SerializeField]
private bool OptOutUsageAnalytics { get; set; } = false;

[field: SerializeField]
private bool AutoConnectLastWallet { get; set; } = false;

[field: SerializeField]
private ulong[] SupportedChains { get; set; } = new ulong[] { 421614 };

Expand All @@ -170,11 +218,13 @@ public class ThirdwebManager : MonoBehaviour

public IThirdwebWallet ActiveWallet { get; private set; }

public bool Initialized { get; private set; }

public static ThirdwebManager Instance { get; private set; }

public static readonly string THIRDWEB_UNITY_SDK_VERSION = "5.14.0";

private bool _initialized;
private const string THIRDWEB_AUTO_CONNECT_OPTIONS_KEY = "ThirdwebAutoConnectOptions";

private Dictionary<string, IThirdwebWallet> _walletMapping;

Expand All @@ -199,7 +249,7 @@ private void Awake()
}
}

public void Initialize()
public async void Initialize()
{
if (string.IsNullOrEmpty(ClientId))
{
Expand Down Expand Up @@ -229,12 +279,26 @@ public void Initialize()

_walletMapping = new Dictionary<string, IThirdwebWallet>();

_initialized = true;
if (AutoConnectLastWallet && GetAutoConnectOptions(out var lastWalletOptions))
{
ThirdwebDebug.Log("Auto-connecting to last wallet.");
try
{
_ = await ConnectWallet(lastWalletOptions);
ThirdwebDebug.Log("Auto-connected to last wallet.");
}
catch (Exception e)
{
ThirdwebDebug.LogError("Failed to auto-connect to last wallet: " + e.Message);
}
}

Initialized = true;
}

public async Task<ThirdwebContract> GetContract(string address, BigInteger chainId, string abi = null)
{
if (!_initialized)
if (!Initialized)
{
throw new InvalidOperationException("ThirdwebManager is not initialized.");
}
Expand Down Expand Up @@ -279,11 +343,6 @@ public void RemoveWallet(string address)

public async Task<IThirdwebWallet> ConnectWallet(WalletOptions walletOptions)
{
if (!_initialized)
{
throw new InvalidOperationException("ThirdwebManager is not initialized.");
}

if (walletOptions == null)
{
throw new ArgumentNullException(nameof(walletOptions));
Expand Down Expand Up @@ -420,7 +479,6 @@ public async Task<IThirdwebWallet> ConnectWallet(WalletOptions walletOptions)
}

var address = await wallet.GetAddress();
ThirdwebDebug.Log($"Wallet address: {address}");

var isSmartWallet = walletOptions.SmartWalletOptions != null;

Expand All @@ -429,6 +487,8 @@ public async Task<IThirdwebWallet> ConnectWallet(WalletOptions walletOptions)
TrackUsage("connectWallet", "connect", isSmartWallet ? "smartWallet" : walletOptions.Provider.ToString()[..1].ToLower() + walletOptions.Provider.ToString()[1..], address);
}

SetAutoConnectOptions(walletOptions);

if (isSmartWallet)
{
ThirdwebDebug.Log("Upgrading to SmartWallet.");
Expand All @@ -444,11 +504,6 @@ public async Task<IThirdwebWallet> ConnectWallet(WalletOptions walletOptions)

public async Task<SmartWallet> UpgradeToSmartWallet(IThirdwebWallet personalWallet, BigInteger chainId, SmartWalletOptions smartWalletOptions)
{
if (!_initialized)
{
throw new InvalidOperationException("ThirdwebManager is not initialized.");
}

if (personalWallet.AccountType == ThirdwebAccountType.SmartAccount)
{
ThirdwebDebug.LogWarning("Wallet is already a SmartWallet.");
Expand Down Expand Up @@ -480,6 +535,12 @@ public async Task<SmartWallet> UpgradeToSmartWallet(IThirdwebWallet personalWall
await AddWallet(wallet);
SetActiveWallet(wallet);

if (AutoConnectLastWallet && GetAutoConnectOptions(out var lastWalletOptions))
{
lastWalletOptions.SmartWalletOptions = smartWalletOptions;
SetAutoConnectOptions(lastWalletOptions);
}

return wallet;
}

Expand All @@ -498,6 +559,44 @@ public async Task<List<LinkedAccount>> LinkAccount(IThirdwebWallet mainWallet, I
);
}

private bool GetAutoConnectOptions(out WalletOptions lastWalletOptions)
{
var connectOptionsStr = PlayerPrefs.GetString(THIRDWEB_AUTO_CONNECT_OPTIONS_KEY, null);
if (!string.IsNullOrEmpty(connectOptionsStr))
{
try
{
lastWalletOptions = JsonConvert.DeserializeObject<WalletOptions>(connectOptionsStr);
return true;
}
catch
{
ThirdwebDebug.LogWarning("Failed to load last wallet options.");
PlayerPrefs.DeleteKey(THIRDWEB_AUTO_CONNECT_OPTIONS_KEY);
lastWalletOptions = null;
return false;
}
}
lastWalletOptions = null;
return false;
}

private void SetAutoConnectOptions(WalletOptions walletOptions)
{
if (AutoConnectLastWallet && walletOptions.Provider != WalletProvider.WalletConnectWallet)
{
try
{
PlayerPrefs.SetString(THIRDWEB_AUTO_CONNECT_OPTIONS_KEY, JsonConvert.SerializeObject(walletOptions));
}
catch
{
ThirdwebDebug.LogWarning("Failed to save last wallet options.");
PlayerPrefs.DeleteKey(THIRDWEB_AUTO_CONNECT_OPTIONS_KEY);
}
}
}

private async void TrackUsage(string source, string action, string walletType, string walletAddress)
{
if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(action) || string.IsNullOrEmpty(walletType) || string.IsNullOrEmpty(walletAddress))
Expand Down
Loading